Network NamespaceにてNAT
今回のNetwork NamespaceではNATを実現。ネットワーク環境は下記である。
中央のルーターがNAT機能を持ち、左側ネットワークがNAT内側、右側ネットワークがNAT外側である。
構築
NG1
まずはトライアンドエラー1回目。NG例の紹介。
- Namespaceを一つだけ作成し(ns1)、仮想ネットワークインターフェースペアを2つ作成(veth1とns1-veth、veth00とveth01)
- veth1とveth00とがNATルーター(後述するiptableコマンドにてNATの設定)
- veth1の左側がNAT内側、veth00の右側がNAT外側
- それぞれの仮想ネットワークインターフェースにIPアドレスをアサイン
が、1st space(ログイン後のシェルが起動している空間)から、ns1-vethへのpingが通ってしまう。
NG2
- Namespaceを二つ作成し(ns1およびns2)、Namespace内に仮想ネットワークインターフェースペアを作成(ns1-veth0とns1-veth、ns2-veth0とns2-veth)
- ns1にてns2側ネットワークへのルートの宛先をns1-veth0、ns2にてns1側ネットワークへのルートの宛先をns2-veth0
が、ns1-veth0とns2-veth0とをつなげられず(ブリッジ化できず)、これもNG。
OKだが複雑
下記は機能したが複雑。
- Namespaceを二つ作成(ns1およびns2)し、仮想ネットワークインターフェースペアを作成(veth1とns1-veth、veth2とns2-veth、ns1-veth10とns1-veth11、ns2-veth20とns1-veth22)
- ns1-vethとns1-veth10、ns2-vethとns2-veth20をブリッジ化
- veth1、veth2、ns1-veth11、ns2-veth22にIPアドレスをアサイン
- 1st spaceにて、IP Forwardにより、veth1とveth2との間の転送を有効化後、NAT化
コマンド多数必要、複雑。
OK:これがEasy
トライを続け、下記構成が最も簡単であると判断。
以降、コマンド解説。
sudo ip netns add ns1
sudo ip link add name veth1 type veth peer name ns1-veth
sudo ip link set ns1-veth netns ns1
sudo ip link set veth1 up
sudo ip addr add 172.16.1.1/24 dev veth1
sudo ip netns exec ns1 ip link set lo up
sudo ip netns exec ns1 ip link set ns1-veth up
sudo ip netns exec ns1 ip addr add 172.16.1.11/24 dev ns1-veth
- Namespace ns1作成
- 仮想ネットワークインターフェースPairであるveth1およびns1-veth作成
- ns1-vethをns1に配置
- veth1をUpし、IPアドレスアサイン
- ns1のループバックおよびns1-vethをUp
- ns1のns1-vethにIPアドレスアサイン
sudo ip netns add ns2
sudo ip link add name veth2 type veth peer name ns2-veth
sudo ip link set ns2-veth netns ns2
sudo ip link set veth2 up
sudo ip addr add 10.1.1.1/24 dev veth2
sudo ip netns exec ns2 ip link set lo up
sudo ip netns exec ns2 ip link set ns2-veth up
sudo ip netns exec ns2 ip addr add 10.1.1.22/24 dev ns2-veth
- 上記ns1設定内容を、ns2にて実施
sudo sysctl -w net.ipv4.ip_forward=1
sudo ip netns exec ns1 ip route add 10.1.1.0/24 via 172.16.1.1
#sudo ip netns exec ns2 ip route add 172.16.1.0/24 via 10.1.1.1
- 1st space(ログイン時のシェルが起動している空間)のIP Forward(転送)を有効化
- ns1にてns2ネットワークへのスタティックルート設定
- (コメント化、未実行、後述)ns2にてns1ネットワークへのスタティックルート設定
検証
NAT構築前
まず、NAT(後述iptablesコマンド)構築前に、上述したコメント文を外し、
sudo ip netns exec ns2 ip route add 172.16.1.0/24 via 10.1.1.1
を実施時(スタティックルート)の結果を記す。左側PCから右側PCへのping時のns2でのtcpdumpの結果である。
$ sudo ip netns exec ns1 ping 10.1.1.22 -c 1
PING 10.1.1.22 (10.1.1.22) 56(84) bytes of data.
64 bytes from 10.1.1.22: icmp_seq=1 ttl=63 time=0.083 ms
$ sudo tcpdump -nel -i veth2
18:07:18.447930 76:a5:94:32:bb:bf > 32:c7:9a:bf:0a:62, ethertype IPv4 (0x0800), length 98: 172.16.1.11 > 10.1.1.22: ICMP echo request, id 2532, seq 1, length 64
18:07:18.447941 32:c7:9a:bf:0a:62 > 76:a5:94:32:bb:bf, ethertype IPv4 (0x0800), length 98: 10.1.1.22 > 172.16.1.11: ICMP echo reply, id 2532, seq 1, length 64
Echo Requestを送出しているパケットのIPアドレスが、左側PCの172.16.1.11であることがわかる(NAT適用前なので当然)。
NAT構築
下記iptablesコマンドにより、1st space内でNATを構築する。
sudo iptables -t nat -A POSTROUTING -o veth2 -j MASQUERADE
sudo iptables -P FORWARD DROP
sudo iptables -A FORWARD -i veth1 -o veth2 -j ACCEPT
sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
この時の左側PCから右側PCへのping時のns2でのtcpdumpの結果は下記となる。(NAT構築前のコメント文はそのまま(未実行)。)
$ sudo ip netns exec ns1 ping 10.1.1.22 -c 1
PING 10.1.1.22 (10.1.1.22) 56(84) bytes of data.
64 bytes from 10.1.1.22: icmp_seq=1 ttl=63 time=0.089 ms
$ sudo tcpdump -nel -i veth2
18:03:43.935497 76:a5:94:32:bb:bf > 32:c7:9a:bf:0a:62, ethertype IPv4 (0x0800), length 98: 10.1.1.1 > 10.1.1.22: ICMP echo request, id 2730, seq 1, length 64
18:03:43.935518 32:c7:9a:bf:0a:62 > 76:a5:94:32:bb:bf, ethertype IPv4 (0x0800), length 98: 10.1.1.22 > 10.1.1.1: ICMP echo reply, id 2730, seq 1, length 64
Echo Requestを送出しているパケットのIPアドレスが、左側PCの172.16.1.11ではなく、NATにて変換された、10.1.1.1であることがわかる。OK。
EOF