Configure Public Bridge Guest Networking in KVM on Debian Jessie

Bridged networking allows KVM guests to connect to the outside network through the physical interface, making them appear as normal hosts to the rest of the network. 

Be advised that network bridging will not work when the physical network device (e.g., eth1, wlan0) used for bridging is a wireless device as most wireless device drivers do not support bridging.

Before We Begin

We have KVM up and running. Check this post for more info.

KVM Default Virtual Network

Every standard libvirt installation provides NAT based connectivity to virtual machines out of the box. This is the so called “default virtual network”. We can verify that it is available with:

# virsh net-list --all
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              inactive   no            yes

When the libvirt default network is running, you will see an isolated bridge device. This device explicitly doesn’t have any physical interfaces added, since it uses NAT with forwarding to connect to outside world.

What we want to have is a public bridge, so that we can assign IP addresses to our virtual machines and make them accessible from our local network.

KVM Public Bridge

Install bridge-utils package:

# apt-get install bridge-utils

Open /etc/network/interfaces and put the following configuration:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet dhcp
  bridge_ports eth0
  bridge_stp off
  bridge_maxwait 5

We have our DHCP server configured to issue a static DHCP lease based on a MAC address. In this case the IP address that should be given is 10.10.1.80/24.

Restart networking:

# systemctl restart networking

Verify the IP address has been issued:

# ip ad
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether 00:30:48:f1:4c:c2 brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 00:30:48:91:3f:0a brd ff:ff:ff:ff:ff:ff
    inet 10.10.1.80/24 brd 10.10.1.255 scope global br0
       valid_lft forever preferred_lft forever

Guest Configuration

Once the KVM host configuration is complete, a guest can be connected to the virtual network based on the network name.

Start the libvirtd service if it’s not already running:

# systemctl start libvirtd

Let us see what guests are installed:

# virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     centos1                        shut off
 -     rhel1                          shut off

We are going to configure the centos1 guest to use the bridge network.

# virsh edit centos1

We should find similar lines:

<interface type='user'>
  <mac address='52:54:00:e7:6c:71'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

User networking connects to the LAN using SLIRP. This provides a very limited form of NAT. User networking does not support a number of networking features like ICMP. Certain applications (like ping) may not function properly. However, the guest operating system will have access to network services, but will not be visible to other machines on the network.

Add the following snippet to the config file replacing the lines above:

<interface type='bridge'>
  <mac address='52:54:00:e7:6c:71'/>
  <source bridge='br0'/>
</interface>

Note that the MAC address is optional and will be automatically generated if omitted.

Start the guest:

# virsh start centos1
Domain centos1 started

Connect to the guest console, and check network configuration. If it’s bridged, it should receive an IP address from our DHCP pool 10.10.1.0/24. NAT pool is 10.0.2.15/24.

# virsh console centos1
Connected to domain centos1
Escape character is ^]


CentOS Linux 7 (Core)
Kernel 3.10.0-327.el7.x86_64 on an x86_64

localhost login: root
Password: **********
Last login: Tue Aug  9 19:31:55 on hvc0
[[email protected] ~]# ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:e7:6c:71 brd ff:ff:ff:ff:ff:ff
    inet 10.10.1.81/24 brd 10.10.1.255 scope global dynamic ens3
       valid_lft 86390sec preferred_lft 86390sec
    inet6 fe80::5054:ff:fee7:6c71/64 scope link 
       valid_lft forever preferred_lft forever

[[email protected] ~]# host www.google.com
www.google.com has address 216.58.214.4
www.google.com has IPv6 address 2a00:1450:4009:801::2004
[[email protected] ~]# exit

It looks like network is OK on the guest.

Leave a Reply

Your email address will not be published. Required fields are marked *