Libvirt Sandbox: Network configuration

The guests created by Libvirt Sandbox do not have any network connectivity available by default. This ensures the environment is strictly locked down from attackers either inside or outside the guest. To provide networking access to a sandbox, it must be connected to a libvirt virtual network. This page describes some common ways to configure libvirt virtual networks to provide varying types of connectivity.

Sandbox configuration

The virt-sandbox and virt-sandbox-service commands share a common syntax for configuring network connectivity.

  -N NETWORK-OPTIONS, --network NETWORK-OPTIONS

Each time the arg is repeated, it causes a new network interface to be added to the sandbox. NETWORK-OPTIONS is a set of key=val pairs,
separated by commas. The following options are valid

dhcp
Configure the network interface using dhcp. This key takes no value.
source=NETWORK
Set the name of the network to connect the interface to. “NETWORK” is the name of any libvirt virtual network. (The virsh -c URI net-list command will list any networks which exist)
address=IP-ADDRESS/PREFIX%BROADCAST
Configure the network interface with the static IPv4 or IPv6 address IP-ADDRESS. The PREFIX value is the length of the
network prefix in IP-ADDRESS. The optional BROADCAST parameter specifies the broadcast address. Some examples

address=192.168.122.1/24
address=192.168.122.1/24%192.168.122.255
address=2001:212::204:2/64
route=IP-NETWORK/PREFIX%GATEWAY
Configure the network interface with the static IPv4 or IPv6 route IP-NETWORK. The PREFIX value is the length of the
network prefix in IP-NETWORK. The optional GATEWAY parameter specifies the address of the gateway. An example:

route=192.168.122.255/24%192.168.1.1

Host configuration

As mentioned above, configuring the virtual network on the host is outside the scope of the libvirt sandbox project. This is something to be done using the standard libvirt tools like virsh, or virt-manger if a graphical interface is desired. There are essentially two logical choices for network connectivity, NAT forwarding, or bridging. With bridging there are a number of possible ways to configure the host, Linux Bridges, or Macvtap in one of three or four different modes. Each of the different bridging methods have their own plus/minus points which admins will decide between.

NAT connectivity

Providing NAT connectivity is the simplest possible option. The main downside of NAT is that it only allows for outbound network access. If the sandbox is intended for running network servers that must be exposed to the LAN / WAN, then NAT cannot be used. The main plus point of NAT is that it is easy to configure and works well with hosts that have dynamically changing network connectivity such as laptops which switch between ethernet, wifi and mobile connectivity.

Traditionally, with most libvirt deployments, there will already be a NAT based virtual network defined, with the name default. In Fedora 18 or later, the default configuration has been made optional, so if it is desired, make sure that the libvirt-daemon-config-network RPM is present. If it is not present, it is very easy to create it with the following steps

# cat > default.xml <<EOF
<network>
  <name>default</name>
  <bridge name="virbr0" />
  <forward/>
  <ip address="192.168.122.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.122.2" end="192.168.122.254" />
    </dhcp>
  </ip>
</network>
EOF
# virsh -c lxc:/// net-define default
# virsh -c lxc:/// net-start default
# virsh -c lxc:/// net-autostart default

These steps load the config into libvirt, then start the network and finally mark it to automatically start after host reboots. Libvirt takes care of creating the bridge device and running a DNS and DHCP server for it. The IP address range can of course be customized to suit, as can the bridge device name, though using virbrNN is a common convention. The libvirt documentation shows how to customize this further to enable IPv6 support, static hostnames and more.

With this network defined and running, sandboxes can be connected to it using the following command line arg

--network dhcp,source=default

The Libvirt Sandbox tools will automatically start a DHCP client inside the sandbox to acquire an address and configure routing, etc.

Bridge connectivity with Linux Bridges

Ethernet bridging provides a much more useful level of connectivity to sandboxes, allowing them to accept incoming network connections. This is only really suitable for servers or machines which have permanent, wired LAN connectivity. The actual steps required to configure a Linux Bridge will vary depending on what Linux distro is installed on the host. The Libvirt Wiki has documentation showing how to configure a bridge on Fedora, RHEL, Debian & Ubuntu.

Once the host OS networking is configured to have a bridge device, Libvirt needs to be told it can use this bridge for a virtual network. Similarly to the NAT config, this requires creating a XML file and then loading it into libvirt. Assuming the bridge device is named br0, the following will work

# cat > default.xml <<EOF
<network>
  <name>lan</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>
EOF
# virsh -c lxc:/// net-define lan
# virsh -c lxc:/// net-start lan
# virsh -c lxc:/// net-autostart lan

Notice that when telling libvirt about a host bridge, there is no need to define any IP address information. That is because it is assumed that the physical LAN admin has already got DHCP/DNS/etc services configured.

With this network defined and running, sandboxes can be connected to it using the following command line arg

--network dhcp,source=lan

The Libvirt Sandbox tools will automatically start a DHCP client inside the sandbox to acquire an address and configure routing, etc.

Bridge connectivity with MacVTap

One of the pain points when using Linux Bridging is the need to reconfigure the host network interfaces to make the wired NIC a slave of the bridge. The MacVTap functionality provides a way to configure bridging without requiring any changes to the existing host networking config. The downside of using MacVTap instead of a Linux Bridge is that it doesn’t allow for connectivity between the host and guest OS. Only between the guest OS and other non-local machines.

Since it does not require any host networking changes, using MacVTap simply involves telling Libvirt about a physical device to use. Similarly to the NAT config, this requires creating a XML file and then loading it into libvirt. Assuming the wired NIC device is named eth0, the following will work

# cat > default.xml <<EOF
<network>
  <name>lan</name>
  <forward mode="bridge">
    <interface dev="eth0"/>
  </forward>
</network>
EOF
# virsh -c lxc:/// net-define lan
# virsh -c lxc:/// net-start lan
# virsh -c lxc:/// net-autostart lan

Notice that when telling libvirt about a macvtap bridge, there is no need to define any IP address information. That is because it is assumed that the physical LAN admin has already got DHCP/DNS/etc services configured.

With this network defined and running, sandboxes can be connected to it using the following command line arg

--network dhcp,source=lan

The Libvirt Sandbox tools will automatically start a DHCP client inside the sandbox to acquire an address and configure routing, etc.

With the MacVTap bridging mode, it is possible to list multiple <interface dev=”eth0″/> elements, each with a different NIC. Libvirt will assign each guest a different physical interface to use, picking the interface with least number of existing guests. This is useful when the host has multiple physical NICs connected to the same LAN, since each guest can get a dedicated NIC with its own I/O queue and bandwith.