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_protoip_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
    #
    

    失敗の唯一の手がかりはゼロ以外の戻りコードです。

    最新製品を使用しながら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になります。

おすすめ記事