使用 conntrack 标记将 Iptables 移植到 Nftables 防火墙

使用 conntrack 标记将 Iptables 移植到 Nftables 防火墙

嗨,亲爱的尊敬的社区,

我很难将功能强大的 iptables 防火墙移植到 nftables。输入/输出/转发内容没有问题,主要是 conntrack 标记。我目前所做的事情如下:

1/ 我使用该命令创建三个路由表ip以及规则和 conntrack 标记。他们每个人都有一个默认路由,要么是我的 FDDI,要么是我的 VPN,要么是我的 4G 连接。

ip route add table maincnx default dev $WAN via 192.168.1.2
ip route add table maincnx 192.168.0.0/24 dev $LAN src 192.168.0.1
ip route add table maincnx 192.168.1.0/24 dev $WAN src 192.168.1.1
ip rule add from 192.168.1.2 table maincnx

[[ $VPN ]] && ip route add table vpnclient default dev $VPNIF via $VPNCLIENTIP
[[ $VPN ]] && ip route add table vpnclient $VPNCLIENTROUTE dev $VPNIF src $VPNCLIENTIP
[[ $VPN ]] && ip route add table vpnclient 192.168.0.0/24 dev $LAN src 192.168.0.1
[[ $VPN ]] && ip route add table vpnclient 192.168.1.0/24 dev $WAN src 192.168.1.1
ip rule add from $VPNCLIENTIP table vpnclient

ip route add table altcnx default dev $WAN2 via 192.168.2.2
ip route add table altcnx 192.168.0.0/24 dev $LAN src 192.168.0.1
ip route add table altcnx 192.168.1.0/24 dev $WAN src 192.168.1.1
ip route add table altcnx 192.168.2.0/24 dev $WAN2 src 192.168.2.1
ip rule add from 192.168.2.2 table altcnx

ip rule add from all fwmark 1 table maincnx
[[ $VPN ]] && ip rule add from all fwmark 2 table vpnclient
ip rule add from all fwmark 3 table altcnx
ip route flush cache

2/ 然后,我将一些 iptables 规则放在一起:(如果有人已经在 Iptables 版本上遇到困难,我留下评论)

$IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark # Restore mark previously set
$IPTABLES -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT # If a mark exists: skip
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.5 -p tcp --sport 50001  -j MARK --set-mark 2 # route through VPN
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.3 -j MARK --set-mark 2
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.4 -j MARK --set-mark 3 # route through 4G
$IPTABLES -t mangle -A POSTROUTING -j CONNMARK --save-mark # save marks to avoid retagging

3/ 相关的后布线:

$IPTABLES -t nat -A POSTROUTING -o $WAN -j SNAT --to-source 192.168.1.1
$IPTABLES -t nat -A POSTROUTING -o $WAN2 -j SNAT --to-source 192.168.2.1
[[ $VPN ]] && $IPTABLES -t nat -A POSTROUTING -o $VPNIF -j SNAT --to-source $VPNCLIENTIP

ps:如果脚本启动时 VPN 已启动并正在运行,$VPN 显然是一个设置为 1 的变量。还有一些其他事情可以使这项工作正常进行,例如 IP 规则清理和一些预路由/转发,但这不是重点,如果您感兴趣,请发表评论,我将完整发布它们。

类型:网关有 3 个 eth: 0/1/2,使用 ips 192.168.1.1 (FDDI)、192.168.0.1 (LAN)、192.168.2.1 (4G),网关为 FDDI 的 192.168.1.2 和 192.168.2.2 的网关4G,VPN 位于 TUN0 设备上,IP 约为 10.8.0.x。

因此,基本上,当 192.168.0.5 向 50001:tcp 端口发起连接时,它是通过 VPN 路由的。 192.168.0.3 始终使用 VPN,无论它尝试连接到什么,192.168.0.4 都通过 4G 连接,所有其他设备默认使用路由表 1 并通过 FDDI 连接。

问题:我猜工作的 Ip 部分与 nftables 保持相同,但是 nftables 中的等效命令是什么,可以像 iptables 一样完成重整和后路由?

答案1

iptables-translate随任何现代安装一起提供iptables(或者可能单独打包,搜索它)。它将(尝试)翻译iptables规则成nftables规则。如果你不想阅读所有内容,这是一种简单的方法文档(包括用于此工具) 和手册页

它不需要 root 即可使用。对于这种情况(用虚拟信息完成一些变量以应对OP创建规则的方式):

$ export IPTABLES=/usr/sbin/iptables-translate
$ $IPTABLES -V
iptables-translate v1.8.7 (nf_tables)

$ export WAN=wan WAN2=wan2 VPNIF=vpnif VPNCLIENTIP=192.0.2.2 VPN=1
$ cat > /tmp/rules.bash <<'EOF'
$IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark # Restore mark previously set
$IPTABLES -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT # If a mark exists: skip
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.5 -p tcp --sport 50001  -j MARK --set-mark 2 # route through VPN
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.3 -j MARK --set-mark 2
$IPTABLES -t mangle -A PREROUTING -s 192.168.0.4 -j MARK --set-mark 3 # route through 4G
$IPTABLES -t mangle -A POSTROUTING -j CONNMARK --save-mark # save marks to avoid retagging

$IPTABLES -t nat -A POSTROUTING -o $WAN -j SNAT --to-source 192.168.1.1
$IPTABLES -t nat -A POSTROUTING -o $WAN2 -j SNAT --to-source 192.168.2.1
[[ $VPN ]] && $IPTABLES -t nat -A POSTROUTING -o $VPNIF -j SNAT --to-source $VPNCLIENTIP
EOF

结果:

$ bash /tmp/rules.bash
nft add rule ip mangle PREROUTING counter meta mark set ct mark
nft add rule ip mangle PREROUTING mark != 0x0 counter accept
nft add rule ip mangle PREROUTING ip saddr 192.168.0.5 tcp sport 50001 counter meta mark set 0x2 
nft add rule ip mangle PREROUTING ip saddr 192.168.0.3 counter meta mark set 0x2 
nft add rule ip mangle PREROUTING ip saddr 192.168.0.4 counter meta mark set 0x3 
nft add rule ip mangle POSTROUTING counter ct mark set mark
nft add rule ip nat POSTROUTING oifname "wan" counter snat to 192.168.1.1
nft add rule ip nat POSTROUTING oifname "wan2" counter snat to 192.168.2.1
nft add rule ip nat POSTROUTING oifname "vpnif" counter snat to 192.0.2.2

译者可能不知道或无法翻译某些部分,并且在发生这种情况时会将该行注释掉,例如:

$ /usr/sbin/iptables-translate -A INPUT -s 192.0.2.2 -j LED --led-trigger-id test
nft # -A INPUT -s 192.0.2.2 -j LED --led-trigger-id test 

由于这个转储的翻译不包含任何注释,因此可以假设翻译是好的。只需正确重命名表、链(并将内容放回到变量中)即可与中选择的内容兼容nftables规则集并重用它。如果需要的话进行改进或简化(例如:counter表达式仅用于调试或统计,而不用于实际操作)。

它通常可以通过以下提供的新功能进行改进nftables(例如:使用更好分解的映射)如果需要的话,但这不在这个答案的范围内。


注意:不要盲目相信翻译,nftables仍然必须了解其特性。

翻译工具不知道使用上下文,因此 OP 仍然必须理解,即使仅在之后检查从翻译中发现的表达式和语句。我只是给出一个OP不需要的例子:当出于重新路由的特定目的在OUTPUT钩子中设置(conn)标记时(对于在PREROUTING中设置的标记没有什么特殊的,因为它是在路由之前完成的,并且这不适用于FORWARD ),执行此操作的正确方法是nftables是在a中设置一个标记链是type route hook outputtype filter hook output不会触发重新路由:

支持的链类型

[...]

类型 家庭 挂钩 描述
[...]
路线 ip、ip6 输出 如果数据包已遍历此类型的链并且即将被接受,则如果 IP 标头的相关部分已更改,则会执行新的路由查找。这允许在 nftables 中实现策略路由选择器。

...为了改变路线。这里nft add rule ip mangle OUTPUT就不讲这个细节了,因为通常碾压刚刚转变为筛选使用时nftables。人们必须了解它是如何运作的:翻译并不能解决所有问题。

相关内容