[libvirt] Integrating MAC address based filtering into libvirt

Hello, I am currently investigating the possibility to implement MAC address based filtering in libvirt and was wondering if there is any related effort going on and what people in general would think about that. Here is a description of my current prototype implementation: I have a small setup of two guests and a network: Guest1: root@stenzel-desktop:/etc/libvirt/qemu# cat build1.xml <domain type='kvm'> <name>build1</name> ... <interface type='network'> <mac address='D0:0F:D0:0F:02:01'/> <source network='mynet'/> <model type='virtio' /> </interface> ... </domain> Guest2: root@stenzel-desktop:/etc/libvirt/qemu# cat build2.xml <domain type='kvm'> <name>build2</name> ... <interface type='network'> <mac address='D0:0F:D0:0F:02:02'/> <source network='mynet'/> <model type='virtio' /> </interface> ... </domain> and the network to which I added a new XML element "filter" with attribute "mac", which switches on the MAC address filtering: root@stenzel-desktop:/etc/libvirt/qemu# cat networks/mynet.xml <network> <name>mynet</name> <uuid>920debe0-c3ef-4395-8241-ee82d4b49c2d</uuid> <bridge name="br%d" stp="off"/> <filter mac="on"/> </network> the "filter" element is evaluated at startup of libvirtd and a generic ebtables rules is generated (all frames are dropped): stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo ebtables -L Bridge table: filter ... Bridge chain: FORWARD, entries: 0, policy: DROP ... When starting up guest1, ... stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo virsh start build1 Domain build1 started ... an ebtables rule is generated to allow its mac address on the its interface: stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo ebtables -L ... Bridge chain: FORWARD, entries: 1, policy: DROP -s d0:f:d0:f:2:1 -i vnet0 -j ACCEPT ... the same happens when starting up the second guest: stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo virsh start build2 Domain build2 started stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo ebtables -L ... Bridge chain: FORWARD, entries: 2, policy: DROP -s d0:f:d0:f:2:2 -i vnet1 -j ACCEPT -s d0:f:d0:f:2:1 -i vnet0 -j ACCEPT ... so the two guests are allowed to communicate. After destroying the two guests, the corresponding ebtables rules are removed: stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo virsh destroy build2 Domain build2 destroyed stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo ebtables -L ... Bridge chain: FORWARD, entries: 1, policy: DROP -s d0:f:d0:f:2:1 -i vnet0 -j ACCEPT ... stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo virsh destroy build1 Domain build1 destroyed stenzel@stenzel-desktop:~/projects/vsn/libvirt$ sudo ebtables -L ... Bridge chain: FORWARD, entries: 0, policy: DROP ... The current prototype implementation is based on the existing iptables wrapper in libvirt. I basically cloned the iptables wrapper to an ebtables wrapper and did some ebtables specific adjustments. There are currenlty four occasions when the ebtables wrapper is called: - when creating the network - when adding a guest to the network - when removing a guest from the network - when destroying the network (currently not implemented) These calls can be augmented to also do for example tagged vlan and protocol filtering. Configuring the filter rules via virsh is also an option. Comments are appreciated. -- Best regards, Gerhard Stenzel, ----------------------------------------------------------------------------------------------------------------------------------- IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Erich Baier Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On Wed, Aug 19, 2009 at 02:11:14PM +0200, Gerhard Stenzel wrote:
Hello, I am currently investigating the possibility to implement MAC address based filtering in libvirt and was wondering if there is any related effort going on and what people in general would think about that.
Great, we certainly need these feature
and the network to which I added a new XML element "filter" with attribute "mac", which switches on the MAC address filtering:
root@stenzel-desktop:/etc/libvirt/qemu# cat networks/mynet.xml <network> <name>mynet</name> <uuid>920debe0-c3ef-4395-8241-ee82d4b49c2d</uuid> <bridge name="br%d" stp="off"/> <filter mac="on"/> </network>
the "filter" element is evaluated at startup of libvirtd and a generic ebtables rules is generated (all frames are dropped):
I think this extra XML element is probably redundant - we should always do MAC filtering at all times, on all bridges. Not simply those used in a virtual network, but also those connected to a real physical device too. I could see having a QEMU driver level configuration option in /etc/libvirt/qemu.conf though, to turn filtering on/off for the host as a whole though.
The current prototype implementation is based on the existing iptables wrapper in libvirt. I basically cloned the iptables wrapper to an ebtables wrapper and did some ebtables specific adjustments. There are currenlty four occasions when the ebtables wrapper is called: - when creating the network
What do you do to ebtables at this point ?
- when adding a guest to the network - when removing a guest from the network
Isn't it sufficient to only use ebtables in these two places ?
- when destroying the network (currently not implemented)
These calls can be augmented to also do for example tagged vlan and protocol filtering.
We probably also want to be able todo IP address filtering too. ie, if the guest XML has an <ip address> element inside the <interface> then we should add rules to ensure only IP traffic matching that source/target address is allowed to pass out/in Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Wed, 2009-08-19 at 13:35 +0100, Daniel P. Berrange wrote:
On Wed, Aug 19, 2009 at 02:11:14PM +0200, Gerhard Stenzel wrote: ... I think this extra XML element is probably redundant - we should always do MAC filtering at all times, on all bridges. Not simply those used in a virtual network, but also those connected to a real physical device too.
I used the extra XML element as a means to switch filtering on and off, I am not passionate about it.
I could see having a QEMU driver level configuration option in /etc/libvirt/qemu.conf though, to turn filtering on/off for the host as a whole though.
Fine with me, if that is the preferred way.
The current prototype implementation is based on the existing iptables wrapper in libvirt. I basically cloned the iptables wrapper to an ebtables wrapper and did some ebtables specific adjustments. There are currenlty four occasions when the ebtables wrapper is called: - when creating the network
What do you do to ebtables at this point ?
The "filter" element is evaluated at startup of libvirtd and a generic ebtables rules is generated to drop all frames. This could be changed to use the config option.
- when adding a guest to the network - when removing a guest from the network
Isn't it sufficient to only use ebtables in these two places ?
I think some generic settings should be dowe at libvirtd startup ...
- when destroying the network (currently not implemented)
... and some reasonable state should be restored at libvirtd shutdown, but that might be unnecessary.
These calls can be augmented to also do for example tagged vlan and protocol filtering.
We probably also want to be able todo IP address filtering too.
IP address filtering, VLAN tag filtering and similar are further down on my list.
ie, if the guest XML has an <ip address> element inside the <interface> then we should add rules to ensure only IP traffic matching that source/target address is allowed to pass out/in
Daniel -- Best regards,
Gerhard Stenzel, ----------------------------------------------------------------------------------------------------------------------------------- IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Erich Baier Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (2)
-
Daniel P. Berrange
-
Gerhard Stenzel