Linuxネットワークの名前空間間でトラフィックを転送する方法は?

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またはネームスペースを設定するには?

ベストアンサー1

まず、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に移動します。ソケットペア(2)またはパイプ(2)と同じであると考えてください。プロセスはペアを作成してフォークし、各プロセスはペアの一端だけを保持して通信できます。

一般に(LXC、virt-managerなど)ネットワークが多い場合は、すべてを同じ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

または、すべてのコンテンツがVPN内の10.0.0.1から来ると見なされるように、SNATルールを追加します。

# 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

これで、ホストから自分で接続しても機能します。もしループバック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

おすすめ記事