Hi,

A while back I opened CLOUDSTACK-1164 [0] since I think that we should
use as much features of libvirt as possible.

libvirt supports network filtering [1] which basically controls
ebtables, iptables and ip6tables (IPv6 support!).

Using a XML definition you can create a filter and than use this filter
for a interface.

I created a simple setup to test:
- Can I prevent MAC spoofing?
- Can I prevent IP spoofing?
- Can I reload a filter without stopping my VM

All the questions were answered by "Yes", so I figured it was useful to
share this information.

On my laptop running Ubuntu 14.04 and libvirt 1.2.2 I created two VMs:
- One NIC with NAT for Internet access (no filter)
- One NIC on a isolated bridge

On the second NIC I assigned 192.168.100.1 and .2.

VM network_filter_1 got a filter assigned:

    <interface type='network'>
      <mac address='52:54:00:c1:b9:5b'/>
      <source network='filternetwork'/>
      <model type='virtio'/>
      <filterref filter='network_filter_1'/>
    </interface>

I created a filter called 'network_filter_1'

<filter name='network_filter_1' chain='ipv4'>
  <uuid>64b80046-9a9d-40c2-8782-ed5878146262</uuid>

  <rule action='drop' direction='out'>
    <mac match='no' srcmacaddr='52:54:00:c1:b9:5b'/>
  </rule>

  <rule action='drop' direction='out'>
    <ip match='no' srcipaddr='192.168.100.1'/>
  </rule>

  <rule action='accept' direction='in'>
    <tcp dstportstart='22'/>
  </rule>

  <rule action='accept' direction='in'>
    <tcp dstportstart='80'/>
  </rule>

  <rule action='accept' direction='in'>
    <tcp dstportstart='443'/>
  </rule>

  <rule action='drop' direction='in'>
    <all/>
  </rule>
</filter>

libvirt can auto-detect the MAC and IP, but since we already know that
information I didn't think I needed to test that.

$ virsh nwfilter-define filter.xml
$ virsh define network_filter_1.xml
$ virsh start network_filter_1

The result was simple. Using any different IP then 192.168.100.1 failed
and connections to ports not being 22, 80 or 443 failed.

Changes to filters were simple as well. Edit filter.xml and run:

$ virsh nwfilter-define filter.xml

Those changes were applied without stopping the VM. Done within 1 second.

I think it is worth the effort to use this instead of using
'security_group.py'.

On KVM we can always perform MAC address filtering and when security
grouping in shared or basic networking is used we can use libvirt to
filter all the traffic.

Less code we have to maintain and I prefer using libvirt over our custom
Python code.

This is not a functional spec yet, but I just wanted to get this
information out there and share what I found.

Looking at the libvirt docs I can't find anything which it can't do
which our security groups currently can. It already fully supports IPv6
which we don't.

CloudStack would only need to generate the proper XML documents and
that's all.

Wido

[0]: https://issues.apache.org/jira/browse/CLOUDSTACK-1164
[1]: http://libvirt.org/formatnwfilter.html

Reply via email to