Tips on Restricting Vserver Guest Network Access
These tips are being collected here because they seem scattered over the documentation. (Thanks to Bertl on #vserver for these tips).
Most of the discussion below is based on vserver version 2.2 with util-vserver version 0.30.212. Newer versions have easier ways to achieve the same goals.
Before doing anything else with Vserver Networking you should repeat the following mantras many times:
- Network routing policy is determined by the routing table on the host.
- The first interface defined in each guest is treated as the address of the loopback interface for the guest. (The Great Flower Page talks about the lback configuration; how does that work?)
- The guest can only establishing "listeners" on <IP address>:<port> combinations where <IP address> is an address that is "assigned" to the guest via an interface definition (or a call to naddress).
- All guest interfaces are also available to the host.
Strictly speaking this is an "interface-less" guest rather than a network-less one. This is a guest that cannot make network connections and cannot be reached from the network since it has no network interfaces.
On a kernel with newer (>= 2.3?) vserver patches it should be possible to create a guest with no interfaces by keeping the directory /etc/vservers/<guest-name>/interfaces/ empty.
However, this does not work with Debian etch (util-vserver 0.30.212 and vserver 2.2). Instead, you get a guest with all host interfaces available for outgoing network connections. At the same time the guest cannot bind a server to these interfaces so one cannot reach the guest from the network.
To disable outgoing use of network interfaces under a kernel with the older (<= 2.2?) vserver patches, you proceed as follows. You create an interface directory (say /etc/vservers/<guest-name>/interfaces/0/) with the nodev configuration. Be sure to define an ip as this is verified first in /usr/lib/util-vserver/vserver.functions; the value in ip can be any IP address that is not an IP address of the host. (For example, an address like 192.168.x.y or 10.x.y.z which is chosen at random will not be a host address with some luck.) This will result in a non-existent host interface being "assigned" to the guest and thus "no" interface will be available to the guest.
We now describe a configuration that leads to a guest that can (a priori) only connect to the host and can be reached via the network only from the host.
Define an interface using dummy0 as the value of dev and an ip value like 192.168.x.y or 10.x.y.z which is not an existing external-facing interface address for the host. (You may need to modprobe dummy in order to create such an interface.)
The guest can now connect to any service on the host that is listening for connections to <IP address>:80; where the IP address must be the one chosen above or the wildcard 0.0.0.0. For example, if the host is running a web server that listens to 0.0.0.0, then (in the guest) one can run the command
socat - TCP:192.168.x.y:80
to connect to this server; where as before 192.168.x.y is the chosen IP address. On the guest, this command is equivalent to the command
socat - TCP:127.0.0.1:80
Note that the address 127.0.0.1 on the guest is equivalent to the chosen IP address but not on the host.
Similarly, the guest can start servers that listen to 192.168.x.y:8888 or 0.0.0.0:8888 providing that there is no server that is already listening to this address (on the guest or on the host). The host can connect to such a server using the command
socat - TCP:192.168.x.y:80
Both the above type of connections, guest-to-host or host-to-guest happen over the loopback network interface.
Suppose you do not want the guest to access services on the host and vice versa. Then you use netfilter to limit connections over the loopback port. For example,
iptables -I INPUT -d ! 127.0.0.1 -i lo -j DROP
One can restrict specific services by more specific netfilter rules. For example, we can use
iptables -I INPUT -i lo -p tcp --dport 80 -j ACCEPT
to allow the guest to access the web server on the host and vice versa.
Warning: With this configuration the guest will "pollute" the network neighbourhood with packets whose source address is the given IP address. So it is best to use netfilter to prevent this with a configuration like
iptables -I OUTPUT -s 192.168.x.y -d ! lo -j DROP
To allow the guest as configured above to have access to the wider network beyond the host, you can replace the dummy0 interface with a real one and the private IP address with a "real" IP address --- assuming such a static adddress is available.
If your host has a dynamic external IP address and or interface, then one can instead use netfilter to translate the private address into a real one.
iptables -t nat -A POSTROUTING -o ! lo -j MASQUERADE
This allows the guest to access the internet without polluting the network neighbourhood with 192.168.x.y addresses.
Kapil Hari Paranjape 13:09, 17 September 2007 (CEST)