発信するすべてのDNSクエリを127.0.0.1:53のローカルスタブリゾルバにリダイレクトします。

発信するすべてのDNSクエリを127.0.0.1:53のローカルスタブリゾルバにリダイレクトします。

LinuxシステムからのすべてのDNSクエリをローカルキャッシュスタブリゾルバ(バインドされていない)にリダイレクトしようとしています。

iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to 1.1.1.1:53
iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 1.1.1.1:53
iptables -t nat -A POSTROUTING -j MASQUERADE

上記のルールを使用すると、すべての発信DNSクエリがブロックされ、1.1.1.1のDNSサーバーにリダイレクトされます。

ただし、「1.1.1.1」を「127.0.0.1」に置き換えると、すべてのDNSクエリが失敗し、ローカルスタブリゾルバにリンクされません。

以下のsysctlパラメータを渡しました。

sysctl -w net.ipv4.conf.eth0.route_localnet=1

しかし、私の問題はまだ同じです。どんなアドバイス?

ベストアンサー1

strace、および/を使用してncデバッグすると、元の出口に選択したアドレスが変更されないことsocatが明らかになります。おそらく、まだ「ルーティング」するローカルアドレスと見なされるので、変更する必要はありません。ここでは、そのルールは機能しません。nat/POSTROUTINGMASQUERADEloMASQUERADE

とにかくそのようなことが起こりました。だから返信するときUDPプロトコルクエリを実行すると、サーバーは実際にデータを送信したソースに再接続され、ターゲットとして使用されます。当然、その宛先、すなわち同じローカルアドレスに対して最良のソースが選択される。いいえ127.0.0.1。したがって、conntrack -Eローカル IP 192.0.2.2 とターゲット 198.51.100.1 UDP ポート 53 の例を使用すると、次のような結果が得られます。

    [NEW] udp      17 30 src=192.0.2.2 dst=198.51.100.1 sport=40037 dport=53 [UNREPLIED] src=127.0.0.1 dst=192.0.2.2 sport=53 dport=40037
    [NEW] udp      17 30 src=192.0.2.2 dst=192.0.2.2 sport=53 dport=40037 [UNREPLIED] src=172.16.0.22 dst=172.16.0.22 sport=40037 dport=53

応答は最初のクエリとは関係がないため(ソースIPが127.0.0.1ではないため)、conntrackはそれを2番目のストリームとして扱います。同時に、クライアントはUDPソケットを接続モードに設定します。これは、誤った送信元IP(正しいポートでも)で受信されたUDPパケットが拒否され、サーバーがICMPエラーを受信することを意味します(これは目撃によって可能ですtcpdump -i lo)。

修正はとても簡単です。MASQUERADEbutを使用しないでくださいSNAT。もちろん、この特定のストリームに固有でなければならないので(SNATすべてを127.0.0.1に変換したくない)、MASQUERADEこの行を次に置き換えます。

iptables -t nat -A POSTROUTING -p udp --dport 53 -j SNAT --to-source 127.0.0.1

変更されたフローを使用すると、ローカルサーバーはconntrackの予想されるアドレスで応答します。これを前のフローに関連付け、正しくSNATを解放します。

    [NEW] udp      17 30 src=192.0.2.2 dst=198.51.100.1 sport=38871 dport=53 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=53 dport=38871
 [UPDATE] udp      17 30 src=192.0.2.2 dst=198.51.100.1 sport=38871 dport=53 src=127.0.0.1 dst=127.0.0.1 sport=53 dport=38871

クライアントは期待ソース 198.51.100.1 を受信し、すべてが期待どおりに動作します。

伝送制御プロトコル192.0.2.2 と 127.0.0.1 の間に接続が確立されると、応答は確立された同じ接続内にあるため、同じ結果は発生しません。これはUDPのような新しい接続ではないため、既に予想されるソースがあり、正しく処理されます。 conntrackで。一貫性のために、以下を追加することをお勧めします。

iptables -t nat -A POSTROUTING -p tcp --dport 53 -j SNAT --to-source 127.0.0.1

2つの注意事項:

  • 場合によっては、route_localnetすべてのパケットがローカルで残りますので必要ありませんlo。逆に、127.0.0.1に送信されたパケットを転送するには(他のトリックと共に)必要です。

  • DNSサーバーが外部にクエリを送信するDNSクライアントでもある場合(再帰DNSサーバーの場合)、または独自のクエリが独自に再ルーティングされてループを生成する場合は、追加の例外ルールが必要になることがあります。通常、サーバーを特定のユーザーとして実行し、iptablesを使用して解決します。-m ownerマッチ。各ルールセット(nat/OUTPUTおよびnat/POSTROUTING)の前に次の内容を挿入するのと同じです。

    iptables -t nat -I .... -m owner --uid-owner unbound -j RETURN
    

おすすめ記事