Virtual Home Network (with Dnsmasq , Bridge, TUN/TAP, Qemu)

Updated: Apr 22, 2023

As I said in my Dnsmasq for Home User article, this post will explain how we can use bridge interface to configure networks inside virtual hosts and much more about virtualization.

First we need to make sure our machine is capable of kvm virtualization, see if you get any output for below command

$ grep -E 'vmx|svm' /proc/cpuinfo

Most modern processers supports Hardware assisted Virtualization. If you don’t get any output for above command, It means you don’t have a processor capable of providing Hardware Assisted Virtualization. Qemu-kvm will not work, but you can use Qemu without kvm or some other virtualization applications like virtualbox etc. Also skip LOADING KERNEL MODULES section of this article if you don’t have kvm support.

LOADING KERNEL MODULES

If your processor supports kvm, then we have to load following kernel modules and make sure they load automatically whenever we restart our system. In gentoo/sabayon, we need to modify modules= line in /etc/conf.d/modules file as

modules="kvm-intel tun"

Here kvm-intel is the kernel module for virtualization and tun is the kernel module for TUN/TAP devices. For, AMD machines, we need to load kvm-amd instead of kvm-intel. Now we need to load these modules for the current run, Here is the commands which will load kvm-intel and tun drivers into kernel

$ sudo modprobe kvm-intel tun
$

INSTALLING PACKAGES

Next is to install required packages, Here is sabayon command to install required packages

$ sudo equo install app-emulation/qemu-kvm net-misc/bridge-utilities net-dns/dnsmasq sys-apps/usermode-utilities
$

qemu-kvm is for virtualization, bridge-utilities is to get brctl command, dnsmasq is to handle DNS and DHCP requests from guests, usermode-utilities is to get tunctl command.

CREATING INTERFACES

Its time to create interfaces, first we need to create the bridge

$ sudo brctl addbr br0

Assign IP address to the bridge,

$ sudo ifconfig br0 192.168.2.1 netmask 255.255.255.0 up

Next, create a tap0 interface, following command will create tap0 pseudo slave interface from /dev/net/tun master interface

$ sudo tunctl -t tap0

Now, we need to hook the tap0 interface with the bridge br0

$ sudo brctl addif br0 tap0

Bring up the tap0

$ sudo ifconfig tap0 up

FIREWALL RULES AND MASQUERADING

If you read my previous ref:dnsmasq-for-home-user, I have dnsmasq configured to serve DHCP requests coming from br0. Hooking tap0 into br0 will make the guest send DHCP requests via tap0->br0 and my host machine’s dhsmasq process will serve ip address to the guest. We have to make sure iptables dont block BROADCAST packets as well as open the port 53 and 64 so that dnsmasq will get the DHCP and BOOTP packets. Make sure your iptables contains following lines,

$ sudo iptables -t filter -L | grep -E 'BROADCAST|domain|bootp'
ACCEPT     all  --  anywhere             anywhere             ADDRTYPE match src-type BROADCAST
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domainflags: FIN,SYN,RST,ACK/SYN
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootpsflags: FIN,SYN,RST,ACK/SYN
$

Now we need to make sure MASQUERADING is enabled and let your host system forward the packets. Also make these settings permanent so that reboot dont break the settings,

$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE
$ sudo sysctl net.ipv4.ip_forward=1
$ sudo /etc/init.d/iptables save
$ sudo /etc/init.d/iptables reload
$ sudo sed -i 's/^.*net.ipv4.ip_forward.*$/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf

Check these settings are ok,

$ sudo iptables -t nat -L
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  anywhere             anywhere
$ sudo sysctl -a | grep ipv4.ip_forward
net.ipv4.ip_forward = 1
$

STARTING QEMU GUEST

Finally, its time to start virtual guest, first we need to create disk image, Here is the command to create a 5GB raw disk image for qemu-kvm

$ sudo qemu-img create -f raw Debian.img 5G
$

Now download debian netinstall image for amd64 architecture

$ sudo wget http://ftp.nl.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot/gtk/mini.iso
$

Atlast, start the guest with with tap0 networking

$ qemu-kvm -cpu kvm64 -drive file=Debian.img,if=virtio -cdrom mini.iso -boot order=dc -m 512 -soundhw sb16 -name "Debian" -net nic,model=virtio -net tap,ifname="tap0",script=no,downscript=no

Thats it, your qemu guest will automatically get network settings from host machine. You can also verify that dnsmasq served a DHCP request via syslog

$ sudo grep 'dnsmasq-dhcp' /var/log/messages
dnsmasq-dhcp[9810]: DHCPDISCOVER(br0) 192.168.2.89 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPOFFER(br0) 192.168.2.89 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPREQUEST(br0) 192.168.2.89 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPACK(br0) 192.168.2.89 52:54:00:12:34:56 virt0
$

Well, if you still reading this article and not get bored, you must be a *nix admin. Have a great day!!