作者说:
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