質問: linuxネットワーク名前空間間でトラフィックを転送する方法は? ネットワーク名前空間を設定して、名前空間内の127.0.0.1で待機するサーバーを起動することができました。# ip netns add vpn # ip netns exec vpn ip link set dev lo up # ip netns exec vpn nc -l -s 127.0.0.1 -p 80 & # ip netns exec vpn netstat -tlpn active internet connections (only servers) proto recv-q send-q local address foreign address state pid/program name tcp 0 0 127.0.0.1:80 0.0.0.0:* listen 5598/nc その後、名前空間内のサーバーに接続できます。# ip netns exec vpn nc 127.0.0.1 80 -zv localhost [127.0.0.1] 80 (http) open しかし、名前空間の外のサーバーに接続できません。# nc 127.0.0.1 80 (unknown) [127.0.0.1] 80 (http) : connection refused グローバルネームスペースからvpnネームスペースにトラフィックを転送するようにiptablesまたはネームスペースを設定するにはどうすればよいですか?
回答: まず、127.0.0.0/8やループバックインターフェイス(loなど)を使用しても、これを実現できるとは思いません。 127.0.0.0/8とループバックに特定のものが組み込まれているため、他のいくつかのipとインターフェースを使用する必要があります。それから確かに複数の方法がありますが、ここに例があります:# ip netns add vpn # ip link add name vethhost0 type veth peer name vethvpn0 # ip link set vethvpn0 netns vpn # ip addr add 10.0.0.1/24 dev vethhost0 # ip netns exec vpn ip addr add 10.0.0.2/24 dev vethvpn0 # ip link set vethhost0 up # ip netns exec vpn ip link set vethvpn0 up # ping 10.0.0.2 ping 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.134 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.100 ms 最初のコマンドは、仮想イーサネットケーブルで接続された一対の仮想イーサネットインターフェイスをシンエアから作成します。 2番目のコマンドは、これらのインターフェースの1つをnetns vpnに移動します。 socketpair(2)またはpipe(2)のようなものと同等であると考えてください。プロセスはペアを作成してからフォークし、各プロセスはペアの一方の端のみを保持して通信できます。通常(lxc、virt-manager、...)多くのnetnがある場合、すべてを同じlanに配置するために必要なブリッジもあります。これが実行されると、ホストにとっては他のルーターのようになります。 ip転送を有効にします(可能な場合はさらに制限を加えます。少なくともvethhost0とメインインターフェイスに必要です)。# echo 1 > /proc/sys/net/ipv4/conf/all/forwarding 次のようなdnatルールを追加します。# iptables -t nat -a prerouting ! -s 10.0.0.0/24 -p tcp -m tcp --dport 80 -j dnat --to-destination 10.0.0.2 これで、vpn内にデフォルトルートを追加できます。# ip netns exec vpn ip route add default via 10.0.0.1 または、代わりに、snatルールを追加して、すべてがvpn内の10.0.0.1からのものとして表示されるようにします。# iptables -t nat -a postrouting -d 10.0.0.2/24 -j snat --to-source 10.0.0.1 これを実行すると、他のホストからテストできますが、ホスト自体からはテストできません。これを行うには、以前のdnatと同様のdnatルールも追加しますが、outputで独自のipに変更します(それ以外の場合は、送信http接続も変更されます)。あなたのipが192.168.1.2だとしましょう:# iptables -t nat -a output -d 192.168.1.2 -p tcp -m tcp --dport 80 -j dnat --to-destination 10.0.0.2 これで、ホストからそれ自体に接続する場合でも機能しますifループバックipを使用しませんが、上記のようにnatルールでホストに属する他のipを使用します。あなたのipが192.168.1.2だとしましょう:# ip netns exec vpn nc -l -s 10.0.0.2 -p 80 & [1] 10639 # nc -vz 192.168.1.2 80 nc: myhost (192.168.1.2) 80 [http] open # [1]+ done ip netns exec vpn nc -l -s 10.0.0.2 -p 80