I have a Linux box with N tunnel interfaces, tun0
, tun1
, and so on.
I want to set things up so that a particular group of processes, A, has its default (and only) route pointed at tun0
. Meanwhile, a second group of processes, B, has its default (and only) route pointed at tun1
, and so on. A, B, and so on are not necessarily "process groups" in the POSIX sense; ideally, the configuration would be established in advance, after which, any process could declare itself a member of A or B or ... at startup. (It is okay if only processes running as root
can do that.)
It is a bug if any of these groups of processes ever sends traffic out the wrong tunnel interface, or out the real network interface eth0
. It is also a bug if unrelated processes on the same host ever send traffic out any of the tunnel interfaces; they should continue to use eth0
directly.
I have the impression that this can be done with "network namespaces" but I have been unable to figure out how; I am asking for step-by-step instructions.
This can indeed be done with network namespaces. Assume that you have all of the following information (which is either assigned by the process at the other end of the tunnel device, or by your controller program):
$namespace
a label for the network namespace$device
the tunnel device to be assigned to the namespace$mtu
the MTU for the tunnel device$address
the IP address to assign to the tunnel device$netmask
the netmask to assign to the tunnel device$broadcast
the broadcast address to assign to the tunnel device$gateway
the default gateway to use inside the namespace$dns_servers
a list of DNS servers to use inside the namespaceThen the following pseudo-shell-script will set up the namespace:
And to tear it down again, you do
And to run a program inside the namespace, just use
ip netns exec
.An actual working implementation of this mechanism for OpenVPN tunnels may be found here; unfortunately, because for what I need it for it has to be setuid, the above turns into 1200 lines of C.