Creating a bridge for virtualizing with KVM
This post applies to Ubuntu given that it uses the netplan paradigm.
Reason
There are multiple ways to allow a KVM VM to have access to the external network, but usually, people implement either a NAT or a bridge method. I went for the latter because it felt more “natural”: my host serves as a gateway (bridge) to the rest of the network, each VM will have their own IP…
Installation
I suppose that you have installed everything you need for the virtualization part, so I jump directly to the bridging part:
1user $ sudo apt install bridge-utils
Configuring netplan
My host has 4 network interfaces, but I’m only using the first one, the others are not wired.
Now, let’s configure our netplan configuration file:
1network:
2 ethernets:
3 eno1:
4 dhcp4: false
5 dhcp6: false
6 eno2:
7 dhcp4: true
8 eno3:
9 dhcp4: true
10 eno4:
11 dhcp4: true
12 version: 2
13
14 bridges:
15 br0:
16 addresses: [ 10.0.20.2/24 ]
17 gateway4 : 10.0.20.1
18 mtu: 1500
19 nameservers:
20 addresses:
21 - 1.1.1.1
22 - 8.8.8.8
23 parameters:
24 stp: true
25 forward-delay: 4
26 dhcp4: false
27 dhcp6: false
28 interfaces:
29 - eno1
So basically, we won’t provide eno1 an IP address, but directly give it to br0 then tell br0 to use eno1 as its interface.
The reason why the br0 addresses is a /24 is to allow all those addresses to be routed over that interface.
Bridging consideration and tuning
By default, all packets going through the bridge are then passed to the iptables / netfilter modules. This may cause issues where packets are blocked by your local rules. What you probably want, it’s to avoid this and send packets directly to the physical network, then let an external firewall to manage the rules. Also, by setting these settings to “no” will improve network (and CPU) performances given that no filter processing will take place. You can read more about this here.
So let’s disable those settings by creating (or apending if it already exists) a file /etc/sysctl.d/bridge.conf and fill it with:
net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0
Now, let’s create a udev rule to apply these everytime the netfilter module is loaded in the kernel.
Create a file called /etc/udev/rules.d/99-bridge.rules and add this line:
ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"
You may apply those settings immediatly by running the /sbin/sysctl -p /etc/sysctl.d/bridge.conf above command or restart, up to you.
Applying
Now, we can apply these settings:
1user $ sudo netplan apply