UbuntuのNAT環境下でForward
UbuntuのNAT環境下で、iptablesを用いてパケットの転送を行ったときのメモ。
ネットワーク
iptablesを用いてLubuntuにNAT環境を構築。左がNAT外側(172.16.1.0/24)、右がNAT内側(192.168.1.0/24)である。末端のPCはすべて、Buster dogというLinux VMである。以降、Lubuntuの設定や実行状況を記載。
0. 転送設定
まずは、下記転送設定が必要。
$ sudo sysctl -w net.ipv4.ip_forward=1
1. IP Forward
ここでいう”IP Forward”は、”1 by 1 Static NAT”のようなもの。上記ネットワークにて、NAT外側IPアドレスである”172.16.1.254”をNAT内側IPアドレス”192.168.1.11 (Bdog2)”に対応させる(転送する)。
設定
Static NATの転送設定。
$ sudo iptables -t nat -A PREROUTING -i enp0s3 -j DNAT --to-destination 192.168.1.11
この設定だけでは、上記のNAT内側のBdog3からNAT外側Bdog1への通信ができてしまう。そこで、
$ sudo iptables -P FORWARD DROP
$ sudo iptables -A FORWARD -s 192.168.1.11 -j ACCEPT
$ sudo iptables -A FORWARD -i enp0s3 -j ACCEPT
により、FORWARDフィルターを用いて、”192.168.1.11 (Bdog2)”のみ通信できるよう設定する。最終的な設定状況は下記。
$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- anywhere anywhere to:192.168.1.11
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- 192.168.1.11 anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
検証
”172.16.1.11 (Bdog1)”から、LubuntuのNAT外側IPアドレス”172.16.1.254”へのpingを実行。
$ ping -c 3 172.16.1.254
PING 172.16.1.254 (172.16.1.254) 56(84) bytes of data.
64 bytes from 172.16.1.254: icmp_seq=1 ttl=63 time=3.02 ms
64 bytes from 172.16.1.254: icmp_seq=2 ttl=63 time=1.22 ms
64 bytes from 172.16.1.254: icmp_seq=3 ttl=63 time=1.18 ms
--- 172.16.1.254 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 1.184/1.808/3.018/0.855 ms
Wiresharkで取得したNAT外側の状況は下記となる。
当然であるが、”172.16.1.11 (Bdog1)”と”172.16.1.254 (Lubuntu NAT外側)”とが見える。NAT内側の状況は下記となる。
”172.16.1.11 (Bdog1)”と”192.168.1.11 (Bdog2)”とが見え、”172.16.1.254 (Lubuntu NAT外側)”が”192.168.1.11 (Bdog2)”に変換されていることがわかる。
2. Port Forward
ここでは、NAT外側のTCPポート60011をNAT内側”192.168.1.11 (Bdog2)”のTCPポート60011にPort Forward、NAT外側のTCPポート60022をNAT内側”192.168.1.22 (Bdog3)”のTCPポート60022にPort Forwardするものとする。(それ以外の通信は不可とする。)
設定
Port Forwardの設定
$ sudo iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 60011 -j DNAT --to-destination 192.168.1.11:60011
$ sudo iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 60022 -j DNAT --to-destination 192.168.1.22:60022
同じく、FORWARDによるフィルタリングが必要。
$ sudo iptables -P FORWARD DROP
$ sudo iptables -A FORWARD -i enp0s3 -p tcp --dport 60011 -j ACCEPT
$ sudo iptables -A FORWARD -i enp0s3 -p tcp --dport 60022 -j ACCEPT
$ sudo iptables -A FORWARD -s 192.168.1.11 -p tcp --sport 60011 -j ACCEPT
$ sudo iptables -A FORWARD -s 192.168.1.22 -p tcp --sport 60022 -j ACCEPT
最終的な設定状況は下記。
$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:60011 to:192.168.1.11:60011
DNAT tcp -- anywhere anywhere tcp dpt:60022 to:192.168.1.22:60022
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:60011
ACCEPT tcp -- anywhere anywhere tcp dpt:60022
ACCEPT tcp -- 192.168.1.11 anywhere tcp spt:60011
ACCEPT tcp -- 192.168.1.22 anywhere tcp spt:60022
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
検証
NAT内側”192.168.1.11 (Bdog2)”にて下記(netcat)を実行。TCPポート60011のListenである。
$ nc -l -p 60011
NAT内側”192.168.1.22 (Bdog3)”にて下記(netcat)を実行。TCPポート60022のListenである。
$ nc -l -p 60022
”172.16.1.11 (Bdog1)”にて、LubutuのNAT外側IPアドレスに向けて”netcat”を実行(TCPポート(60011および60022)を指定したTCPセッション確立)。
$ nc -z 172.16.1.254 60011
$ nc -z 172.16.1.254 60022
Wiresharkで取得したNAT外側の状況は下記となる。
特異事項なし。NAT内側の状況は下記となる。
TCPポート60011通信は”192.168.1.11 (Bdog2)”へ、TCPポート60022通信は”192.168.1.22 (Bdog3)”へ転送されていることがわかる。
EOF