iptables (2) ~ NAT ~

September 03, 2017

iptables の機能

・パケットフィルタリング: 特定の条件を満たす IP パケットだけ送受信を許可
・NAT: DNAT、SNAT、MASQUERADE 等、ルーターとしての機能

今回は二つ目の機能「 NAT 」についてです。
SNAT/MASQUERADE の仕組みと設定例について以下にまとめます。

SNAT/MASQUERADE の仕組み

SNAT/MASQUERADE では Server 2 のデフォルトゲートウェイを Server 1 の Private IP アドレスに指定し、インターネット上のサーバー ( B.B.B.B ) を送信先 IP アドレスに指定したパケットを Server 2 から Server 1 を経由して送信することが可能となる。

f:id:shiro_kochi:2018××××××××:plain:w100:left

ポイント

  1. Server 1 が外部サーバーからの戻りパケットを正しく送信するには、対応するリクエストパケット送信元 ( Server 2 ) の IP アドレス ( 10.1.51.147 ) を記憶する必要がある
  2. 上記の図には、Server 1 の SNAT を利用するのは Server 2 しかないが、実際は複数存在する可能性がある。そのため、Server 1 は TCP/UDP パケットの送信元ポート番号をキーとし、送信元 IP アドレスを記憶する
    ( 例えば、Server 2 から送信元ポート番号が 3021 のパケットを受信して、インターネットに転送した際、ポート番号 3021 と Server 2 の IP アドレス 10.1.51.147 をマッピングする )
  3. 2 により、インターネット上のクライアントからレスポンスが来た際に、ポート番号からレスポンスを転送するべき相手を正しく選択できる
  4. 複数の送信元が利用するポート番号が重複した場合は、Server 1 は送信元ポート番号も変換してパケットを転送する
    ( 変換後のポートは現在 Server 1 で利用されていないもの )

SNAT/MASQUERADE の設定例

パケットフィルタリングの際に適用した iptables の設定を Server 1 から削除する。

$ sudo cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Sat Sep  2 09:38:33 2017
*filter
:INPUT ACCEPT [589:130328]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [413:279548]
-A INPUT -s 10.1.77.146/32 -p icmp -j LOG --log-prefix "[INPUT]"
-A INPUT -s 10.1.77.146/32 -p icmp -j DROP
-A INPUT -s 10.1.77.146/32 -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -p icmp -j LOG --log-prefix "[OUTPUT] "
COMMIT
# Completed on Sat Sep  2 09:38:33 2017

$ sudo iptables -D INPUT -s 10.1.77.146/32 -p icmp -j LOG --log-prefix "[INPUT]"
$ sudo iptables -D INPUT -s 10.1.77.146/32 -p icmp -j DROP
$ sudo iptables -D INPUT -s 10.1.77.146/32 -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
$ sudo iptables -D OUTPUT -p icmp -j LOG --log-prefix "[OUTPUT] "
$ sudo iptables -D OUTPUT -p icmp -j LOG --log-prefix "[OUTPUT] "
$ sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

$ sudo cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Sat Sep  2 17:14:02 2017
*filter
:INPUT ACCEPT [81:5900]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [52:4480]
COMMIT
# Completed on Sat Sep  2 17:14:02 2017

Server 2 に、「 13.112.48.35 にアクセスする際のゲートウェイを Server 1 ( 10.1.51.165 ) とする 」という設定を追加。

$ sudo ip route add 13.112.48.35/32 via 10.1.51.165
$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         ip-10-1-51-1.ap 0.0.0.0         UG    100    0        0 eth0
10.1.51.0       0.0.0.0         255.255.255.0   U     100    0        0 eth0
ec2-13-112-48-3 server1         255.255.255.255 UGH   0      0        0 eth0

次に、Server 1 でパケットの転送を許可するように、/etc/sysctl.confnet.ipv4.ip_forward = 1 に変更し、以下のコマンドを実行。

$ sudo sysctl -p
net.ipv4.ip_forward = 1

最後に、/etc/sysconfig/iptables に *nat セクション部分の記述を追加し、設定内容をアクティブにする。

$ sudo systemctl stop iptables

$ sudo cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Sat Sep  2 17:14:02 2017
*filter
:INPUT ACCEPT [81:5900]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [52:4480]
COMMIT
# Completed on Sat Sep  2 17:14:02 2017

*nat
:POSTROUTING ACCEPT
-A POSTROUTING -s 10.1.51.147/32 -j MASQUERADE

$ sudo systemctl start iptables

$ sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

以下のコマンドによりロギング。

$ sudo iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 -j LOG --log-prefix "[raw/PREROUTING] "
$ cat /var/log/messages
Sep  2 20:19:24 ip-10-1-51-165 kernel: [raw/PREROUTING] IN=eth0 OUT= MAC=0a:11:d1:09:77:ce:0a:5b:5e:31:67:02:08:00 SRC=10.1.51.147 DST=13.112.48.35 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=55029 DF PROTO=TCP SPT=47312 DPT=80 WINDOW=26883 RES=0x00 SYN URGP=0

( ちなみに EC2 インスタンスを使ってますが、送信元/送信先のチェックを無効にするのを忘れていてかなりハマりました… )


 © 2023, Dealing with Ambiguity