在中使用集合nftables真的很酷。我目前在我的规则集中使用了很多这样的语句nftables.conf
:
iifname {clients0, dockernet} oifname wan0 accept \
comment "Allow clients and Docker containers to reach the internet"
上面的规则中{clients0, dockernet}
有一个匿名的(内联)接口集。我不想一遍又一遍地重复规则,而是想在文件顶部定义一组接口,称为命名集在 nftables 中。这联机帮助页(Debian Buster)展示了如何对几种类型的集合执行此操作:ipv4_地址,ipv6_地址,以太地址,inet_proto,inet_服务和标记。但是,它似乎不适用于按名称或简单原始类型(例如字符串)的接口。
我有以下方法,但这不适用于给出的错误:
省略类型:
table inet filter { set myset { elements = { clients0, dockernet, } } [...] }
结果:
Error: set definition does not specify key
。使用
string
类型:table inet filter { type string; set myset { elements = { clients0, dockernet, } } [...] }
结果:
Error: unqualified key type string specified in set definition
。
难道真的没有办法命名我在顶部显示的匿名集吗?
答案1
通过搜索在0.9.0版本的源码:
static const struct datatype *datatypes[TYPE_MAX + 1] = {
[...]
[TYPE_IFINDEX] = &ifindex_type,
[...]
[TYPE_IFNAME] = &ifname_type, };
const struct datatype ifindex_type = { .type = TYPE_IFINDEX, .name = "iface_index", .desc = "network interface index",
[...]
const struct datatype ifname_type = { .type = TYPE_IFNAME, .name = "ifname", .desc = "network interface name",
可能会发现所需的类型是iface_index
(eg: iif lo
) 和ifname
(eg iifname "lo"
),即使(在撰写此答案时)它是nft
的手册页中未记录。
nft add set inet filter if-index-set '{ type iface_index; }'
nft add set inet filter if-name-set '{ type ifname; }'
nft add element inet filter if-index-set '{ lo }'
nft add element inet filter if-name-set '{ lo }'
nft add chain inet filter input '{ type filter hook input priority 0; }'
nft add rule inet filter input iif @if-index-set counter
nft add rule inet filter input iifname @if-name-set counter
注意如果名称已于 2022 年 5 月 31 日添加了集合中的通配符支持nftables 1.0.3。必须使用命名集flags intervals
,最后的通配符是*
(+
不像iptables)。
答案2
nft
可以使用如下方式轻松找到元素数据类型:
$ nft describe iifname
meta expression, datatype ifname (network interface name) (basetype string), 16 characters
% nft describe iif
meta expression, datatype iface_index (network interface index) (basetype integer), 32 bits
你看到了ifname
和iface_index
是可能的类型,所以你可以声明:
set myset {
type ifname
elements = {
"clients0",
"dockernet"
}
}
在上面的例子中,如果你不知道类型,你甚至可以写typeof iifname
代替(需要v0.9.4 或更高版本)。type ifname
nft