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.