[libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs

Gerhard Stenzel gstenzel at linux.vnet.ibm.com
Fri Jan 22 12:29:16 UTC 2010


On Wed, 2010-01-13 at 17:36 +0000, Daniel P. Berrange wrote:
> In addition the DMTF XML format illustrated above is seriously ugly
> and not following the style of other libvirt XML formats. The use
> of UPPERCASE alone is reason enough to create a native libvirt format
> for this.  We should of course ensure that whatever we do can be
> reliably mapped into the DMTF format via a simple XSL transform.
> 
> Daniel

Hi, we have been thinking about the comments regarding the XML format
and hope the following is more in line with other libvirt XML formats:

As Stefan proposed originally, the guest interface has an additional
firewall. The firewall can have several filters, some of which are
generic and template based and some are guest specific. The template
filters can take parameters.
The filters contain rules, currently for mac, arp, vlan and ip. A rule
is applied if the conditions specified by the attributes and their
values are true and the specified action will happen. The match
attribute can be used to specify that the action should happen if the
condition is not true.
If an attribute is supplied on a rule but its value is empty (''), the
supplied parameter for a template or the respective value for the
current interface is used.

This will need a few more examples to verify it is sufficient, but here
is the current status:

The guest xml file:
-------------------
<domain type='kvm'>
  <name>demo</name>
  <memory>256000</memory>
  <devices>
    <interface type="bridge">
      <firewall>
	<filter template='drop-all'/>
	<filter template='no-arp-spoofing' srcipaddr='10.0.0.1'/>
	<filter template='no-mac-spoofing'/>
	<filter template='no-ip-spoofing srcipaddr='10.0.0.1'/>
	<filter>
	  <!-- allow outgoing IPV4 packets with the 
	       guest mac addr and vlanid 3 -->
	  <rule action='allow' direction='out'>
	    <mac srcmacaddr='' />
	    <vlan id='3'/>
	    <ip version='4'/>
	  </rule>

	  <!-- only accept non-IPV6 packets from
	  'aa:bb:cc:dd:ee:ff' -->
	  <rule action='allow' direction='in'>
	    <mac srcmacaddr='aa:bb:cc:dd:ee:ff' />
	    <vlan id='3'/>
	    <ip  match='no' version='6'/>
	  </rule>

	  <!-- no access to port 25 allowed -->
	  <rule action='allow' direction='in'>
	    <ip match='no'
		dstportstart = '25'
		dstportend   = '25' />
	  </rule>
	</filter>
      </firewall>
    </interface>
  </devices>
</domain>

The template xml files could be similar to this:
------------------------------------------------

<firewall>
  <!-- by default drop everything -->
  <template name='drop-all'>
    <filter policy='drop' />
  </template>
  
  <template name='no-arp-spoofing'>
    <filter name='ARP' policy='drop'>
      <!-- no arp spoofing -->
      <!-- drop if ipaddr or macaddr does not belong to guest -->
      <rule action='drop' direction='out'>
	<arp match='no' srcmacaddr=''/>
	<arp match='no' srcipaddr='' />
      </rule>
      <!-- drop if ipaddr or macaddr does not belong to guest -->
      <rule action='drop' direction='in'>
	<arp match='no' dstmacaddr=' '/>
	<arp match='no' dstipaddr='' />
      </rule>
      <!-- allow all other request or reply packets -->
      <rule action='allow' direction='inout'>
	<arp opcode='request'/>
	<arp opcode='reply'/>
      </rule>
    </filter>
  </template>
  
  <template name='no-mac-spoofing'>
    <filter name='DLFT'>
      <!-- no mac spoofing -->
      <rule action='drop' direction='out'>
	<mac match='no' srcmacaddr=''/>
      </rule>
    </filter>
  </template>
  
  <template name='no-ip-spoofing'>
    <filter name='IPv4'>
      <!-- no ip spoofing -->
      <rule action='drop' direction='out'>
	<ip match='no' srcipaddr=''/>
      </rule>
    </filter>
  </template>
  
  
  
Fully populated elements for schema generation:
  
  <filter name='IPv4' table='filter' priority='1'>
    <rule action='drop' direction='out'>
      <mac match='yes'
	   srcmacaddr='aa:bb:cc:dd:ee:ff'
	   srcmacmask='ff:ff:ff:ff:ff:ff'
	   dstmacaddr='aa:bb:cc:dd:ee:fe'
	   dstmacmask='ff:ff:ff:ff:ff:ff' />
      <vlan id='3' protocol  ='1' priority  ='1'/>
      <arp match='yes'
	   hwtype='1'
	   protocoltype='IPv4'
	   opcode='request'
	   srcmacaddr='aa:bb:cc:dd:ee:ff'
	   srcipaddr='192.168.0.1'
	   dstmacaddr='aa:bb:cc:dd:ee:fe'
	   dstipaddr='192.168.0.1'/>
    </rule>
    <rule action='accept' direction='inout'>
      <ip match='no'
	  version    = '4'
	  srcipaddr    = '192.168.0.1'
	  srcipmask    = '255.255.255.255'
	  dstipaddr    = '192.168.0.2'
	  dstipmask    = '255.255.255.255'
	  protocol     = '6'
	  srcportstart = '100'
	  srcportend   = '200'
	  dstportstart = '101'
	  dstportend   = '201'
	  hdrdscp      = '12345678' />
    </rule>
  </filter>

The (generated) schema looks currently like this. This will need of
course additional manual rework once we can agree on the basic approach:

<?xml version="1.0" encoding="UTF-8"?>
<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <element name="firewall">
      <oneOrMore>
        <element name="template">
          <attribute name="name">
            <data type="NCName"/>
          </attribute>
          <ref name="filter"/>
        </element>
      </oneOrMore>
      <ref name="filter"/>
    </element>
  </start>
  <define name="filter">
    <element name="filter">
      <optional>
        <attribute name="name">
          <data type="NCName"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="policy">
          <data type="NCName"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="priority">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="table">
          <data type="NCName"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <element name="rule">
          <attribute name="action">
            <data type="NCName"/>
          </attribute>
          <attribute name="direction">
            <data type="NCName"/>
          </attribute>
          <optional>
            <element name="mac">
              <optional>
                <attribute name="dstmacaddr">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="dstmacmask">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
              <attribute name="match">
                <data type="NCName"/>
              </attribute>
              <attribute name="srcmacaddr">
                <data type="anyURI"/>
              </attribute>
              <optional>
                <attribute name="srcmacmask">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
            </element>
          </optional>
          <optional>
            <element name="vlan">
              <attribute name="id">
                <data type="integer"/>
              </attribute>
              <attribute name="priority">
                <data type="integer"/>
              </attribute>
              <attribute name="protocol">
                <data type="integer"/>
              </attribute>
            </element>
          </optional>
          <choice>
            <element name="ip">
              <optional>
                <attribute name="dstipaddr">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="dstipmask">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="dstportend">
                  <data type="integer"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="dstportstart">
                  <data type="integer"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="hdrdscp">
                  <data type="integer"/>
                </attribute>
              </optional>
              <attribute name="match">
                <data type="NCName"/>
              </attribute>
              <optional>
                <attribute name="protocol">
                  <data type="integer"/>
                </attribute>
              </optional>
              <attribute name="srcipaddr"/>
              <optional>
                <attribute name="srcipmask">
                  <data type="NMTOKEN"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="srcportend">
                  <data type="integer"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="srcportstart">
                  <data type="integer"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="version">
                  <data type="integer"/>
                </attribute>
              </optional>
            </element>
            <zeroOrMore>
              <element name="arp">
                <optional>
                  <attribute name="dstipaddr"/>
                </optional>
                <optional>
                  <attribute name="dstmacaddr">
                    <data type="anyURI"/>
                  </attribute>
                </optional>
                <optional>
                  <attribute name="hwtype">
                    <data type="integer"/>
                  </attribute>
                </optional>
                <optional>
                  <attribute name="match">
                    <data type="NCName"/>
                  </attribute>
                </optional>
                <optional>
                  <attribute name="opcode">
                    <data type="NCName"/>
                  </attribute>
                </optional>
                <optional>
                  <attribute name="protocoltype">
                    <data type="NCName"/>
                  </attribute>
                </optional>
                <optional>
                  <attribute name="srcipaddr"/>
                </optional>
                <optional>
                  <attribute name="srcmacaddr">
                    <data type="anyURI"/>
                  </attribute>
                </optional>
              </element>
            </zeroOrMore>
          </choice>
        </element>
      </zeroOrMore>
    </element>
  </define>
</grammar>


-- 
Best regards, 

Gerhard Stenzel, 
-----------------------------------------------------------------------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294




More information about the libvir-list mailing list