VPN分割トンネリングにネットワーク名前空間を使用する方法

VPN分割トンネリングにネットワーク名前空間を使用する方法

私の目標は、VPNを介してデフォルトの名前空間をルーティングし、VPNを介してルーティングされない新しい名前空間を作成することです。これにより、リモートVPNネットワークにアクセスできないプログラムを選択的に起動できます。

LANアドレス: enp0s3の10.0.2.15/24
VPNアドレス: tun1の10.111.0.10/24

# enable forwarding
sysctl -w net.ipv4.ip_forward=1
# create the network namespace
ip netns add sample_ns
# create the virtual nic and it's peer
ip link add virt_out type veth peer name virt_in

# assign the peer to the network namespace
ip link set virt_in netns sample_ns
# bring up interface
ip link set virt_out up

#Create a new bridge and change its state to up:
ip link add name bridge_name type bridge
#To add an interface (e.g. eth0) into the bridge, its state must be up:
ip link set enp0s3 up
#Adding the interface into the bridge is done by setting its master to bridge_name:
ip link set enp0s3 master bridge_name
ip link set virt_out master bridge_name
#To show the existing bridges and associated interfaces, use the bridge utility (also part of iproute2). See bridge(8) for details.
bridge link
# assign an ip address
ip addr add 10.0.3.1/24 dev virt_out


#network setup for network namespace
ip netns exec sample_ns ip link set lo up
ip netns exec sample_ns ip addr add 10.0.3.2/24 dev virt_in
ip netns exec sample_ns ip link set virt_in up
ip netns exec sample_ns ip route add default via 10.0.3.2 dev virt_in

# allow forwarding and add enable NAT
iptables -I FORWARD -s 10.0.3.0/24 -j ACCEPT
iptables -t nat -I POSTROUTING -s 10.0.3.0/24 -o enp0s3 -j MASQUERADE

# pop a shell in the namespace
ip netns exec sample_ns bash

# check that you're in the namespace
ip netns identify

# run the browser as your local user
runuser -u $USER google-chrome


#to access snap packages in ns run in the ns: (“error: cannot find tracking cgroup”)
sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup
sudo mount -t securityfs securityfs /sys/kernel/security/

その目標は基本的に名前空間-openvpn(https://github.com/slingamn/namespaced-openvpn)したがって、VPNで保護されている名前空間はデフォルトの名前空間であり、接続されていないVPNに接続されている名前空間は新しい名前空間です。

現在行っている作業は機能しません。どういうわけか、ブリッジ/仮想NICまたはenp0s3にIPアドレスを追加する必要がありますか?

助けてくれてありがとう!

他のソース:
https://forums.openvpn.net/viewtopic.php?f=15&t=25690
https://github.com/ausbin/nsdo

答え1

これを行うには、ブリッジの代わりに他の仮想化ネットワークを使用する方が簡単です。
「veth+bridgeを使用しないでください!macvlanを使用してください!
https://unix.stackexchange.com/a/546090/568691

名前空間を追加

ip netns add sample_ns

macvlanリンクを作成し、それを親ホストenp0s3(https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking/#macvlan)

ip link add mv1 link enp0s3 address 00:11:22:33:44:55 type macvlan mode bridge

アドレスの 00:11:22:33:44:55 部分を省略すると、任意の MAC アドレスが生成されます。物理enp0s3やeth0などと同じMacを使用する場合は、レイヤ2モードでmacvlanの代わりにipvlanを使用できます(https://www.kernel.org/doc/Documentation/networking/ipvlan.txt)。

新しいインターフェイスmv1を新しい名前空間に移動します。

ip link set mv1 netns sample_ns

インターフェイスコール

ip netns exec sample_ns ip link set dev lo up
ip netns exec sample_ns ip link set dev mv1 up

dhclientを使用してIPアドレスを設定します。通常、これによりルーティングも確立されます。

ip netns exec sample_ns dhclient mv1

#dhclientが機能しない場合は、手動でIPとルートを追加してください。

#ip netns exec sample_ns ip addr add $your_ip/24 dev mv1
#ip netns exec sample_ns ip route add default via $your_gateway dev mv1

新しい名前空間に必要な接続があるかどうかをテストします。 pingが成功したこと(fpingがインストールされているかどうか)を確認するためにfpingを使用することに注意してください。

ip netns exec sample_ns sudo fping 1.1.1.1 &>/dev/null && echo "Internet connectivity okay"
ip netns exec sample_ns sudo fping 1.1.1.1 &>/dev/null || echo "No internet"
ip netns exec sample_ns sudo fping google.com &>/dev/null || echo "No DNS service"

次に、新しいネットワーク名前空間からxserverにアクセスできるように設定します。これは、新しい名前空間でプログラムを開くことができない場合にのみ必要です。
デフォルトの名前空間から:

sudo -u $USER xhost +local:$USER
ip netns exec sample_ns bash export DISPLAY=:0

これにより、DISPLAY環境変数がエクスポートされます。たとえば、:1 または :99 とは異なる場合があります。次のコマンドを使用して、デフォルトの名前空間を確認できます。

echo $DISPLAY

次に、新しい名前空間でいくつかのプログラムを実行してください。

 sudo ip netns exec sample_ns sudo -u $USER bash
 /usr/bin/chromium-browser %U

または、これをすぐに実行したい場合:

sudo ip netns exec sample_ns sudo -u $USER /usr/bin/chromium-browser %U

この新しい名前空間で開かれたbashを引き続き使用するには、次のようにコマンドの最後に&を追加して、この親bashとは無関係にすることができます。

 /usr/bin/chromium-browser %U &

これにより、CTRL + Cを押すとプログラムは引き続き実行されますが、bashを再起動して他のプログラムを実行できます。あるいは、複数の端末を開くこともできます。

トラブルシューティング:
#配信を有効にする

 sysctl -w net.ipv4.ip_forward=1

#nsでスナップパッケージにアクセスし、nsで実行します:(「エラー:トレースcgroupが見つかりません」)

sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup
sudo mount -t securityfs securityfs /sys/kernel/security/

他のソース:
ネットワークネームスペースでOpenVPNを実行してみてください。
Linuxネームスペース、ネットワークネームスペースからインターネットに接続する方法は?
Unixプログラムを特定のネットワークインタフェースにバインドする
https://networkstatic.net/configuring-macvlan-ipvlan-linux-networking/

答え2

ここに橋を建設する必要はないと思います。ルーティングだけが必要です。

私はできます。削除する以下は(enp0s3がすでに起動されていると仮定します):

#Create a new bridge and change its state to up:
ip link add name bridge_name type bridge
#To add an interface (e.g. eth0) into the bridge, its state must be up:
ip link set enp0s3 up
#Adding the interface into the bridge is done by setting its master to bridge_name:
ip link set enp0s3 master bridge_name
ip link set virt_out master bridge_name
#To show the existing bridges and associated interfaces, use the bridge utility (also part of iproute2). See bridge(8) for details.
bridge link

私は変更します:

ip netns exec sample_ns ip route add default via 10.0.3.2 dev virt_in

到着する:

ip netns exec sample_ns ip route add default via 10.0.3.1 dev virt_in

これにより、新しいネットワーク名前空間がローカル LAN 10.0.2.0/24 と通信できるようになります (たとえば、サービス プロバイダー ルーターへの ping)、現在インターネット アクセスが機能しない可能性があります。 「ip Route show」、「ip Route Show Table All」、「ip Rule Show」、「iptables-save」、「cat /etc/resolv.conf」などのコマンドの出力をデフォルトの名前空間に提供する必要があります。そして、新しいネットワークネームスペースbashセッションの "cat /etc/resolv.conf"です。これらの出力には機密情報がないと仮定されます。

関連情報