2

My aim is to route the default namespace through my vpn, and create a new namespace which does not route through the vpn (so i can selectively launch programs that should not have access to the remote vpn network).

lan address: 10.0.2.15/24 on enp0s3
vpn address: 10.111.0.10/24 on tun1

# 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/

The aim is basically the reverse of namespaced-openvpn (https://github.com/slingamn/namespaced-openvpn) so the vpn protected namespace is the default, and the not vpn connected namespace is the new one.

What I am doing currently does not work, I assume I should somehow add ip address to the bridge/the virtual nic or the enp0s3?

Thanks for any help!

Other sources:
https://forums.openvpn.net/viewtopic.php?f=15&t=25690
https://github.com/ausbin/nsdo

2 Answers2

1

It is easier to use other virtualized networking instead of bridges for this purpose.
"Don't use veth + bridge! Use macvlan!"
(from https://unix.stackexchange.com/a/546090/568691)

Add the namespace

ip netns add sample_ns

Create the macvlan link attaching it to the parent host 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

If the address 00:11:22:33:44:55 part is ommitted then a random mac address will be generated. If you want to use the same mac as your physical enp0s3 or eth0 etc. than you can use ipvlan in layer 2 mode instead of macvlan (https://www.kernel.org/doc/Documentation/networking/ipvlan.txt).

Move the new interface mv1 to the new namespace

ip link set mv1 netns sample_ns

Bring the interfaces up

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

Set ip addresses with dhclient - usually this also sets the routing.

ip netns exec sample_ns dhclient mv1

#if dhclient does not work, add ip and route manually:

#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

Test if the new namespace has the desired connectivity. Note that I am using fping to check if ping was successful or not (install 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"

Now only have to make the xserver accessible from the new network namespace - this is only neccessary if you cannot already open programs from the new namespace.
In default namespace:

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

This exports the DISPLAY environmental variable, yours may be different, like :1 or :99. You can check in default namespace with

echo $DISPLAY

Now run some programs from new namespace

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

or if you want to do it at once:

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

If you want to continue using the bash opened in this new namespace you can add & to the end of the command to make it independent from this parent bash like so:

 /usr/bin/chromium-browser %U &

This way if you press CTRL+C the program will keep running, but you can get back your bash to run additional programs from it. Or you can just open multiple terminals.

Troubleshooting:
#enable forwarding

 sysctl -w net.ipv4.ip_forward=1

#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/

Additional sources:
Trying to run OpenVPN in Network Namespace
linux namespace, How to connect internet in network namespace?
Bind unix program to specific network interface
https://networkstatic.net/configuring-macvlan-ipvlan-linux-networking/

0

I don't think you need to bridge here. You just need to route.

I would remove the following (I'm assuming that enp0s3 is already 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

I would change:

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

to:

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

I would guess that this should allow your new network namespace to communicate with the local LAN 10.0.2.0/24 (e.g. ping the service provider router), but going out to the Internet may not work at this point. You would need to provide the output from commands like "ip route show", "ip route show table all", "ip rule show", "iptables-save", "cat /etc/resolv.conf" from the default namespace. And "cat /etc/resolv.conf" from the new network namespace bash session. Assuming there is no sensitive information in those outputs.

DericS
  • 711