我有很多子网10.x.y.0/24
,其中0 ≤ x ≤ 50
和0 ≤ y ≤ 20
。
我希望允许 之间的流量10.x.y.0/24
以及10.z.y.0/24
的每个值(x, y, z)
。
我可以使用可执行文件编写脚本nft
,但我想知道是否可以使用单个规则和二进制操作来完成它。
我可以y
使用“提取”地址的“字节” ip saddr & 0.0.255.0
,但是当我尝试使用==
运算符时,nftables
告诉我语法无效:
$ cat /etc/nftables.conf
# [...]
ip saddr & 0.0.255.0 == daddr & 0.0.255.0 accept
# [...]
$ sudo nft -f /etc/nftables
/etc/nftables.conf:113:27-31: Error: syntax error, unexpected daddr
ip saddr & 0.0.255.0 == daddr & 0.0.255.0 accept
我尝试了一些变体,但它们似乎都不起作用,并且 NFTables wiki 从不比较数据包的不同字段。
有没有办法做到这一点?
答案1
我不认为目前nftables支持比较右侧的任意非常量表达式。我不知道这个限制是否在用户空间端如何生成足够的字节码,或者内核端的字节码是否无法处理这样的事情。可以有一个常量或一个集合/映射查找,但仅此而已。这可能会在未来演变。
无论如何,我提出了一个替代解决方案,使用放和串联作为查找表。仍然使用您的特定网络掩码操作,这将只需要 y 元素 (21),这比详尽的规则集或其等效的完整集版本要好得多(它仍然比简单的规则集更快,因为它是散列的):它们可能需要更多规则或详尽的匹配列表的元素。
我将在示例中使用表ip myfilter
及其type filter hook forward
链,请修改:ip myfilter forward
nft add table myfilter
nft add chain ip myfilter forward '{ type filter hook forward priority 0; policy drop; }'
添加由两个 IP 地址类型串联组成的集合:
table ip myfilter {
set same-y {
type ipv4_addr . ipv4_addr
}
}
创建于:
nft add set ip myfilter same-y '{ type ipv4_addr . ipv4_addr; }'
查找将匹配两个 IP 地址的串联。现在仍然可以在比较的左侧应用运算符,因此仍将使用您的自定义网络掩码运算符:只需提供修改后的源地址和修改后的目标地址,如果集合中存在匹配元素,则结果将是true(并且规则将运行该accept
语句)。
nft 'add ip myfilter forward ip saddr & 0.0.255.0 . ip daddr & 0.0.255.0 @same-y accept'
再次强调:使其工作的区别在于,在这里,取决于数据包内容的两个表达式都位于左手边的比较,因此是允许的。
现在用类型的条目填充集合0.0.y.0 : 0.0.y.0
,以完成逻辑比较的部分,这部分不能纯粹在数据包路径遍历期间完成,例如使用以下 shell 循环:
for i in $(seq 0 20); do printf 'add element ip myfilter same-y { 0.0.%d.0 . 0.0.%d.0 }\n' $i $i; done | nft -f -
这将在 中添加 21 个元素@same-y
:
0.0.0.0 . 0.0.0.0,
0.0.1.0 . 0.0.1.0,
[...]
0.0.20.0 . 0.0.20.0
如果网络扩展并接收 类型的子网络10.x.21.0/24
,则只需要添加一个元素,并且这仍然可以在运行时完成。
如果您需要过滤器的一些例外情况,同时保持其通用性,则可以将上面的集合转换为判定图。大多数判决元素将以 结尾: accept
,例外情况如下0.0.15.0 . 0.0.15.0 : jump exception-net-15
(此类用户链也必须在同一规则集中定义)。
有了这个判决图:
table ip myfilter {
map accept-same-y {
type ipv4_addr . ipv4_addr : verdict
}
}
应该用这种元素填充:
0.0.0.0 . 0.0.0.0 : accept,
0.0.1.0 . 0.0.1.0 : accept,
[...]
0.0.20.0 . 0.0.20.0 : accept
并按照此规则使用,vmap
如果找到,将从地图中执行判决:
ip saddr & 0.0.255.0 . ip daddr & 0.0.255.0 vmap @accept-same-y