如何在 nftables 中按名称创建一组命名接口?

如何在 nftables 中按名称创建一组命名接口?

在中使用集合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_服务标记。但是,它似乎不适用于按名称或简单原始类型(例如字符串)的接口。

我有以下方法,但这不适用于给出的错误:

  1. 省略类型:

    table inet filter {
      set myset {
        elements = {
          clients0,
          dockernet,           
        }
      }
      [...]
    }
    

    结果:Error: set definition does not specify key

  2. 使用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

你看到了ifnameiface_index是可能的类型,所以你可以声明:

 set myset {
    type ifname
    elements = {
       "clients0",  
       "dockernet"  
    }       
 }

在上面的例子中,如果你不知道类型,你甚至可以写typeof iifname代替(需要v0.9.4 或更高版本)。type ifnamenft

相关内容