web-dev-qa-db-ja.com

IPTables -jDNATが特定のケースで機能しないように見える

ICMP応答パケットの宛先IPアドレスを変更しようとしています。

ICMP応答は、IPSECトンネルからルーターに入力されます(tcpdumpに2回表示される理由は完全にはわかりません)。

14:28:09.562030 IP 35.182.188.86 > 54.76.131.136: ICMP echo request, id 28997, seq 1259, length 64
14:28:09.641595 IP 54.76.131.136 > 35.182.188.86: ICMP echo reply, id 28997, seq 1259, length 64
14:28:09.641645 IP 54.76.131.136 > 35.182.188.86: ICMP echo reply, id 28997, seq 1259, length 64

PREROUTINGテーブルで宛先IPをローカルIP(172.31.20.219)に変更しようとしています。

Sudo iptables -t nat -A PREROUTING --source 54.76.131.136 --destination 35.182.188.86 -j DNAT --to-destination 172.31.20.219

したがって、テーブルは次のようになります。

ubuntu@ip-172-31-23-13:~$ Sudo iptables-save -c
# Generated by iptables-save v1.6.0 on Tue Oct  3 14:58:19 2017
*nat
:PREROUTING ACCEPT [33:2711]
:INPUT ACCEPT [32:2627]
:OUTPUT ACCEPT [8:1080]
:POSTROUTING ACCEPT [9:1164]
[0:0] -A PREROUTING -s 54.76.131.136/32 -d 35.182.188.86/32 -j DNAT --to-destination 172.31.20.219
COMMIT
# Completed on Tue Oct  3 14:58:19 2017
# Generated by iptables-save v1.6.0 on Tue Oct  3 14:58:19 2017
*raw
:PREROUTING ACCEPT [2646:283498]
:OUTPUT ACCEPT [998:168846]
[1954:164136] -A PREROUTING -s 54.76.131.136/32 -d 35.182.188.86/32 -j LOG
[821:68964] -A PREROUTING -s 54.76.131.136/32 -d 35.182.188.86/32 -j TRACE
COMMIT
# Completed on Tue Oct  3 14:58:19 2017

ただし、IPの変更は行われません。

使用する

Sudo iptables -t raw -A PREROUTING --source 54.76.131.136 --destination 35.182.188.86 -j LOG

生のテーブルで一致させることができることがわかります:

Oct  3 14:25:20 ip-172-31-23-13 kernel: [  889.588090] IN=eth0 OUT= MAC=02:fc:a0:12:56:64:02:7f:fe:dc:a4:0d:08:00 SRC=54.76.131.135 DST=35.182.188.85 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=64700 PROTO=ICMP TYPE=0 CODE=0 ID=28997 SEQ=1091

ただし、NATテーブルでは一致しないようです。

宛先IPが変更されない理由、またはこれをさらにデバッグする方法について誰かがアドバイスを提供できますか?とても奇妙に思えます。

Ubuntu16.04を使用しています。着信トラフィックは、StrongSwanを使用したIPSECトンネル設定で着信します。

ありがとう

1
noflowcontrol

ICMPエコー応答パケットは、確立されたフローの一部です。つまり、カーネルが通常の場合にそのようなパケットを受信したとき、カーネルはすでにそれを予期していたので(最初のICMPエコー要求の後)、natに必要なベースブリックであるconntrackはすでにそのパケットの期待値エントリを作成しました。このような場合、NATテーブルは短絡され、この応答パケットに対しても実行されません。

参照: https://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html#ss3.2 (NAT)

このテーブルは、新しい接続の最初のパケットのみがテーブルをトラバースするという点で、「フィルター」テーブルとは少し異なります。このトラバースの結果は、同じ接続内の将来のすべてのパケットに適用されます。

この動作を確認するには、イベントモニターモードで(conntrackパッケージの)conntrackコマンドを使用します。 Googleへのpingが1つある例を次に示します。

# conntrack -E
    [NEW] icmp     1 30 src=192.168.3.2 dst=8.8.8.8 type=8 code=0 id=12837 [UNREPLIED] src=8.8.8.8 dst=198.51.100.5 type=0 code=0 id=12837
 [UPDATE] icmp     1 30 src=192.168.3.2 dst=8.8.8.8 type=8 code=0 id=12837 src=8.8.8.8 dst=198.51.100.5 type=0 code=0 id=12837
[DESTROY] icmp     1 src=192.168.3.2 dst=8.8.8.8 type=8 code=0 id=12837 src=8.8.8.8 dst=198.51.100.5 type=0 code=0 id=12837

最初のパケットは[NEW]エントリを作成するため、期待値を変更する機会を与えるnatテーブルを渡します(この例では、従来のSNAT/MASQUERADE)。このフローの他のパケットは、エントリが破棄されるまで(このicmpでは30秒のタイムアウト)、conntrackの期待値でのみ処理されます。

Natルールを使用すると、新しいフローであるため、最初のICMP PingEcho要求で機能します。

あなたはこれらすべてで実際に何をしたいのかを言いませんでした。パケットを172.31.20.219にコピーすることが目標である場合は、TEEターゲット(man iptables-extensions)を試す必要があります。

1
A.B