作者说:
I for myself always like to know how things work and to dig a little deeper than just gaining the very minimum knowledge required to solve the issue at hand.
过去这些年,创建了很多图片来图形化通过netfilter hooks的数据包流,也就是包通过iptables或者nftables的tables, chains,rules的流程。下面这张图是最著名、且维护的最好的。
但是这张图描述的是旧的iptables,而不是最新的nftables。nftables可以自己创建、命名tables和chains。
官网的图,扩展阅读[2]。
netfilter
linux内核内部的netfilter框架是包选择系统,例如iptables或者更新的nftables的基本构建单元。它提供了一些列hooks,在包通过内核时,这些hooks被遍历执行。
这5个hooks在内核已经存在很长时间了。每个ipv4, ipv6, arp, bridge, network namespace, 都有对应的独立的hooks。额外的ingress hook存在于每一个network device。nftable把它们抽象成address families (ip, ip6, inet, arp, bridge, netdev)。
Network Namespace
通常我们只有一个默认的namespace,也就是init_net,但是我们可以创建namespace,每个namespace有独立的hooks。
Register hook functions
使用nf_register_net_hook()和nf_unregister_net_hook()来注册和删除hook。
每个netfilter hook有它自己的数组,用struct nf_hook_entries来表示。
priority
每个hook 函数有优先级,用int表示,数字低,优先级高,内核预定义了一些离散值。
enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, NF_IP_PRI_RAW_BEFORE_DEFRAG = -450, NF_IP_PRI_CONNTRACK_DEFRAG = -400, NF_IP_PRI_RAW = -300, NF_IP_PRI_SELINUX_FIRST = -225, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_SECURITY = 50, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_SELINUX_LAST = 225, NF_IP_PRI_CONNTRACK_HELPER = 300, NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, NF_IP_PRI_LAST = INT_MAX, };
Hard-coded vs. Flexibility
netfilter hook是写死在内核协议栈中的,通过NF_HOOK()调用。
Hook traversal and verdict
skb通过hook中注册的每一个函数,按优先级数从小到达遍历,每个hook函数的返回值表明是丢掉,还是继续。
iptables
iptables有已经预定义好的tables,每个tables包含固定的chains。
table | contains chains | command to show that |
---|---|---|
filter | INPUT , FORWARD , OUTPUT | iptables [-t filter] -L |
nat | PREROUTING , (INPUT )10), OUTPUT , POSTROUTING | iptables -t nat -L |
mangle | PREROUTING , INPUT , FORWARD , OUTPUT , POSTROUTING | iptables -t mangle -L |
raw | PREROUTING , OUTPUT | iptables -t raw -L |
图1中的hook,上面是table,下面是input。
为了配置不同的协议,iptables suite包括几个不同的命令工具:
iptables
for IPv4 / NFPROTO_IPV4
ip6tables
for IPv6 / NFPROTO_IPV6
arptables
for ARP / NFPROTO_ARP
ebtables
for Bridging / NFPROTO_BRIDGE
iptables用于ipv4,它的chain已注册的hooks的名字命名,如下图所示:
connection tracking
如上图所示,连接追踪系统也注册netfilter hooks,优先级为-200。连接追踪实际上创建了更多的hooks。但是上面两个足够理解连接追踪的行为,当创建iptables或nftables rules时。
连接追踪可以参考[1]。
Nftables
和iptables一样,将rules组织成tables和chains。但是nftables没有预定义的tables和chains。
address families
和iptables将不同的协议用不同的工具维护不同。nftables只有一个工具,而使用所谓的address families概念。
ip
: maps to IPv4 protocol hooks / NFPROTO_IPV4
(default)
ip6
: maps to IPv6 protocol hooks / NFPROTO_IPV6
inet
: maps to both IPv4 and IPv6 protocol hooks
arp
: maps to ARP protocol hooks / NFPROTO_ARP
bridge
: maps to bridging hooks / NFPROTO_BRIDGE
netdev
: maps to ingress hook / NFPROTO_NETDEV
比如
nft create table ip foo nft create chain ip foo bar {type filter hook input priority 0\;}
inet 比较特殊,它会注册两个netfilter hook,ipv4和ipv6的。
priority
需要指定优先级,如果是负数,则参数传递比较特殊。将两个横线--。
nft -- add chain foo bar {type nat hook input priority -100\;}
有一些预定义的好的priority名字
Name | Priority Value |
---|---|
raw | -300 |
mangle | -150 |
conntrack13) | -200 |
dstnat | -100 |
filter | 0 |
security | 50 |
srcnat | 100 |
当注册两个相同优先级的rule时,作者测试发现,后注册的先执行。
Example: NAT edge router
将路由器配置成SNAT
nft create table ip nat nft create chain ip nat postrouting {type nat hook postrouting priority srcnat\;} nft add rule ip nat postrouting oif eth1 masquerade nft create table ip filter nft create chain ip filter input {type filter hook input priority filter\;} nft create chain ip filter forward {type filter hook forward priority filter\;} nft create chain ip filter output {type filter hook output priority filter\;} nft add rule ip filter forward iif eth1 oif eth0 ct state new,invalid drop nft add rule ip filter input iif eth1 ip protocol != icmp ct state new,invalid drop
如下图:
List hook functions
nftables开发者在2021年7月宣布一个新的feature,可能在nftables的下个release包含,支持列出所有的hook函数。如下提交:
http://git.netfilter.org/nftables/commit/?id=4694f7230195bfcff179ed418ddcdd5ff7d5a8e1
本文来自同标题的下面这篇文章
Andrej Stender. Nftables - Packet flow and Netfilter hooks in detail. 2020-05-17.
https://thermalcircle.de/doku.php?id=blog:linux:nftables_packet_flow_netfilter_hooks_detail
拓展阅读
[1] https://thermalcircle.de/doku.php?id=blog:linux:connection_tracking_1_modules_and_hooks
[2] https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks