次の iptables ルールがあります。
iptables -t mangle -A PREROUTING -p udp -m udp --dport 10000 -j MARK --set-xmark 0x4/0xffffffff
宛先ポートが10000のすべてのUDPパケットにfwmark 4を設定します。 NATなしでポリシーベースのルーティングを使用してそれをトンネルに転送します。
[root@localhost ~]# ip rule
0: from all fwmark 0x4/0x4 lookup 87
32765: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@localhost ~]# ip route show table 87
default dev tunnel scope link
パケットが通常のNIC(eth0
など)から来る場合、すべてがうまく機能しますが、ループバックインターフェイスから送信されたパケット(lo
生成されたパケットを使用するなどsocat -u - UDP:localhost:10000
)はスキップされているようです。PREROUTING
チェーン後のルーティング決定、ローカルホストによって受信されます(実際には、lo
インターフェイスを介してICMPポートに接続できないパケットで応答します)。
これが予想される動作ですか?それでは、この問題をどのように解決できますか?より複雑なiptablesルールセットをテストするためにパケットを使用したいので、他の入力デバイスに異なるパスを持たないようにするパケットが必要ですlo
(つまり、natを使用した追加のルールは私にとって解決策ではありません)。
答え1
これにはいくつかの点が含まれています。
ローカルボックスの出力は、ボックスを通過するトラフィックにOUTPUT
テーブルを代わりに使用しますPREROUTING
。PREROUTING
iptablesルールは、パケットが送信されたときにのみ一致します。クライアントが接続を開くときに単一のパケットを生成する前に、アドレスにバインドする必要があります。バインドするときは、iptablesを参照せずにルーティングルールに従ってソースアドレスを選択します。
宛先としてテストして127.0.0.1
パケットを送信すると、送信元127.0.0.1
アドレスとして送信しようとし、カーネルはデフォルトでルーティングを許可しません。
この問題を解決すると、パケットがインターフェイスを離れ、リモートシステムが戻り方法を知らないソースアドレスを持つようになると、別の問題が発生します。
したがって、解決策は3つあります。
1) OUTPUT テーブルにルールを追加します。
iptables -t mangle -A OUTPUT -p udp -m udp --dport 10000 -j MARK --set-xmark 0x4/0xffffffff
2)ローカルネットワークルーティングを有効にする:
sysctl -w net.ipv4.conf.$iface.route_localnet=1
$iface
トンネルインターフェイスはどこにありますか?
3)MASQUERADE
インターフェイスから発信されるトラフィックの送信元アドレスを書き換えるルールを追加します。
iptables -t nat -A POSTROUTING -o $iface -m addrtype --src-type LOCAL -j MASQUERADE
ただし、127.0.0.1
トラフィック転送をテストするときに問題が発生する可能性があります。何も宛先アドレスを書き換えないため、宛先$iface
アドレスにルーティングされます127.0.0.1
。リモートシステムでこのトラフィックを拒否できます。