# Using network namespaces

## friesia

Are there any userspace tools to utilize network namespaces for something like the following configuration?

Let's say I wish Chromium to only see 'lo' and 'tun0' (operated by OpenVPN) interfaces while for all other processes all of them are visible? (or maybe all except tun0)

----------

## Hu

Recent versions of sys-apps/iproute2 can be used to manage network namespaces.  I think you could move tun0 into the private namespace with Chromium, but sharing it between the namespaces is harder.

----------

## friesia

Ok, I'll look into it.

But I guess this way Chromium will see eth0 as well (which is dual stack). And tun0 is IPv4-only. I don't want it to use IPv6 while VPN is active.

----------

## Hu

Chromium will not see network devices from the original network namespace.  It will see only the devices in the namespace in which it runs, which is the point of a namespace.  Chromium will not be automatically restricted to IPv4, but it will only have access to lo and to tun0, so you will be fine as long as the upstream nameserver for the namespace does not serve AAAA records.

----------

## friesia

I will share how I solved this (without openvpn launch part).

I prepared 2 simple shell scripts ns_start and ns_inside placed in /usr/local/bin.

The user launches the former one (in root shell). It prepares the namespace, executes another script called ns_inside in it and then launches another bash shell inside namespace.

You should have bridged interface br0 already configured with your primary network interface linked to it (eth0).

ns_start:

```

#!/bin/bash

# This tool prepares a proper network namespace

ip netns add vpn

ip link add type veth

ip link set veth0 netns vpn

brctl addif br0 veth1

ifconfig veth1 up

ip netns exec vpn /usr/local/bin/ns_inside

ip netns exec vpn bash

```

ns_inside:

```

#!/bin/bash

# This tool sets up environment inside a namespace

ifconfig lo up

ifconfig veth0 up

ip add add 192.168.1.100/24 dev veth0

ip route add default via 192.168.1.1

```

Also, some kernel configuration is needed:

CONFIG_NET_NS

CONFIG_VETH

CONFIG_TUN

----------

## friesia

Actually I get some undesirable behaviour with this.

Initially br0's MAC address reflects eth0's MAC. But when I add veth1 to that bridge, br0's MAC changes to veth1's MAC.

I can work it around by changing the MAC back manually with "ifconfig br0 down hw ether xx:xx:xx:xx:xx:xx up" (and that way all previously configured IPv4 and IPv6 global addresses on br0 disappear and have to be set again as well).

Maybe there's a better way to forbid MAC change on the bridge? (I think there might be variables for this purpose in /proc)

----------

## Hu

Why are you bridging the inner namespace into your main network?  I thought you wanted a namespace which was just the VPN connection.

----------

## friesia

The end result looks like this.

Main namespace:

* br0. Includes lan0 and and veth 1. This is the default route. IP address 192.168.1.2.

* lan0. My main internet connection.

* lan1. My connection into another local network.

* lo.

* veth1. Virtual card peered with veth0.

VPN namespace:

* lo

* tun0. This is the default route here. Packets meant for outer networks are encapsulated into veth0.

* veth0. Virtual card peered with veth1. IP address 192.168.1.100

So data received on lan0 for IP address 192.168.1.100 is forwarded to veth1 because the bridge exists. veth1 is peered with veth0, so it gets into VPN namespace.

Data for IP address 192.168.1.2 is processed by the main namespace.

----------

## Hu

Yes, I understand how you configured it, but not why you chose to do it that way.  Your opening post specified you wanted the inner namespace to contain only lo and tun0, but that is not what you have done.

----------

## friesia

OpenVPN can't work with tun0 in one namespace and 'normal' ethernet network interface in another because openvpn process intself belongs to only 1 namespace.

What matters for me here is the default route only.

----------

## Hu

OpenVPN detects and rejects the scenario that you start OpenVPN, let it create its tun device, and then you move that tun device into the inner namespace?

----------

## friesia

No, I think it doesn't detect this (at least nothing appears in journal).

In this case the link stops working. In the other namespace tun0 appears unconfigured and down. The routing table there is empty, too.

Even if I try to configure it manually, there is no way to add route like:

/bin/ip route add <endpoint-ip>/32 via 192.168.1.1

(which openvpn adds at start)

since 192.168.1.1 has to be reached via local interface.

----------

## Hu

Moving tun0 from the outer namespace to the inner one causes it to change state?  That seems odd.  The lack of a route in the inner namespace is expected.  You need to add a default route there.  No route additions should be needed in the external namespace, since the command you showed is just to avoid OpenVPN trying to route the VPN packets back over the VPN, which would result in a routing loop.  You mention 192.168.1.1, but your most recent post is the first mention of that address I have seen.  What device has that address?

----------

## friesia

192.168.1.1 is my gateway, initially configured with DHCP.

Looks like re-configuring tun0 and adding default route was enough to restore connectivity.

What I did:

```
openvpn --config /etc/openvpn/myvpn.conf --daemon

ip netns add vpn

ip link set tun0 netns vpn

ip netns exec vpn bash

ip addr add dev tun0 local 10.0.15.209 peer 10.0.15.210

ifconfig tun0 up

ip route add default via 10.0.15.210
```

As for why ip command or kernel unconfigures tun0 and sets it to down, I couldn't find anything.

----------

