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_tcpmss
和xt_TCPMSS
)通过nftables内核 API 沿着兼容层API, 即使扩展表最初用于(旧版内核 API)iptables。本国的nftables不能用扩展表内核模块设计:每当扩展表正在使用中,它不再是本机的,并且 userland
nft
命令(或其 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 } }
上图:
match
和target
意思扩展表模块。自从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
)。
笔记
nft
iptables-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-translate
andnft
的输出隐藏了差异。再次运行该nft
命令后,结果是完全原生的nftables用tcp option maxseg size set rt mtu
代替-j TCMPSS --clamp-mss-to-pmtu
.但该iptables-save
命令不再识别结果,因为iptables- 翻译后的代码,无法将其翻译回iptables格式。
不要盲目倾倒iptables规则使用nftables重新加载它们nftables,如果iptables仍然需要。