Virtualization and Firewalls

For anyone out there who’s playing with KVM and potentially untrusted clients (and if your virtual machine can get hacked, it’s potentially untrusted! - so anyone using KVM) there are two things (specifically) you need to worry about with regards to protecting both the host and other virtual machines.

Firstly, what if someone mis-types their IP address when setting up their machine? It’s not an uncommon mistake, and the implications are that (a) you won’t be able to tie up traffic / abuse with their IP, and (b) they might be using someone else’s IP and potentially break someone else’s server.

Secondly, probably only done deliberately, what if they change the MAC address of their virtual network card? Any sort of filtering or firewalling based on MAC goes out the Window.

The main problem is that KVM/libvirt comes with it’s own ‘managed’ network filtering, which is in effect unmanaged and totally impossible to use sensibly, partly because Ubuntu don’t keep up with the libvirt source tree and partly because even when they do they decide not to compile in critical features like libpcap … which means you can’t actually use the network filtering as designed without recompiling KVM and libvirt from source!! … Ok, rant over, here’s the solution;

Anyone doing this properly will be using “firehol”, and in addition you will need “ebtables”. (and “iptables”, but you’ll already have this)


[ol]- apt-get install ebtables

  • edit /etc/libvirt/qemu/.xml and insert into the “interface” stanza.
  • /etc/init.d/libvirt-bin restart
  • do an ifconfig and check your “vnetx” interface has been renamed to “”
  • now insert the following at the head of your /etc/firehol/firehol.conf[/ol]
ebtables --flush

NODE1_IP="<instance ip address>"
NODE1_MAC="<instance MAC address>"
NODE1_INT="<instance interface name>"   #(or <instance> as used above)

ebtables -A FORWARD -i "$NODE1_INT" -s ! "$NODE1_MAC" -j DROP                           # Limit MAC to interface
iptables -A FORWARD -s "$NODE1_IP"  -m mac --mac-source ! "$NODE1_MAC" -j DROP          # Limit IP to MAC

All of a sudden you have a proper bridged KVM instance that the users can’t abuse in terms of MAC or IP address! 8)
-obviously you can repeat this block for each instance you have … (but only include the ebtables “flush” once!!)