我有两台虚拟机(路由器和客户端)ubuntu服务器18 04,路由器是客户端的网关。Nftables安装在路由器上,并使用两条链在路由前和路由后创建一个NAT表,并为客户端设置规则。
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oif "enp0s3" ip saddr 192.168.2.100 snat to 192.168.1.10 comment "STATIC" # handle 4
}
}
我打开从客户端到互联网的 ping - 一切正常。
root@router:/home/router# conntrack -L -n
icmp 1 29 src=192.168.2.100 dst=8.8.8.8 type=8 code=0 id=13006 src=8.8.8.8 dst=192.168.1.10 type=0 code=0 id=13006 mark=0 use=1
但是当您删除规则时,会话不会中断并且 ping 继续进行:
root@router:/home/router# nft delete rule nat postrouting handle 4
root@router:/home/router# nft list ruleset
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
}
}
root@router:/home/router# conntrack -L -n
icmp 1 29 src=192.168.2.100 dst=8.8.8.8 type=8 code=0 id=13006 src=8.8.8.8 dst=192.168.1.10 type=0 code=0 id=13006 mark=0 use=1
conntrack v1.4.4 (conntrack-tools): 1 flow entries have been shown.
我希望当更改或删除规则时,客户端的当前会话将终止。
我怎么才能得到它?
答案1
除了 Linux 网络堆栈之外,还有一个旨在改变行为但尽可能与网络堆栈分开的附加“堆栈”:Netfilter。该工具允许客户端(仍在内核中)连接到它,以便在其在网络堆栈中的生命周期中的各个战略位置拦截数据包:用于防火墙和执行 NAT。在这些客户中,但不仅如此,还有iptables和nftables。这是对应的Netfilter 和通用网络中的数据包流示意图:
经过简·恩格尔哈特- 自己的作品,起源静止无功发生器 巴布亚新几内亚,抄送-SA 3.0,关联
虽然这个原理图是用创建的iptables请记住,它也适用于nftables。在这个答案中,nftables具有相同的作用iptables。这里说的最多的事情是关于nftables适用于iptables(旧版或 nft 版本),反之亦然。
可以看出,另一个重要的客户端(实际上被认为是 Netfilter 的一部分)是conntrack
,它跟踪看到的所有流,并且还使用相同的流簿记来执行大量 NAT 处理。 NAT 并不是真正由nftables:如原理图中心所示,它将仅接收每个流的第一个数据包,以便能够给出一个改变规则,该规则将决定整个流(而不是单个数据包)的命运:一旦存储信息在conntrack
查找条目中,conntrack
将独立处理它,并且钩子类型的链nat
将不会看到来自该流的后续数据包。
所以这并不重要:一旦流已经由 处理conntrack
,它就不会受到任何nat
规则更改的影响,即使没有更多规则,只是因为这些规则不再使用。
要影响此流程,可以采取的措施是直接查询设施conntrack
。与此相关的工具称为conntrack
(从https://conntrack-tools.netfilter.org/)。
正如OP所写,它可用于读取有关conntrack
条目的信息,但也可用于更新、创建、删除或刷新(删除所有)条目。
可以选择粒度:
删除所有条目:
conntrack -F
删除所有 snat-ed 条目(技术上意味着回复目标地址与查找表中的原始源地址不同):
conntrack -D --src-nat
一直到对指定所有元素的 OP 条目进行外科手术删除,甚至包括精确的 ICMP id(因此这不会中断在删除 NAT 规则之前启动的相同 ping 命令,因为 id 肯定会有所不同):
# conntrack -D -p icmp --orig-src 192.168.2.100 --orig-dst 8.8.8.8 --reply-src 8.8.8.8 --reply-dst 192.168.1.10 --icmp-type 8 --icmp-code 0 --icmp-id 13006 icmp 1 28 src=192.168.2.100 dst=8.8.8.8 type=8 code=0 id=13006 src=8.8.8.8 dst=192.168.1.10 type=0 code=0 id=13006 mark=0 use=1 conntrack v1.4.6 (conntrack-tools): 1 flow entries have been deleted.
(Ubuntu 18.04LTS 的 1.4.4 没有理由
conntrack
在这里表现不同)
一旦删除此条目,之前属于此流的下一个数据包将被视为新数据包。处于状态新的,它将再次获得改变的机会并遍历nat
链。由于不会再有任何改变,如果它是出口,它将穿越未经过 NAT 处理的下一个路由器,该路由器可能会丢弃它或将其传递到将丢弃它的路由器(因为严格反向路径转发或针对特定的路由规则) RFC1918 地址),如果它是来自 8.8.8.8 的延迟入口回复,它将被本地路由并被网络堆栈忽略:ping 命令被中断并且现在超时。