ポリシーベースのルーティングを使用したループバックインターフェイスでのパケット転送

ポリシーベースのルーティングを使用したループバックインターフェイスでのパケット転送

次の 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テーブルを代わりに使用しますPREROUTINGPREROUTING

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。リモートシステムでこのトラフィックを拒否できます。

関連情報