Project

General

Profile

Running strongSwan in Network Namespaces on Linux » History » Version 2

Tobias Brunner, 10.06.2015 18:03

1 1 Tobias Brunner
h1. Running strongSwan in Network Namespaces on Linux
2 1 Tobias Brunner
3 1 Tobias Brunner
Normally, the network stack (interfaces, routing tables, firewall rules etc.) is shared by all processes running on an operating system. With Linux network namespaces (netns) it's possible to have multiple separate instances of the network stack.
4 1 Tobias Brunner
5 1 Tobias Brunner
> *Note:* While basic support for network namespaces was added to the Linux kernel a long time ago some features (e.g. CLUSTERIP support) might require a recent kernel.
6 1 Tobias Brunner
7 1 Tobias Brunner
The easiest way to work with network namespaces is to use the @ip@ command of the _iproute2_ package. These commands will have to be executed as root (i.e. with @sudo@ on most distros).
8 1 Tobias Brunner
9 1 Tobias Brunner
h2. Network Namespace Basics
10 1 Tobias Brunner
11 1 Tobias Brunner
To create a new netns use the following command:
12 1 Tobias Brunner
13 1 Tobias Brunner
<pre>
14 1 Tobias Brunner
# ip netns add <network namespace name>
15 1 Tobias Brunner
</pre>
16 1 Tobias Brunner
17 1 Tobias Brunner
A list of all currently defined netns is provided by @ip netns list@.
18 1 Tobias Brunner
19 1 Tobias Brunner
Interfaces can be assigned to a netns with the @ip link@ command:
20 1 Tobias Brunner
21 1 Tobias Brunner
<pre>
22 1 Tobias Brunner
# ip link set <interface name> netns <netns name>
23 1 Tobias Brunner
</pre>
24 1 Tobias Brunner
25 1 Tobias Brunner
If you run @ip link list@ afterwards such an interface won't be seen as it is only available in the configured netns.
26 1 Tobias Brunner
27 1 Tobias Brunner
So to actually list the interface in a specific netns it's required to be able to run commands in a specific netns. This can be done with the @ip netns exec@ command. So to get a list of interfaces defined in a specific netns use:
28 1 Tobias Brunner
29 1 Tobias Brunner
<pre>
30 1 Tobias Brunner
# ip netns exec <netns name> ip link list
31 1 Tobias Brunner
</pre>
32 1 Tobias Brunner
33 1 Tobias Brunner
If only one physical interface is available, or if you don't want to assign physical interfaces to the netns for other reasons, it's possible to create virtual Ethernet interface pairs (veth, provided via @CONFIG_VETH@). These are like a bi-directional pipe (i.e. what's written to one end comes out the other and vice-versa) of which one end is placed inside the netns and the other stays outside in the "default" or "global" namespace.
34 1 Tobias Brunner
35 1 Tobias Brunner
To create such a pair use:
36 1 Tobias Brunner
37 1 Tobias Brunner
<pre>
38 2 Tobias Brunner
# ip link add <interface name 1> type veth peer name <interface name 2>
39 1 Tobias Brunner
</pre>
40 1 Tobias Brunner
41 1 Tobias Brunner
This creates two connected Enthernet interfaces with the given names. One is assigned to a netns (via @ip link@) the other is not (it doesn't matter which one and it's also possible to assign both interfaces to two different netns to connect them).  How the outer interface is used depends on the use case, it may be put inside a bridge, or used in routing rules to route traffic to and from a netns.
42 1 Tobias Brunner
43 1 Tobias Brunner
Since interfaces assigned to a netns are disabled they have to be enabled first, and they will probably also require an IP address, which can be done with:
44 1 Tobias Brunner
45 1 Tobias Brunner
<pre>
46 2 Tobias Brunner
# ip netns exec <netns name> ip addr add x.x.x.x/x dev <iface name>
47 2 Tobias Brunner
# ip netns exec <netns name> ip link set dev <iface name> up
48 1 Tobias Brunner
</pre>
49 1 Tobias Brunner
50 1 Tobias Brunner
Similar to these commands routes or firewall rules may be added by running @ip route@ or @iptables@ inside a specific netns via @ip netns exec <command>@.
51 1 Tobias Brunner
52 1 Tobias Brunner
h2. Running strongSwan Inside a Network Namespace
53 1 Tobias Brunner
54 1 Tobias Brunner
Running a single instance of strongSwan inside a netns is straight-forward. Simply run [[ipseccommand|ipsec]] commands via @ip netns exec ipsec <command>@.
55 1 Tobias Brunner
56 1 Tobias Brunner
But more interesting is probably running multiple instances of strongSwan in separate namespaces. Because all netns share the same file system this is a bit tricky.
57 1 Tobias Brunner
58 1 Tobias Brunner
Luckily, the @ip netns exec@ command provides a helpful feature: Every file found in @/etc/netns/<name>/@ for a given netns is bind mounted over its corresponding counterpart in @/etc@ (so it has to exist there).  This can be used to provide different config files for each instance, but may also be used to redirect the so called _piddir_, where the charon and starter daemons create their PID files and UNIX sockets (the default is to use @/var/run@, which would conflict if multiple instances would use it).
59 1 Tobias Brunner
60 1 Tobias Brunner
To do so make sure strongSwan is [[AutoConf|configured]] with @--sysconfdir=/etc@ and e.g. @--with-piddir=/etc/ipsec.d/run@. Then after [[InstallationDocumentation#Building-strongSwan|building and installing strongSwan]] the piddirs can be created as follows:
61 1 Tobias Brunner
62 1 Tobias Brunner
<pre>
63 2 Tobias Brunner
# mkdir -p /etc/ipsec.d/run
64 2 Tobias Brunner
# mkdir -p /etc/netns/<netns name 1>/ipsec.d/run
65 2 Tobias Brunner
# mkdir -p /etc/netns/<netns name 2>/ipsec.d/run
66 1 Tobias Brunner
</pre>
67 1 Tobias Brunner
68 1 Tobias Brunner
For config files that differ between netns a modified copy of the original may be placed in @/etc/netns/<name>/@ or a subdirectory.