Nftables 구성 오류: 충돌하는 프로토콜이 지정됨: inet-service 대 icmp

Nftables 구성 오류: 충돌하는 프로토콜이 지정됨: inet-service 대 icmp

나는간단한 상태 저장 방화벽그리고nftables따르다아치 리눅스 nftables 가이드. 나는 이 질문을 Arch Linux 포럼에 게시했지만 답변을 받지 못했습니다.

가이드를 완료하고 컴퓨터를 다시 시작한 후,체계로드할 수 없습니다.nftables.service. 오류를 해결하기 위해 다음을 실행했습니다.

systemctl status nftables

관련 출력은 다음과 같습니다.

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

이 오류는 입력 체인에서 새 핑(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(또는 다른 버전)의 구문적 제한 사항입니다. inet어떤 IP 프로토콜이 먼저 사용되는지 명시적으로 지정하지 않고 이중 IPv4/IPv6 테이블에서 직접 사용되는 ICMP 및 ICMPv6을 고려하지 않습니다.

따라서 규칙은 다음과 같습니다.

icmp type echo-request ct state new accept

IPv4와 IPv6 모두에서 작업하려면 다음과 같이 두 번 작성해야 합니다.

고쳐 쓰다nexthdr: 실제로, 상위 계층 프로토콜을 가리키는 IPv6에 의존해서는 안 됩니다 .확장 헤더고정 헤더와 상위 헤더(마지막 헤더) 사이. 올바른 구문을 추가하고(이미 프로토콜 정보를 제공하는 메타 정보를 사용하여) "올바른" 구문이 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

해당 바이트코드가 주어지면(display 사용 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 ]

즉, ICMPv6이 아닌 ICMP만 처리하므로 다음과 같이 간단한 추가 규칙을 추가해야 합니다.

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 ]

관련 정보