NAT-based network¶
A NAT-based network is ideal if virtual machines (VMs) only need outbound IPv4 network access. The libvirt server acts as a router, and VM traffic appears to originate from the IPv4 address of the server.
Limitations¶
The default virtual network is NAT-based (with a fragile hook system to forward incoming connections). Unfortunately, it automatically inserts iptables rules whether you want them or not — in an order that is difficult to control — unless you disable the default network completely.
If you would rather be in full control and prevent libvirt from interfering, create a Custom NAT-based network instead.
Configure the default network¶
The default NAT-based network should already be available after installing libvirt.
# virsh net-info default
Name: default
UUID: f63c210f-67e7-4aed-8d21-066d9fd6c7d6
Active: no
Persistent: yes
Autostart: no
Bridge: virbr0
# virsh net-autostart default
# virsh net-start default
If the default network is missing, create /tmp/default.xml
with the
following contents. (Optionally, use DHCP host entries to always
assign the same IP address to a particular VM.)
<network>
<name>default</name>
<bridge name="virbr0"/>
<forward mode="nat"/>
<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>
Use /tmp/default.xml
to create the default network.
# virsh net-define /tmp/default.xml
# virsh net-start default
# virsh net-autostart default
Multiple virtual networks¶
You can create as many NAT-based networks as required. Simply choose a different
name for the network (eg, default2
), a different name for the virtual bridge
(eg, virbr2
), and a different range of IP addresses. Also see
Multiple networks.
Forward incoming connections¶
Note
This step is optional. It is only necessary if one or more VMs are running services (eg, web applications) that need to be available over the network.
If one of the VMs has a web application listening on ports 80
/443
,
connections to those ports on the server can be forwarded to the VM using a
fragile hook system.
The main limitation is that a specific port on the server can only be forwarded
to a single VM. This is problematic if many VMs are fighting over ports
80
/443
. One option is to forward connections to ports 80
/443
on
the server to a VM running a reverse proxy (eg, NGINX or HAProxy), which can
then proxy those connections to other VMs. Alternatively, run a reverse proxy on
the libvirt server itself.
If you want more control over your firewall than the hook system can provide, create a Custom NAT-based network.
Configure IPv6¶
Note
This step is optional.
NAT makes little sense for IPv6, so create a Routed network instead. A routed network can be run alongside a NAT-based network if both are needed.
If preferred, you can avoid creating a separate routed network and allow VMs on a NAT-based network to bind to IPv6 addresses. However, no NAT is performed for IPv6 traffic so you still have to configure static routes (see Routed network). Open the XML configuration for the default network in a text editor.
# virsh net-edit default
Replace the configuration with the following content. Addresses are allocated via stateless address autoconfiguration (SLAAC).
<network>
<name>default</name>
<bridge name="virbr0"/>
<forward mode="nat"/>
<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>
<ip family="ipv6" address="2001:db8::1" prefix="64"/>
</network>
Alternatively, you may want to allocate addresses via DHCPv6 instead of SLAAC.
Add a <dhcp>
element with a range of addresses to offer to VMs. (Optionally,
use DHCP host entries to always assign the same IP address to a
particular VM.)
<network>
<name>default</name>
<bridge name="virbr0"/>
<forward mode="nat"/>
<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>
<ip family="ipv6" address="2001:db8::1" prefix="64">
<dhcp>
<range start="2001:db8::1000" end="2001:db8::1fff"/>
</dhcp>
</ip>
</network>
Configure virtual machines¶
New VM¶
# virt-install --network network=default ...
Optionally, pass --network
more than once to create additional virtual Ethernet
interfaces for the VM.
# virt-install --network network=default --network network=default2 ...
Existing VM¶
Open the XML configuration for the VM in a text editor.
# virsh edit name-of-vm
To configure a virtual Ethernet interface for the VM, add an <interface>
section. If required, you can add multiple <interface>
sections.
<interface type="network">
<source network="default"/>
</interface>
Reboot the VM to apply the changes. You may need to amend the VM’s network initialization scripts to account for the network interface changes.