如何使用网络命名空间进行 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/

其目标基本上是与namespaced-openvpn相反(https://github.com/slingamn/namespaced-openvpn)因此 vpn protected 命名空间是默认命名空间,未连接 vpn 连接的命名空间是新命名空间。

我目前所做的不起作用,我想我应该以某种方式将 IP 地址添加到网桥/虚拟网卡或 enp0s3 中?

谢谢你的帮助!

其他来源:
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 层模式下使用 ipvlan 而不是 macvlan (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

测试新命名空间是否具有所需的连接。请注意,我使用 fping 来检查 ping 是否成功(安装 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 来运行其他程序。或者您可以打开多个终端。

故障排除:
#enable 转发

 sysctl -w net.ipv4.ip_forward=1

#访问ns中的snap包,在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 服务提供商路由器),但此时访问 Internet 可能不起作用。您需要提供默认命名空间中的“ip Route show”、“ip Route Show Table All”、“ip Rule Show”、“iptables-save”、“cat /etc/resolv.conf”等命令的输出。以及来自新网络命名空间 bash 会话的“cat /etc/resolv.conf”。假设这些输出中没有敏感信息。

相关内容