KVM default NAT-based networking

NAT-based networking is commonly provided and enabled as default by most major Linux® distributions that support KVM virtualization.

This network configuration uses a Linux bridge in combination with Network Address Translation (NAT) to enable a guest OS to get outbound connectivity regardless of the type of networking (wired, wireless, dial-up, and so on) used in the KVM host without requiring any specific administrator configuration.

Like other software bridge choices, NAT-based networking allows KVM guests sharing the same bridge to communicate together even if the bridge is not connected to an interface in the KVM host or if the KVM host has no physical networking installed or enabled.

While NAT is a convenient choice that is extremely flexible, allowing a guest OS to easily connect to the world outside of the KVM host, it has characteristics which can make it more or less desirable for many business and enterprise uses.

First, by default, the bridge used with NAT-based connectivity is typically configured to use private IP addresses from a 192.168.x.x subnet. Addresses in the private space are not allocated to any specific organization and anyone may use these addresses without approval from a regional Internet registry.1 Using a 192.168.x.x subnet allows a Linux distribution to avoid many of the configuration tasks and complexities regarding network resource reservation and administration, which is extremely convenient.

A second characteristic or restriction with using the KVM default NAT-based networking is that interfaces associated to the NAT are not, by default, visible outside of the KVM host running the NAT. This mean that external systems and their networking components have no knowledge of or way to route network traffic directly to a KVM guest OS on separate KVM host. This generally means a NAT would not be unusable for server workloads that rely on receiving unsolicited external network requests in order to do work.

A third characteristic, the use of Network Address Translation in addition to a software bridge, creates additional overhead which can affect network performance throughput and latency as well as potentially increases the consumption of CPU and memory resources. NAT behavior is normally implemented using a linux firewall that employs static and dynamic firewall rules. The use of the firewall puts additional demands on system.

For most Linux distributions, NAT-based networking is configured and available by default when the operating system is installed. Typically, the name for the default NAT bridge is virbr0 and the typical name for the default network is default.

To list which networks have been defined to the libvirt daemon for use by KVM guests, use the following command:
[root@kvmhost ~] # virsh net-list
Name    State  Autostart Persistent
----------------------------------------------------------
default active yes       yes

To use the default NAT bridge by a KVM guest, add or edit the network section of the libvirt XML configuration file for the KVM guest to include the name of the default bridge:

<interface type="bridge"> 
    <source bridge="bridge-name"/>
    <model type="virtio"/>
    <driver name="vhost"/>
</interface>

To define a new NAT bridge, complete the following steps.

  1. Create a new libvirt network configuration like the following:
    [root@kvmhost ~] # vi ~/new-kvm-network.xml
    <network>
        <name>newnatnetwork</name> 
        <forward mode='nat'> 
            <nat> 
                <port start='1024' end='65535'/> 
            </nat>
        </forward>
        <bridge name='my-bridge-name' stp='on' delay='0'/> 
        <ip address='192.168.X.1' netmask='255.255.255.0'> 
            <dhcp> 
                <range start='192.168.X.2' end='192.168.X.254'/> 
            </dhcp> 
        </ip>    
    </network>

    Change the <name>, <bridge name> and <ip address> to suite your needs. It is recommended that you choose names and ip address that are different from the default bridge to avoid conflicts. The typical ip address of the default network is 192.168.122.1.

    The network name defined in network XML <name> tag is reported in the Name field using the virsh net-list command.

  2. Add the new network definition XML file to libvirt:
    [root@kvmhost ~] # virsh net-create ~/net-nat-network.xml

    Once added to libvirt, the new network definition will persist.

  3. To set the new network to automatically startup each time the KVM host is rebooted, do this:
    [root@kvmhost ~] # virsh net-autostart <network-name-from-xml>

    Specify the network by the <name> defined in the XML file.

  4. Add or change the KVM guest's configuration to use this network or bridge name.
    To view configuration details of a specific network defined in libvirt, use the following command:
    [root@kvmhost ~] # virsh net-dumpxml<libvirt-network-name>