
iptables DNAT ルールは再起動するまで機能しません。サーバーを再起動すると、すべてのルールが機能します。
アーキテクチャの説明:
数十のホスト (送信者) が、いくつかの UDP パケット (特定のポート 9999 で一方向) を Linux ルーターに送信します。この Linux ルーターは、iptables を使用して、それらのパケットを複数のホスト (受信者) に転送します。
送信者X 10.0.0.X ====> iptables を備えた Linux ルーター ====> 受信者Y 10.0.1.Y
Linux ルーターには、eth1 10.0.0.1/24 (送信側) と eth0 10.0.1.1/24 (受信側) の 2 つのネットワーク カードがあります。
Iptables の設定:
- ip_forwardingが有効になっています
- すべてのデフォルトポリシーはACCEPTに設定されています
- 送信者ごとに 1 つの iptables ルールが存在します。次に例を示します。
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
ネットワークセットアップ :
ip addr show
:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 54:9f:35:0a:16:38 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.1/24 brd 10.0.1.255 scope global eth0
inet6 fe80::569f:35ff:fe0a:1638/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 54:9f:35:0a:16:3a brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global eth1
inet6 fe80::569f:35ff:fe0a:163a/64 scope link
valid_lft forever preferred_lft forever
症状 :
一連のルールを追加した後、一部のルールが機能しなくなりました。また、tcpdump で UDP パケットがルーティングされなくなり、パケットが拒否されていることが確認できます。
tcpdump -n -i eth1 host 10.0.0.2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
16:12:58.241225 IP 10.0.0.2.56859 > 10.0.0.1.9999: UDP, length 1464
16:12:58.241285 IP 10.0.0.1 > 10.0.0.2: ICMP 10.0.0.1 udp port 9999 unreachable, length 556
- すべてのルールをフラッシュして iptables に再挿入すると、機能していなかったルールは依然として機能しません。
- サーバーを再起動すると、すべてのルールが正常に機能します。
分析完了:
機能していない特定の送信者をログに記録するルールを追加しました:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j LOG --log-prefix='PREROUTING LOG :'
しかし、このルールは何もログに記録しません。パケットはtcpdumpで確認できるので来ていますが、ログには記録されません。また、-v
iptablesのオプションを使用しても、このルールのカウンターが増加しているようには見えません。
動作が停止する前に同じルールを適用すると、ログがいくつか残ります。
質問 :
- iptables での UDP 転送に制限はありますか?
- この問題をトラブルシューティングするにはどうすればいいでしょうか?
答え1
あなたが説明した症状は、NAT ルールと接続追跡エントリの間に競合がある場合に見られる症状と一致します。
例えば、パケットが
-A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
新しい接続追跡エントリを作成する必要があります。これにより、受信側の送信元と宛先の IP とポートのタプルが、送信側の同様のタプルにマッピングされます。
着信側に一致する既存の接続追跡エントリは存在できません。存在する場合、ルールの代わりにそのエントリが使用されるためです。ただし、タプルの宛先 IP が置き換えられて発信側のタプルが構築されると、タプルは既存の接続追跡エントリと競合する可能性があります。
conntrack
このユーティリティをインストールすると、conntrack -L
既存の接続追跡エントリのリストを表示できます。このユーティリティには、特定の条件に一致する接続追跡エントリのみをリストする機能や、選択したエントリを削除する機能もあります。
これが実際に直面している問題である場合、問題の原因となっている接続追跡エントリを削除すると、問題は解消されます。永続的な修正には通常、両方向のパケットに関連する NAT ルールを構成することが含まれます。これにより、最初のパケットが通常とは逆方向に送信された場合でも、常に目的の接続追跡エントリを取得できます。