編集:tldr:UDPトラフィックのクローンを作成するためにTEEとNATを使用します。応答の処理について心配していません。新しいソフトウェアをインストールしたくないので、TEEを使用しています。ローカルセグメント(127.0.0.2)に正常に送信するには、WANにトラフィックを送信するNAT.
Debianサーバーのポート53でbind9をリッスンしています。このサーバーにDNS要求を行う外部クライアントがあります。これらはすべて正常に機能しています。着信DNS要求をポート53にコピーして、たとえば8.8.8.8に送信したいと思います。単語copyに注意してください。
SUに関する多くのグーグルと読書から、最も頻繁に推奨される方法は、iptables TEEとNATを使用することです。私はTEEをかなりうまく動かしています、これが私のコマンドです:
iptables -t mangle -A POSTROUTING -p udp -d 127.0.0.1 --dport 53 -j TEE --gateway 127.0.0.2
127.0.0.2:53にDNSリクエストのコピーをnetcatで受け取ることを確認しました。ここまでは順調ですね。
次に、宛先IPを変更する必要があります。私はこれを達成しようとします:
iptables -t nat -A PREROUTING -p udp -d 127.0.0.2 --dport 53 -j DNAT --to 8.8.8.8
Tcpdumpを使用して、8.8.8.8への送信トラフィックを監視しました。何もない。私は思った:127.0.0.2に到着しているので、カーネルがこのパケットをドロップしないようにソースIPアドレスを変更する必要があるかもしれませんが、ソースIPは外部DNSクライアントのIPに設定されています。何故なの?
iptables -t nat -A POSTROUTING -p udp -d 127.0.0.2 --dport 53 -j SNAT --to DNS_SERVERS_PUBLIC_IP
それでも、tcpdumpは何も表示しません。
IP転送をオンにしています:
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
私はアイデアがほとんどないので、どんな助けもありがたいです。ありがとうございました。
Iptablesがあれば、不可能はありません。
# iptables -t nat -L -v --line-numbers -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 5 281 MARK udp -- docker0 * 0.0.0.0/0 172.17.0.1 udp dpt:53 MARK set 0xc0fe
2 5 281 TEE udp -- docker0 * 0.0.0.0/0 172.17.0.1 udp dpt:53 TEE gw:127.1.2.3
3 3 167 DNAT udp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0xc0fe to:1.1.1.1:53
インターフェースで操作するのが簡単なので、私はこれをドッカーでテストしていました。これらのルールをnatプレルーティングテーブルの他のルールの前に配置したことに注意してください。
あなたがすることは、あなたが興味のあるパケットをマークし、次にそのパケットをTEE(コピー)し、そして今あなたはそのパケットを1.1.1.1にDNATすることができます。
それらをマークアップします。ここでは、docker0ではなくeth0またはeno1を使用する必要があります。
iptables -t nat -I PREROUTING 1 -i docker0 -p udp -d 172.17.0.1 --dport 53 -j MARK --set-mark 0xc0fe
それをローカルホストにコピー/ティーして、ルールは次のようにすることができます
iptables -t nat -I PREROUTING 2 -i docker0 -p udp --dst 172.17.0.1 --dport 53 -j TEE --gateway 127.1.2.3
しかし、次のようにすることもできます-t nat -I PREROUTING 3 -p udp -m mark --mark 0xc0fe -j TEE --gateway 127.1.2.3
最後に
iptables -t nat -I PREROUTING 3 -p udp -m mark --mark 0xc0fe -j DNAT --to-destination 1.1.1.1:53
こんにちは、マングルテーブルでTEEを使用することを除いて、あなたは正しい道を進んでいました。ここでは、natテーブルでTEEとDNATの両方を使用しています。MARKは、デバッグが簡単で、ルール変更を処理する場合を除いて必要ありません。また、TEEが行くべきだと信じているもののdstにDNATルールを機能させることで、もう1つの間違いがありましたが、TEEとDNATは同じ条件で機能するはずです。しかし、ここではマークのルールはそのままにしておきます。貨物のカルティストと一緒に楽しんでください。
短い形式ではiptables -t nat -I PREROUTING 1 -i eth0 -p udp --dst 172.17.0.1 --dport 53 -j TEE --gateway 127.3.3.3 iptables -t nat -I PREROUTING 2 -i eth0 -p udp --dst 172.17.0.1 --dport 53 -j DNAT --to-destination 1.1.1.1:53
ドキュメントは言う
[〜#〜] tee [〜#〜]ターゲットはパケットのクローンを作成し、このクローンをlocalネットワークセグメント上の別のマシンにリダイレクトします。つまり、ネクストホップをターゲットにする必要があります。そうでない場合は、必要に応じてネクストホップをさらに転送するように設定する必要があります。
この制限の理由はわかりませんが、iptables NATでは解決できないようです。これは、基礎となる実装が外部ターゲットをサポートしている場合、TEEのターゲット範囲を制限する理由です。 TEEはNATレベルの下で行われていると思います。
応答が間違った送信元アドレスで届くため、とにかく機能しません。
TEEは同じサブネットでのみ使用できるため、 Daemonlogger のツールを使用できる場合があります github も使用できます(どこが新しいようですか?)。
Daemonloggerは、Martin Roeschが開発したパケットロガーおよびソフトタップです。 libpcapベースのプログラムには、2つのランタイムモードがあります。
- パケットをスニッフィングして直接ディスクにスプールし、バックグラウンドパケットロギングのためにデーモン化できます。デフォルトでは、2 GBのデータが記録されると、ファイルはロールオーバーされます。
- パケットをスニッフィングし、それらを2番目のインターフェースに書き換え、基本的にソフトタップとして機能します。デーモンモードでもこれを行うことができます。これらの2つのランタイムモードは相互に排他的です。プログラムがタップモードになっている場合(-Iスイッチを使用)、ディスクへのロギングは無効になります。
いくつかの記事: