KVM On Ubuntu - KVM Logo

Simpler KVM Network Configuration

In the series of articles I wrote discussing the installation of KVM on Ubuntu I spent articles 2 and 3 discussing the network set up but it occurred to me that it was actually an unnecessarily difficult set up and so in this article I’ll discuss a simpler KVM network configuration set up.

In the original articles my aim was to have the virtual machines on the same subnet as the rest of the network. At the time this seemed like a good idea as it would allow for a very simple routing configuration but as time went on I realized I was making the configuration on the server complicated for the want of a one line entry in my main switches routing table. The solution I describe here is a routed network. What that means is the virtual machines live on a completely separate subnet to the rest of the network and the host machine takes the responsibility of routing packets to the virtual machines. In the original articles I also destroyed the default network but in reality I could just have reused it so that’s what I’ll do this time.

Simpler KVM Network Configuration – Network Definition

Start a virsh session and edit your default network configuration:

virsh
net-edit default

Modify it so that it looks something like this:

<network>
    <name>default</name>
    <uuid>7402c7e0-9b4d-4e0f-8913-6198ecdc3acb</uuid>
    <forward dev='p2p1' mode='route'>
        <interface dev='p2p1'/>
    </forward>
    <bridge name='virbr0' stp='on' delay='0'/>
    <mac address='52:54:00:6e:8e:30'/>
    <ip address='192.168.10.1' netmask='255.255.255.0'>
        <dhcp>
            <range start='192.168.10.2' end='192.168.10.254'/>
        </dhcp>
    </ip>
</network>

The key change is to the forward configuration which should be changed to “route”. Your device may be called “eth0” or something similar, the names of devices all changed recently. The IP address block defines the address of the virtual bridge and the range of the network and any DHCP setting you might want.

Simpler KVM Network Configuration – Firewall

I typically just reboot at this point to apply the changes (so that I can see everything comes up cleanly) but you can just restart libvirt if you want. When libvirt restarts it will attempt to add some required rules to the firewall:

-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A FORWARD -d 192.168.10.0/24 -i p2p1 -o virbr0 -j ACCEPT
-A FORWARD -s 192.168.10.0/24 -i virbr0 -o p2p1 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT

If you don’t have a standard default set up (e.g. you are managing the firewall with Webmin) then you’ll need to add these rules to your firewall manually.

Other than that all you need to do is add a routing entry to your switch to tell it to route all packets to 192.168.10.0 to whatever address you server is on (e.g. 192.168.5.5). Now you have a simpler KVM network configuration that should be easier to manage.

Simpler KVM Network Configuration – Checking

You can check that everything is configured correctly by running the command “ip -a” which should give you output that looks like this:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 inet 127.0.0.1/8 scope host lo
 valid_lft forever preferred_lft forever
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: p2p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
 link/ether 00:01:2e:33:fe:14 brd ff:ff:ff:ff:ff:ff
 inet 192.168.5.5/24 brd 192.168.1.255 scope global p2p1
 valid_lft forever preferred_lft forever
 inet6 fe80::201:2eff:fe33:fe14/64 scope link
 valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
 link/ether 74:f0:6d:6f:f2:e7 brd ff:ff:ff:ff:ff:ff
4: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
 link/ether 52:54:00:6e:8e:30 brd ff:ff:ff:ff:ff:ff
 inet 192.168.10.1/24 brd 10.1.0.255 scope global virbr0
 valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 500
 link/ether 52:54:00:6e:8e:30 brd ff:ff:ff:ff:ff:ff
11: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UNKNOWN group default qlen 500
 link/ether fe:54:00:c3:9f:ff brd ff:ff:ff:ff:ff:ff
 inet6 fe80::fc54:ff:fec3:9fff/64 scope link
 valid_lft forever preferred_lft forever

The last entry “vnet0” is for a virtual machine I’ve already deployed to this host so you won’t see that.

Note 1: The interface “virbr0” will indicate it’s state as DOWN until you add a virtual machine.

Note 2: This set up only works if your network interface can handle routing which most wireless interfaces can’t. This shouldn’t be much of a problem for a server but it proved to be an irritating inconvenience for my laptop set up.