在 Linux 上,我想删除所有包含过时 tcp 选项的数据包。我所说的过时选项是指所有 tcp 选项类型编号大于 8 的选项。我如何使用 来做到这一点nftables
?
例如,如果有一种方法可以检查 tcp 数据包是否具有 nftables 中给定数字类型的选项,那就可行。如果 nftables 不支持此功能,我可以使用tc
或其他标准 Linux 实用程序来执行此操作吗?
答案1
里面有很多关键词nftables只是代表一个常数。这就是 tcp 选项的情况(更新: 但只是从那时起nftables0.9.8)。
以下是 tcp 选项的摘录:
扩展标头表达式是指来自可变大小协议标头的数据,例如 IPv6 扩展标头和 TCP 选项。
[...]
TCP选项
{停产|努普 |最大分段|窗口|解雇允许|麻袋|麻袋0 |麻袋1 |麻袋2 |麻袋3 |时间戳} tcp_option_field
TCP 选项
关键词 描述 TCP 选项字段 停产 选项列表结束 种类 努普 1 字节 TCP 无操作选项 种类 最大分段 TCP 最大段大小 种类、长度、尺寸 窗户 TCP 窗口缩放 种类、长度、数量 [...] 时间戳 TCP 时间戳 种类、长度、tsval、tsecr [...]
布尔规范
以下表达式支持布尔比较:
表达 行为 谎言 检查路由是否存在。 扩展 检查 IPv6 扩展标头是否存在。 TCP选项 检查 TCP 选项标头是否存在。 [...]
# match if TCP timestamp option is present filter input tcp option timestamp exists
这里eol
代表0,nop
代表1,...timestamp
代表8,等等。
更新:从0.9.8版本开始可以指定任意数值而不是关键字:
添加原始 tcp 选项匹配支持
... TCP 选项@42,16,4
您可以在其中指定@kind、offset、length
允许检查是否存在任何 tcp 选项
... TCP 选项 42 存在
所以有了这样的规则:
nft add table t
nft add chain t c '{ type filter hook input priority 0; policy accept; }'
nft add rule t c tcp option 8 exists drop
nft add rule t c tcp option 9 exists drop
nft add rule t c tcp option 10 exists drop
[...]
nft add rule t c tcp option 254 exists drop
可以过滤值为 8(包含在后面显示 8 的意思timestamp
)或以上(选项值位于 8 位字段上)的所有规则。
已知值(仅此处timestamp
)与关键字一起显示,否则它们保留为数字:
# nft -a --debug=netlink list ruleset
ip t c 2
[ exthdr load tcpopt 1b @ 8 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ immediate reg 0 drop ]
ip t c 3 2
[ exthdr load tcpopt 1b @ 9 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ immediate reg 0 drop ]
ip t c 4 3
[ exthdr load tcpopt 1b @ 10 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ immediate reg 0 drop ]
ip t c 5 4
[ exthdr load tcpopt 1b @ 254 + 0 present => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ immediate reg 0 drop ]
table ip t { # handle 21
chain c { # handle 1
type filter hook input priority filter; policy accept;
tcp option timestamp exists drop # handle 2
tcp option 9 exists drop # handle 3
tcp option 10 exists drop # handle 4
tcp option 254 exists drop # handle 5
}
}
我没有找到一种方法将其分解为集合或映射,也没有与选项值进行比较,这会简化这一点,因为整体tcp option foo
必须在语法中使用,而不仅仅是tcp option
,据我所知,这会导致无用特点如下:
检查选项时间戳是否意味着种类8其 kind 值为... 8。(如果存在则始终为 true,因此相当于
tcp option timestamp exists
):nft add rule t c tcp option timestamp kind == 8
或检查选项时间戳是否意味着种类8kind 值大于 8(始终为 false):
nft add rule t c 'tcp option timestamp kind > 8'
考虑到一个TCP选项是选项列表的一部分,我可以理解实现并不那么容易,因为它必须循环遍历所有现有选项才能选择一个。当两个可以匹配时会选择哪个?
注意:8 以上的几个选项值得保留。例如TCP 选项种类 30是用来多点TCP最近被添加到主流 Linux 中,而 tcp 选项种类 6(回显)和 7(回显回复)已过时。