
A deep dive into Linux namespaces, part 4 - iffyio
http://ifeanyi.co/posts/linux-namespaces-part-4/
======
OJFord
I first learnt of network namespaces from configuring WireGuard. They offer a
very neat way of ensuring all traffic uses your wg interface, in brief:

\- create a new netns, call it 'physical' say

\- move your physical device's interface to 'physical'

\- create wg interface in 'physical'

\- move wg interface to init ns

It works because it 'remembers' where it was created and remains bound to it
for sending encrypted packets over the physical device, but is now the only
interface available to processes by default (i.e. without a superuser making
them use 'physical' ns directly).

Not long enough; want to read more:
[https://www.wireguard.com/netns](https://www.wireguard.com/netns)

------
sophacles
These are really good posts - I've been mucking about with namespaces recently
at work and I wish I had known about this series before today, I wouldn't have
had to go figure out a bunch of stuff the hard way!

I hope some future part covers the nsfs and bind mount thing for persisting
namespaces past a specific process. It took me way, way to long to catch this
passage in the man page:

    
    
        Bind mounting (see mount(2)) one of the files in this directory to somewhere else in the filesystem keeps the corresponding namespace of the process specified by pid alive even if all processes currently in the namespace terminate.
    

It's not that it's hard to understand, it's just poorly highlighted in most
namespace discourse that I've seen. Persisting namespaces was very much a
mystery to me - I had to break down and read the source to understand how the
ip command persisted network namespaces before I understood the importance of
that sentence.

~~~
mav3rick
LWN has a very good series on namespaces and cgroups.

~~~
sophacles
Oh, good pointer - thanks!

------
finchisko
Wondering, if it's possible to build "application firewall" on top of
namespaces. Only thing I'm missing on Linux.

~~~
chousuke
IPtables/netfilter can already filter traffic by process. I don't think you
need namespaces.

------
markandrewj
If you are interested in network namespaces, you might want to take a look at
VRF in Cumulus Linux.

------
foresto
Recent pet project: I wanted multiple network clients to access the internet
concurrently, each through its own separate VPN session, established on demand
and without elevated privileges.

The first part seemed like a simple enough idea until I remembered that
traditional IP routing is based on destination address alone. Although I could
establish multiple VPN sessions, give each one its own network interface, and
configure each client to bind to a different interface (and therefore send
packets with a different source address), the routing table had no way to know
that it should send CLIENT_A's packets to the server via IFACE_A and
CLIENT_B's packets to the same server via IFACE_B.

Policy-based routing looked like a promising solution, but it would require
hooking the VPN startup sequence to find each new tunnel interface as it was
created, using elevated privileges to install a special routing policy for
each interface, and reliably cleaning up the routing tables when each client
was done. This seemed overly complicated, and a poor fit for unprivileged
users.

Linux namespaces, along with tools that are already in the debian/ubuntu
repos, let me do everything I wanted. I ended up writing a couple shell
scripts that create N namespaces, give each one a veth connected to a shared
bridge device with internet access, establish a namespaced VPN session via
each veth, and let the VPN take control of its namespace's default route.

That by itself would have been enough, since any network client running within
a namespace is at the mercy of that namespace's routing table, and therefore
goes through its own VPN session. I went a couple steps further, though: I
added firewall rules within each namespace, to prevent any leaks if the VPN
failed or a routing mistake crept in. I also decided to launch a lightweight
proxy server in each namespace instead of running my network clients directly
within, allowing me to conveniently start and stop my network clients outside
of the namespaces and independently of the namespace setup/teardown process.

With the addition of user namespaces, the steps that would normally require
root can be run as a fake uid 0 by an unprivileged user. With the help of lxc-
user-nic, the one privileged operation that must be run outside the namespaces
(adding each veth to the bridge) can be done by an unprivileged user as well.
With the help of dumb-init (or tini), stopping the parent process of any
namespace automatically cleans up everything within, including the routing
table, firewall rules, veth, VPN, and proxy.

This arrangement solved all the problems I set out to solve, and the exercise
was a good way to get familiar with namespaces. I might some day convert my
hackish shell script implementation to python, perhaps with a little GUI, and
see if I can combine it with Firefox containers. Per-container or per-tab VPN
sessions in a web browser would be neat.

Related: [https://github.com/mozilla/multi-account-
containers/issues/3...](https://github.com/mozilla/multi-account-
containers/issues/313)

