nftables dnat 매핑 규칙이 자동으로 실패합니다.

nftables dnat 매핑 규칙이 자동으로 실패합니다.

아래 답변을 바탕으로 작업 중입니다.이것질문과 내 구성에 몇 가지 규칙을 만들기 man nft위해 .dnatnftables

관련 구성 발췌 내용은 다음과 같습니다.

define src_ip       = 192.168.1.128/26
define dst_ip       = 192.168.1.1
define docker_dns   = 172.20.10.5

table inet nat {
    map dns_nat {
        type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
        flags interval
        elements = {
            $src_ip . $dst_ip . udp . 53 : $docker_dns . 5353,
        }
    }
    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        
        dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
    }
}

이 규칙을 적용하면 nft -f명령 출력이 표시되지 않으므로 성공했다고 가정합니다. 그런데 규칙을 이용해 규칙세트를 확인해 보니 nft list ruleset규칙이 없습니다. 해당 줄이 주석 처리 dnat to ...되면 규칙이 적용되는 것처럼 보이지만 해당 줄이 있을 때는 적용되지 않습니다.

prerouting교체하려는 체인의 규칙 세트는 다음과 같습니다.

ip saddr $src_ip ip daddr $dst_ip udp dport 53 dnat to $docker_dns:5353;
...

버전 정보:

# nft -v
nftables v1.0.6 (Lester Gooch #5)
# uname -r
6.1.0-11-amd64

왜 이것이 작동하지 않을 수 있습니까? 감사해요

답변1

질문이 3개 있습니다.

  • 오류가 표시되지 않음

    이거 버그 같은데nftables1.0.6, 아래 글머리 기호를 참조하세요.

    동일한 버전과 OP의 규칙 세트는 다음과 같습니다 /tmp/ruleset.nft.

    # nft -V
    nftables v1.0.6 (Lester Gooch #5)
    [...]
    # nft -f /tmp/ruleset.nft 
    /tmp/ruleset.nft:7:38-45: Error: unknown datatype ip_proto
            type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
                                         ^^^^^^^^
    /tmp/ruleset.nft:6:9-15: Error: set definition does not specify key
        map dns_nat {
            ^^^^^^^
    
  • 오류: 알 수 없는 데이터 유형ip_proto

    원래 링크된 Q&A에서는 올바른 유형을 사용합니다 inet_proto. ip_proto알 수 없는 유형 으로 교체하면 안 됩니다 . 따라서 다음으로 다시 바꾸십시오.

    type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
    

    원래 철자를 수정하세요.

    type ipv4_addr . ipv4_addr . inet_proto . inet_service : ipv4_addr . inet_service
    

    사용 가능한 유형 목록은 다음 nft(8)에서 찾을 수 있습니다.페이로드 표현보다 정확하게는 이 경우IPv4 헤더 표현:

    핵심 단어 설명하다 유형
    [...]
    protocol 상위 계층 프로토콜 inet_proto
    [...]

    typeof ip protocol<=> type inet_proto(아님 type ip_proto).

    이는 올바른 유형을 추측하는 것을 피하기 위해 일반적 typeof으로 선호 되지만type제가 링크된 Q&A에 썼듯이, 일부 버전nftables이 특정 사례는 올바르게 처리되지 않을 수 있습니다. 대안은 다음과 같습니다:

    typeof ip saddr . ip daddr . ip protocol . th dport : ip daddr . th dport
    

    이는 사용 규칙을 잘라내고 붙여넣은 것과 비슷하지만 동작을 철저히 테스트해야 합니다.

  • 표시된 오류 없음 - 테이크 2

    이전 오류를 수정하고 결과를 에 넣으면 /tmp/ruleset2.nftOP가 작성한 것처럼 규칙 세트를 다시 시도하면 자동으로 실패합니다.

    # nft -V
    nftables v1.0.6 (Lester Gooch #5)
      cli:        editline
      json:       yes
      minigmp:    no
      libxtables: yes
    # nft -f /tmp/ruleset2.nft
    # echo $?
    1
    #
    

    실패에 대한 유일한 단서는 0이 아닌 반환 코드입니다.

    최신 제품을 사용하면서도nftables버전:

    # nft -V
    nftables v1.0.8 (Old Doc Yak #2)
      cli:        editline
      json:       yes
      minigmp:    no
      libxtables: yes
    # nft -f /tmp/ruleset2.nft 
    /tmp/ruleset2.nft:16:9-12: Error: specify `dnat ip' or 'dnat ip6' in inet table to disambiguate
            dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
            ^^^^
    #
    

    이제 오류가 표시됩니다. 1.0.6에 어떤 문제가 있었든 적어도 버전 1.0.8에서는 수정되었습니다.

  • 오류: 명확하게 하려면 inet 테이블에 "dnat ip" 또는 "dnat ip6"을 지정하십시오.

    NAT는 (IPv4) 또는 (IPv6) inet제품군이 아닌 제품군(IPv4+IPv6 결합)에서 수행되므로 일반적으로 선택적 매개 변수가 필요합니다. NAT를 적용해야 하는 IP 버전 선언(가능하더라도) 지도 테이블 레이아웃(IPv4)에서 추론). 문서에는 다음과 같이 나와 있습니다.ipip6

    NAT 문

    snat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
    dnat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
    masquerade [to :PORT_SPEC] [FLAGS]
    redirect [to :PORT_SPEC] [FLAGS]
    

    [...]

    inet 계열과 함께 사용하는 경우(커널 5.2에서 사용 가능)dnat 및 snat 문에는 ip 및 ip6 키워드를 사용해야 합니다.주소가 제공된 경우 아래 예를 참조하세요.

    그래서:

    dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
    

    다음으로 교체해야 합니다:

    dnat ip to ip saddr . ip daddr . ip protocol . th dport map @dns_nat
    

    ip원래 Q/A에는 이 시리즈에 대한 언급이 없었기 때문에 기본 시리즈로 가정하고 굳이 할 필요는 없을 것 같습니다 .

    물론 이것은 작동합니다nftables1.0.6에서는 버그 보고만 문제가 됩니다. 이제 반환 코드는 0이 됩니다.

관련 정보