为什么 iptables(-nft) 中的 MSS 钳位似乎在 nftables 中不起作用?

为什么 iptables(-nft) 中的 MSS 钳位似乎在 nftables 中不起作用?

iptables -t mangle -o "$PPP_IFACE" --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu我的 pppoe 客户端自动添加来自 的iptables 规则/etc/ppp/ip-up.d。然而,nftables 中的这条规则看起来像

table ip mangle {
    chain FORWARD {
        type filter hook forward priority mangle; policy accept;
        oifname "ppp0" meta l4proto tcp tcp flags & (syn|rst) == syn # tcpmss match 1400:65495 counter packets 714 bytes 42388 tcp option maxseg size set rt mtu
    }
}

为什么tcpmss后面的内容被注释了,而这条规则似乎没有任何作用?

答案1

解释

  • 通过设置的规则iptables-nft正在使用xtables 内核模块(这里:xt_tcpmssxt_TCPMSS)通过nftables内核 API 沿着兼容层API, 即使扩展表最初用于(旧版内核 API)iptables

    本国的nftables不能用扩展表内核模块设计:每当扩展表正在使用中,它不再是本机的,并且 userlandnft命令(或其 API)仅处理本机nftables。用于扩展表为兼容层保留。所以当显示通过NFFT任何此类未知模块都会被注释掉(但请参阅下文)。

  • 当前版本iptables-nft尚无法自动翻译iptables规则为本地化nftables规则(对于这种情况)或没有等效的本机nftables翻译成的规则(例如:思考LED目标)。

    这里nft看到有扩展表通用翻译引擎无法翻译的模块,因此认为这部分是禁止的,并对不可翻译的部分添加注释,但仍然翻译它所知道的内容。致电给扩展表可以通过以下方式查看模块--debug=netlink

    # nft -a --debug=netlink list ruleset
    ip mangle FORWARD 2
      [ meta load oifname => reg 1 ]
      [ cmp eq reg 1 0x30707070 0x00000000 ]
      [ meta load l4proto => reg 1 ]
      [ cmp eq reg 1 0x00000006 ]
      [ match name tcp rev 0 ]
      [ match name tcpmss rev 0 ]
      [ counter pkts 0 bytes 0 ]
      [ target name TCPMSS rev 0 ]
    
    table ip mangle { # handle 167
      chain FORWARD { # handle 1
          type filter hook forward priority mangle; policy accept;
          oifname "ppp0" meta l4proto tcp tcp flags & (syn|rst) == syn # tcpmss match 1400:65495 counter packets 0 bytes 0 tcp option maxseg size set rt mtu # handle 2
      }
    }
    

    上图:matchtarget意思扩展表模块。自从nftables使用与iptables-翻译在这方面,人们可能会猜测-m tcpmss --mss 1400:65495遇到了问题,因为这是以注释开头并且在输出中未翻译的问题,而最后一部分已翻译。此处显示的内容nft仅供展示,不作为实际规则

    实际的规则是显示的字节码--debug=netlink(加上不可见的部分扩展表具体数据),所以这个字节码就是这个规则的证明做某事。对本地人来说没什么用nftables

本国的nftables版本

例如大多数OPiptables规则可以本地翻译:

# iptables-translate -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
nft add rule ip mangle FORWARD tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu

虽然目前没有可用的自动翻译-m tcpmss --mss,但该功能是可用的:tcp option maxseg size可以用作表达式(相当于 match -m tcpmss --mss)或 withset用作语句(相当于 target -j TCPMSS)。以下是此类翻译的结果(一旦翻译引擎得到改进,将来可能会出现):

nft add rule ip mangle FORWARD 'oifname ppp0 tcp flags & (syn|rst) == syn tcp option maxseg size 1400-65495 counter tcp option maxseg size set rt mtu'

第二个值 65495 可能没用(可以代替tcp option maxseg size >= 1400)。


笔记

nftiptables-nft当试图滥用翻译时可能会产生误导。例如使用iptables v1.8.7 (nf_tables)NFFTv1.0.0,可以得到这个:

# iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# nft list ruleset | tee /tmp/mss.nft
table ip mangle {
    chain FORWARD {
        type filter hook forward priority mangle; policy accept;
        meta l4proto tcp tcp flags & (syn|rst) == syn counter packets 0 bytes 0 tcp option maxseg size set rt mtu
    }
  }
# nft flush ruleset
# nft -f /tmp/mss.nft
# iptables-save 
# Table `mangle' is incompatible, use 'nft' tool.

这是因为虽然nft在显示时能够翻译整个规则集,但初始兼容规则集仍然包含扩展表字节码中的目标(与上面所见相同:)[ target name TCPMSS rev 0 ]iptables-nft没有表现出iptables-translateandnft的输出隐藏了差异。再次运行该nft命令后,结果是完全原生的nftablestcp option maxseg size set rt mtu代替-j TCMPSS --clamp-mss-to-pmtu.但该iptables-save命令不再识别结果,因为iptables- 翻译后的代码,无法将其翻译回iptables格式。

不要盲目倾倒iptables规则使用nftables重新加载它们nftables,如果iptables仍然需要。

相关内容