DNS 要求をリモートの systemd-resolved にリダイレクトするにはどうすればよいですか?

DNS 要求をリモートの systemd-resolved にリダイレクトするにはどうすればよいですか?

私は、system-resolved をリモート DNS キャッシュ サーバーとして作成しようとしていました (そうする意図はないことは承知しています)。net.ipv4.conf.br0.route_localnet を 1 に変更し、次の nftable ルールを追加しました。

table ip nat {
    chain prerouting {
        type nat hook prerouting priority 100; policy accept;
        iif "br0" udp dport 53 counter packets 6 bytes 366 dnat to 127.0.0.53
    }

    chain postrouting {
        type nat hook postrouting priority -100; policy accept;
        ip saddr 127.0.0.53 oif "br0" counter packets 0 bytes 0 snat to 192.168.1.2
    }
}

ルールに一致するパケットがあるため、事前ルーティング ルールは機能しているようです。ただし、ホストからパケットが送信されません。何が問題なのでしょうか。

192.168.1.0/24 からの DNS 要求を、IP 127.0.0.53 の 192.168.1.2 の lo デバイスでホストされている systemd-resolved にリダイレクトするにはどうすればよいですか?

答え1

systemd-resolvedインターフェースにバインドしますlo:

# ss -aunp src == 127.0.0.53 sport == 53
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port 
UNCONN 0      0      127.0.0.53%lo:53         0.0.0.0:*     users:(("systemd-resolve",pid=44157,fd=17))

net.ipv4.conf.br0.route_localnet=1これにより、インターフェイスに設定されたルートに一度適用された場合でも、利用可能なルートが制限されますlo

$ ip -4 route show table all dev lo
broadcast 127.0.0.0 table local proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 table local proto kernel scope host src 127.0.0.1 
local 127.0.0.1 table local proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 table local proto kernel scope link src 127.0.0.1 

一致するものはありません。

送信元アドレスを変更する必要があります。あまり使用されないtype nat hook inputチェーン タイプでは、アプリケーションが受信する前に送信元アドレスを変更できますが、すでに遅すぎます。これはルーティングが完了した後に発生し、パケットはすでにドロップされています。そのため、ステートフル NAT ではこのケースを処理できません。


代わりにプロキシを使うこともできます(特定のNAT設定をすべて削除した後)。以下はプロキシを使った例です。socatsocat専用アプリケーションではないため、特に UDP には注意点があります。

  • TCP 処理 (OP は DNS も TCP を使用することを忘れていました)

    socat TCP4-LISTEN:53,bind=192.168.1.2,reuseaddr,fork TCP4:127.0.0.53:53
    

    127.0.0.53:53 はすでにバインドされているためバインドできませんIN_ADDR_ANY。そのため、OP が指定したアドレス (間違った理由により) 192.168.1.2 にバインドします。それ以外は非常に簡単です。

  • UDP処理

    socat -T 20 UDP4-LISTEN:53,bind=192.168.1.2,reuseaddr,fork UDP4:127.0.0.53:53
    

    20 秒のタイムアウトが設定されているのは、socat単一の UDP パケット応答を受信した直後に停止するように指示することができず、socat時間の経過とともにすべてのフォークされたコマンドが蓄積され続けるためです。

    この場合、UDPはアドレスにバインドする必要はありませんが、UDPを使用してアドレスにバインドすると、マルチホーミングに関連する警告と、IP_PKTINFOソケットオプション。

関連情報