Nftables 配置错误:指定冲突协议:inet-service v. icmp

Nftables 配置错误:指定冲突协议:inet-service v. icmp

我正在尝试建立一个简单的状态防火墙nftables遵循Arch Linux nftables 指南。我在 Arch Linux 论坛上发布了这个问题,但从未收到答案。

完成指南并重新启动我的机器后,系统无法加载nftables.service。为了解决我运行的错误:

systemctl status nftables

这是相关的输出:

/etc/nftables.conf:7:17-25: Error: conflicting protocols specified: inet-service v. icmp

该错误抱怨我为在输入链中接受新 ping (icmp) 而设置的规则。这是规则,我不认为它有什么问题:

icmp type echo-request ct state new accept

如果我删除该规则,它就会起作用。但我想要规则。

这是我的规则集nftables.conf完成指南后:

    table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        iif "lo" accept
        ct state invalid drop
        icmp type echo-request ct state new accept
        ip protocol udp ct state new jump UDP
        tcp flags & (fin | syn | rst | ack) == syn ct state new jump TCP
        ip protocol udp reject
        ip protocol tcp reject with tcp reset
        meta nfproto ipv4 counter packets 0 bytes 0 reject with icmp type prot-unreachable
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }

    chain TCP {
        tcp dport http accept
        tcp dport https accept
        tcp dport ssh accept
        tcp dport domain accept
    }

    chain UDP {
        tcp dport domain accept
    }
}

我缺少什么?先感谢您。

答案1

这是 nftables 0.7(或其他一些版本)的语法限制:它不认为 ICMP 和 ICMPv6 可直接在双 IPv4/IPv6 表中使用,inet而无需明确说明首先使用哪个 IP 协议:

所以规则是:

icmp type echo-request ct state new accept

要同时在 IPv4 和 IPv6 上工作,必须像这样编写两次:

更新:实际上,人们不应该依赖 IPv6 指向nexthdr上层协议:可以有扩展头固定报头和上层报头(最后一个)之间。添加正确的语法(使用已经提供协议信息的元信息),并保留我原来的答案,因为我不知道“正确”语法对于 nftables 0.7 是否有效:

meta nfproto ipv4 meta l4proto icmp icmp type echo-request ct state new accept
meta nfproto ipv6 meta l4proto icmpv6 icmpv6 type echo-request ct state new accept
ip protocol icmp icmp type echo-request ct state new accept
ip6 nexthdr icmpv6 icmpv6 type echo-request ct state new accept

给出相应的字节码(使用显示nft --debug=netlink list ruleset -a):

inet filter input 9 8 
  [ meta load nfproto => reg 1 ]
  [ cmp eq reg 1 0x00000002 ]
  [ payload load 1b @ network header + 9 => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 1b @ transport header + 0 => reg 1 ]
  [ cmp eq reg 1 0x00000008 ]
  [ ct load state => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x00000008 ) ^ 0x00000000 ]
  [ cmp neq reg 1 0x00000000 ]
  [ immediate reg 0 accept ]

inet filter input 10 9 
  [ meta load nfproto => reg 1 ]
  [ cmp eq reg 1 0x0000000a ]
  [ payload load 1b @ network header + 6 => reg 1 ]
  [ cmp eq reg 1 0x0000003a ]
  [ payload load 1b @ transport header + 0 => reg 1 ]
  [ cmp eq reg 1 0x00000080 ]
  [ ct load state => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x00000008 ) ^ 0x00000000 ]
  [ cmp neq reg 1 0x00000000 ]
  [ immediate reg 0 accept ]

ICMP 是 IP 协议 1,回显请求值 8。ICMPv6
是 IPv6 协议 58 (0x3a),其回显请求值 128 (0x80)。

较新的 nftables 0.9 直接接受规则icmp type echo-request ct state new accept,但其相应的字节码只是:

inet filter input 9 8 
  [ meta load nfproto => reg 1 ]
  [ cmp eq reg 1 0x00000002 ]
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 1b @ transport header + 0 => reg 1 ]
  [ cmp eq reg 1 0x00000008 ]
  [ ct load state => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x00000008 ) ^ 0x00000000 ]
  [ cmp neq reg 1 0x00000000 ]
  [ immediate reg 0 accept ]

这意味着它只处理 ICMP,而不是 ICMPv6,仍应添加一条附加规则,简单如下:

icmpv6 type echo-request ct state new accept

返回先前版本的等效字节码:

inet filter input 10 9 
  [ meta load nfproto => reg 1 ]
  [ cmp eq reg 1 0x0000000a ]
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x0000003a ]
  [ payload load 1b @ transport header + 0 => reg 1 ]
  [ cmp eq reg 1 0x00000080 ]
  [ ct load state => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x00000008 ) ^ 0x00000000 ]
  [ cmp neq reg 1 0x00000000 ]
  [ immediate reg 0 accept ]

相关内容