Discussion:
[libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
(too old to reply)
Stefan Berger
2010-01-11 17:55:27 UTC
Permalink
Hello!

The following is a proposal to introduce network traffic filtering
capabilities for the network traffic originating from and destined to
virtual machines. Libvirt's capabilities will be extended to allow users
to describe what traffic filtering rules are to be applied on a virtual
machine (using XML) and libvirt then creates the appropriate ebtables and
iptables rules and applies those on the host when the virtual machine
starts up, resumes after suspension or resumes on a new host after
migration. libvirt tears down the traffic filtering rules when the virtual
machine shuts down, suspends, or a VM is migrated to another host. It will
also be possible to modify the filtering rules while a virtual machine is
running. In this architecture we apply the firewall rules on the outside
of the virtual machines on the Linux host and make use of the fact that
virtual machines can be configured by libvirt to have their network
traffic pass through the host and the host exposes (tap) 'backend'
interfaces on which the firewall rules can be applied. The application of
the firewall rules is optional and those who do not want to introduce a
raw network throughput performance hit on their system due to the
evaluation of every packet passing through the filtering chains, do not
have to use these capabilities. An initial implementation would be done
for libvirt's Qemu support.

As stated above, the application of firewall rules on virtual machines
will require some form of XML description that lets the user choose what
type of filtering is to be performed. In effect the user needs to be able
to tell libvirt which ebtables and iptables rules to generate so that the
appropriate filtering can be done. We realize that ebtables and iptables
have lots of capabilities but think that we need to restrict which
capabilities can actually be 'reached' through this XML.

The following proposal is based on an XML as defined by the DMTF (
http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf, slide
10) with extensions for processing of ARP packets.It gives control over
the evaluation of Ethernet (MAC) frames, ARP packet data and IP header
information. A (draft) XML skeleton in this case could look as follows:

<FilterEntry>
<Action>DROP|ACCEPT</Action> <!-- from FilterEntry -->

<TrafficType>incoming [to VM]|outgoing [from VM]</TrafficType>

<Hdr8021Filter>
<HdrSrcMACAddr8021> </HdrSrcMACAddr8021>
<HdrSrcMACMask8021> </HdrSrcMACMask8021>
<HdrDestMACAddr8021> </HdrDestMACAddr8021>
<HdrDestMACMask8021> </HdrDestMACMask8021>
<HdrProtocolID8021> numeric and/or string?
</HdrProtocolID8021>
<HdrPriorityValue8021></HdrPriorityValue8021>
<HdrVLANID8021> </HdrVLANID8021>
</Hdr8021Filter>

<ARPFilter>
<HWType> </HWType>
<ProtocolType> </ProtocolType>
<OPCode> </OPCode>
<SrcMACAddr> </SrcMACAddr>
<SrcIPAddr> </SrcIPAddr>
<DestMACAddr> </DestMACAddr>
<DestIPAddr> </DestIPAddr>
</ARPFilter>

<IPHeadersFilter>
<HdrIPVersion> </HdrIPVersion>
<HdrSrcAddress> </HdrSrcAddress>
<HdrSrcMask> </HdrSrcMask>
<HdrDestAddress> </HdrDestAddress>
<HdrDestMask> </HdrDestMask>
<HdrProtocolID> numeric and/or string? </HdrProtocolID>
<HdrSrcPortStart> </HdrSrcPortStart>
<HdrSrcPortEnd> </HdrSrcPortEnd>
<HdrDestPortStart> </HdrDestPortStart>
<HdrDestPortEnd> </HdrDestPortEnd>
<HdrDSCP> </HdrDSCP>
</IPHeadersFilter>

</FilterEntry>

Since the ebtables and iptables command cannot accept all possible
parameters at the same time, only a certain subset of the above parameters
may be set for any given filter command. Higher level application writers
will likely use a library that lets them choose which features they would
want to have enforced, such as no-broadcast or no-multicast, enforcement
of MAC spoofing prevention or ARP poisoning prevention, which then
generates this lower level XML rules in the appropriate order of the
rules.

Further, we will introduce filter pools where a collection of the above
filter rules can be stored and referenced to by virtual machines'
individual interface. A reference to such a filter pool entry will be
given in the interface description and may look as in the following draft
XML:

<interface type='bridge'>
<source bridge='virbr0'/>
<script path='vif-bridge'/>
<firewall>
<reference profile='generic-layer2' ip_address='10.0.0.1'/>
<reference profile='VM-specific-layer3'/>
</firewall>
</interface>

The above XML has one reference to a generic layer2 filter template XML
that should be usable by multiple virtual machines but would need to be
customized with interface-specific parameters. In this case, the IP
address of the interface is explicitly provided in order to make the
filter XML template a concrete XML for the particular interface. The MAC
address of the interface is not explicitly provided since it will already
have been randomly generated by libvirt at the point when this layer2
filter XML needs to be converted into concrete ebtables commands/rules. We
still need to determine how the format of a template should look like,
though an idea would be to indicate a placeholder for a VM's MAC address
using THIS_MAC and similarly for the IP address with THIS_IP as
placeholder.

Further, we would introduce the management of filter 'pools'. Considering
existing functionality in libvirt and CLI commands for similar type of
management functionality, the following CLI commands would be added:

virsh nwfilter-create <file>
virsh nwfilter-destroy <profile name>
virsh nwfilter-list <options>
virsh nwfilter-dumpxml <profile name>
virsh nwfilter-update <filename> (performs an update on an existing
profile replacing all rules)

possibly also:

virsh nwfilter-edit <profile name>
virsh nwfilter-create-from <profile name>


Please let us know what you think of this proposal.

Regards
Stefan, Gerhard and Vivek
Daniel Veillard
2010-01-13 17:03:22 UTC
Permalink
Post by Stefan Berger
Hello!
The following is a proposal to introduce network traffic filtering
capabilities for the network traffic originating from and destined to
virtual machines. Libvirt's capabilities will be extended to allow users
to describe what traffic filtering rules are to be applied on a virtual
machine (using XML) and libvirt then creates the appropriate ebtables and
iptables rules and applies those on the host when the virtual machine
starts up, resumes after suspension or resumes on a new host after
migration. libvirt tears down the traffic filtering rules when the virtual
machine shuts down, suspends, or a VM is migrated to another host. It will
also be possible to modify the filtering rules while a virtual machine is
running. In this architecture we apply the firewall rules on the outside
of the virtual machines on the Linux host and make use of the fact that
virtual machines can be configured by libvirt to have their network
traffic pass through the host and the host exposes (tap) 'backend'
interfaces on which the firewall rules can be applied. The application of
the firewall rules is optional and those who do not want to introduce a
raw network throughput performance hit on their system due to the
evaluation of every packet passing through the filtering chains, do not
have to use these capabilities. An initial implementation would be done
for libvirt's Qemu support.
It's relatively clear that this would not work with devices exposed
natively to the domain, say though PCI passthough. I'm wondering what
other case of limitiations could be found. Also this may not map well
for other kind of hypervisors like VMWare, right ?
Post by Stefan Berger
As stated above, the application of firewall rules on virtual machines
will require some form of XML description that lets the user choose what
type of filtering is to be performed. In effect the user needs to be able
to tell libvirt which ebtables and iptables rules to generate so that the
appropriate filtering can be done. We realize that ebtables and iptables
have lots of capabilities but think that we need to restrict which
capabilities can actually be 'reached' through this XML.
The following proposal is based on an XML as defined by the DMTF (
http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf, slide
10) with extensions for processing of ARP packets.It gives control over
the evaluation of Ethernet (MAC) frames, ARP packet data and IP header
Humpf, extending astandard XML schemas is really bad practice. Even if
you think that the extension may be accepted later, it may have
different semantic for the same construct and that's a disaster.
I would at least put the new elements in a separate namespace to
avoid something insane if DMTF extends its specification.
Post by Stefan Berger
<FilterEntry>
<Action>DROP|ACCEPT</Action> <!-- from FilterEntry -->
<TrafficType>incoming [to VM]|outgoing [from VM]</TrafficType>
<Hdr8021Filter>
<HdrSrcMACAddr8021> </HdrSrcMACAddr8021>
<HdrSrcMACMask8021> </HdrSrcMACMask8021>
<HdrDestMACAddr8021> </HdrDestMACAddr8021>
<HdrDestMACMask8021> </HdrDestMACMask8021>
<HdrProtocolID8021> numeric and/or string?
</HdrProtocolID8021>
<HdrPriorityValue8021></HdrPriorityValue8021>
<HdrVLANID8021> </HdrVLANID8021>
</Hdr8021Filter>
<ARPFilter>
<HWType> </HWType>
<ProtocolType> </ProtocolType>
<OPCode> </OPCode>
<SrcMACAddr> </SrcMACAddr>
<SrcIPAddr> </SrcIPAddr>
<DestMACAddr> </DestMACAddr>
<DestIPAddr> </DestIPAddr>
</ARPFilter>
<IPHeadersFilter>
<HdrIPVersion> </HdrIPVersion>
<HdrSrcAddress> </HdrSrcAddress>
<HdrSrcMask> </HdrSrcMask>
<HdrDestAddress> </HdrDestAddress>
<HdrDestMask> </HdrDestMask>
<HdrProtocolID> numeric and/or string? </HdrProtocolID>
<HdrSrcPortStart> </HdrSrcPortStart>
<HdrSrcPortEnd> </HdrSrcPortEnd>
<HdrDestPortStart> </HdrDestPortStart>
<HdrDestPortEnd> </HdrDestPortEnd>
<HdrDSCP> </HdrDSCP>
</IPHeadersFilter>
</FilterEntry>
hum the types for each values should be made explicit if possible,
But in general I find that extremely bulky for a single entry, while
I would expect any domain to have a dozen filters or so just for
simple stuff. I wonder if empty default should just be dropped, so
that basically if you're filtering on a MAC address you don't carry
a bunch of unused fields.
Post by Stefan Berger
Since the ebtables and iptables command cannot accept all possible
parameters at the same time, only a certain subset of the above parameters
may be set for any given filter command. Higher level application writers
will likely use a library that lets them choose which features they would
want to have enforced, such as no-broadcast or no-multicast, enforcement
of MAC spoofing prevention or ARP poisoning prevention, which then
generates this lower level XML rules in the appropriate order of the
rules.
I wonder if a tailored set of simpler XML matching what is actually
possible and getting away from the DMTF records wouldn't be better,
since the original spec is extended on the feature side and the
applicability is restricted on the implementation side, I'm not sure I
see the point of trying to be compatible.
Post by Stefan Berger
Further, we will introduce filter pools where a collection of the above
filter rules can be stored and referenced to by virtual machines'
individual interface. A reference to such a filter pool entry will be
given in the interface description and may look as in the following draft
<interface type='bridge'>
<source bridge='virbr0'/>
<script path='vif-bridge'/>
<firewall>
<reference profile='generic-layer2' ip_address='10.0.0.1'/>
<reference profile='VM-specific-layer3'/>
</firewall>
</interface>
the devil is in the details, basically how you would template
the profiles based on the strings in the reference. I.e. what the
profile would look like and how for example ip_address='10.0.0.1'
would be instancied in the profile use.
Post by Stefan Berger
The above XML has one reference to a generic layer2 filter template XML
that should be usable by multiple virtual machines but would need to be
customized with interface-specific parameters. In this case, the IP
address of the interface is explicitly provided in order to make the
filter XML template a concrete XML for the particular interface. The MAC
address of the interface is not explicitly provided since it will already
have been randomly generated by libvirt at the point when this layer2
filter XML needs to be converted into concrete ebtables commands/rules. We
still need to determine how the format of a template should look like,
though an idea would be to indicate a placeholder for a VM's MAC address
using THIS_MAC and similarly for the IP address with THIS_IP as
placeholder.
Further, we would introduce the management of filter 'pools'. Considering
existing functionality in libvirt and CLI commands for similar type of
virsh nwfilter-create <file>
virsh nwfilter-destroy <profile name>
virsh nwfilter-list <options>
virsh nwfilter-dumpxml <profile name>
virsh nwfilter-update <filename> (performs an update on an existing
profile replacing all rules)
virsh nwfilter-edit <profile name>
virsh nwfilter-create-from <profile name>
Please let us know what you think of this proposal.
The feature looks interesting ! It looks it should be applicable to
at least qemu and xen, I'm not so sure about LXC or VirtualBox, and
looks unlikely for VMWare unless they have a matching capability (might
be possible since it's based at least partly on DMTF).
I'm not sure reusing the DMTF format actually helps much, it also has
its risks due to the extension.

Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
***@veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
Daniel P. Berrange
2010-01-13 17:36:45 UTC
Permalink
Post by Daniel Veillard
Post by Stefan Berger
As stated above, the application of firewall rules on virtual machines
will require some form of XML description that lets the user choose what
type of filtering is to be performed. In effect the user needs to be able
to tell libvirt which ebtables and iptables rules to generate so that the
appropriate filtering can be done. We realize that ebtables and iptables
have lots of capabilities but think that we need to restrict which
capabilities can actually be 'reached' through this XML.
The following proposal is based on an XML as defined by the DMTF (
http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf, slide
10) with extensions for processing of ARP packets.It gives control over
the evaluation of Ethernet (MAC) frames, ARP packet data and IP header
Humpf, extending astandard XML schemas is really bad practice. Even if
you think that the extension may be accepted later, it may have
different semantic for the same construct and that's a disaster.
I would at least put the new elements in a separate namespace to
avoid something insane if DMTF extends its specification.
Post by Stefan Berger
<FilterEntry>
<Action>DROP|ACCEPT</Action> <!-- from FilterEntry -->
<TrafficType>incoming [to VM]|outgoing [from VM]</TrafficType>
<Hdr8021Filter>
<HdrSrcMACAddr8021> </HdrSrcMACAddr8021>
<HdrSrcMACMask8021> </HdrSrcMACMask8021>
<HdrDestMACAddr8021> </HdrDestMACAddr8021>
<HdrDestMACMask8021> </HdrDestMACMask8021>
<HdrProtocolID8021> numeric and/or string?
</HdrProtocolID8021>
<HdrPriorityValue8021></HdrPriorityValue8021>
<HdrVLANID8021> </HdrVLANID8021>
</Hdr8021Filter>
<ARPFilter>
<HWType> </HWType>
<ProtocolType> </ProtocolType>
<OPCode> </OPCode>
<SrcMACAddr> </SrcMACAddr>
<SrcIPAddr> </SrcIPAddr>
<DestMACAddr> </DestMACAddr>
<DestIPAddr> </DestIPAddr>
</ARPFilter>
<IPHeadersFilter>
<HdrIPVersion> </HdrIPVersion>
<HdrSrcAddress> </HdrSrcAddress>
<HdrSrcMask> </HdrSrcMask>
<HdrDestAddress> </HdrDestAddress>
<HdrDestMask> </HdrDestMask>
<HdrProtocolID> numeric and/or string? </HdrProtocolID>
<HdrSrcPortStart> </HdrSrcPortStart>
<HdrSrcPortEnd> </HdrSrcPortEnd>
<HdrDestPortStart> </HdrDestPortStart>
<HdrDestPortEnd> </HdrDestPortEnd>
<HdrDSCP> </HdrDSCP>
</IPHeadersFilter>
</FilterEntry>
hum the types for each values should be made explicit if possible,
But in general I find that extremely bulky for a single entry, while
I would expect any domain to have a dozen filters or so just for
simple stuff. I wonder if empty default should just be dropped, so
that basically if you're filtering on a MAC address you don't carry
a bunch of unused fields.
Post by Stefan Berger
Since the ebtables and iptables command cannot accept all possible
parameters at the same time, only a certain subset of the above parameters
may be set for any given filter command. Higher level application writers
will likely use a library that lets them choose which features they would
want to have enforced, such as no-broadcast or no-multicast, enforcement
of MAC spoofing prevention or ARP poisoning prevention, which then
generates this lower level XML rules in the appropriate order of the
rules.
I wonder if a tailored set of simpler XML matching what is actually
possible and getting away from the DMTF records wouldn't be better,
since the original spec is extended on the feature side and the
applicability is restricted on the implementation side, I'm not sure I
see the point of trying to be compatible.
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
--
|: 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 :|
Gerhard Stenzel
2010-01-22 12:29:16 UTC
Permalink
Post by Daniel P. Berrange
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
Daniel P. Berrange
2010-01-25 14:59:04 UTC
Permalink
Post by Gerhard Stenzel
Post by Daniel P. Berrange
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
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
-------------------
<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 shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule

<filter name='BLAH'/>

and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Post by Gerhard Stenzel
------------------------------------------------
<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='' />
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
Post by Gerhard Stenzel
</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>
I don't think that '<firewall>' is the top level object to be managed
here. I would suggest that '<firewall>' and '<template>' elements are
redundant, and that <filter> should be for the top level managed objects.
The libvirt API would allow listing of existing filters, creating / deleting
filters and updating the config. The <filter> element would allow some kind
of <include> element to allow a complex filter to be built out of multiple
simpler filters.


Regards,
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 :|
Vivek Kashyap
1970-01-01 00:00:00 UTC
Permalink
Date: Mon, 25 Jan 2010 14:59:04 +0000
Subject: Re: [libvirt] [RFC] Proposal for introduction of network traffic
filtering capabilities for filtering of network traffic from and to VMs
Post by Gerhard Stenzel
Post by Daniel P. Berrange
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
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
-------------------
<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 shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
Yes,that would be cleaner. It can be done with the above xml if the
rules are organised in such a way. Or, are you suggesting that it must
always be that there is only one entry referring to a separate filter object.
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Post by Gerhard Stenzel
------------------------------------------------
<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='' />
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
Yes, this is a good idea. We had originally thought of introducing a
symbol like 'THIS_IP' for the specific domain.
Post by Gerhard Stenzel
</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>
I don't think that '<firewall>' is the top level object to be managed
here. I would suggest that '<firewall>' and '<template>' elements are
redundant, and that <filter> should be for the top level managed objects.
The libvirt API would allow listing of existing filters, creating / deleting
filters and updating the config. The <filter> element would allow some kind
of <include> element to allow a complex filter to be built out of multiple
simpler filters.
yes, that should be possible.

thanks
Vivek
Regards,
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 :|
--
libvir-list mailing list
https://www.redhat.com/mailman/listinfo/libvir-list
__

Vivek Kashyap
Linux Technology Center, IBM
Gerhard Stenzel
2010-01-26 13:24:43 UTC
Permalink
...
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
...
Post by Daniel P. Berrange
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
...
Post by Daniel P. Berrange
I don't think that '<firewall>' is the top level object to be managed
here. I would suggest that '<firewall>' and '<template>' elements are
redundant, and that <filter> should be for the top level managed objects.
The libvirt API would allow listing of existing filters, creating / deleting
filters and updating the config. The <filter> element would allow some kind
of <include> element to allow a complex filter to be built out of multiple
simpler filters.
Regards,
Daniel
Daniel,

ok, trying to combine your suggestions:

- guest contains a single filter reference per interface

guest.xml:
----------
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' ipaddr='10.0.0.1'/>
</interface>
</devices>
</domain>

- complex filter include other filter and can contain rules

complex demofilter.xml:
-----------------------
<filter name='demofilter'>
<include href='drop-all'/>
<include href='no-arp-spoofing' srcipaddr='$IP'/>
<include href='no-mac-spoofing'/>
<include href='no-ip-spoofing' srcipaddr='$IP'/>
<!-- no ip spoofing -->
<rule action='drop' direction='out'>
<ip match='no' srcipaddr='$IP'/>
</rule>
</filter>

- simple filter contain only rules

simple no-arp-spoofing.xml:
---------------------------
<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='$MAC'/>
<arp match='no' srcipaddr='$IP' />
</rule>
<!-- drop if ipaddr or macaddr does not belong to guest -->
<rule action='drop' direction='in'>
<arp match='no' dstmacaddr='$MAC'/>
<arp match='no' dstipaddr='$IP' />
</rule>
<!-- allow all other request or reply packets -->
<rule action='allow' direction='inout'>
<arp opcode='request'/>
<arp opcode='reply'/>
</rule>
</filter>

- $IP, $MAC represent the guests configured IP,MAC values

If the above seems acceptable for the moment, I would suggest we verify that this is actually implementable or if we missed something.
--
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
Daniel P. Berrange
2010-01-26 13:35:36 UTC
Permalink
Post by Gerhard Stenzel
...
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
...
Post by Daniel P. Berrange
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
...
Post by Daniel P. Berrange
I don't think that '<firewall>' is the top level object to be managed
here. I would suggest that '<firewall>' and '<template>' elements are
redundant, and that <filter> should be for the top level managed objects.
The libvirt API would allow listing of existing filters, creating / deleting
filters and updating the config. The <filter> element would allow some kind
of <include> element to allow a complex filter to be built out of multiple
simpler filters.
Regards,
Daniel
Daniel,
- guest contains a single filter reference per interface
----------
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' ipaddr='10.0.0.1'/>
</interface>
There's no need for ipaddr there - the XML schema already allows
for a

<ip address='10.0.0.1'/>

within the <interface> tag here. We already have MAC address as
a separate tag too. We could likely add VLAN in a similar way.
Post by Gerhard Stenzel
</devices>
</domain>
- complex filter include other filter and can contain rules
-----------------------
<filter name='demofilter'>
<include href='drop-all'/>
<include href='no-arp-spoofing' srcipaddr='$IP'/>
<include href='no-mac-spoofing'/>
<include href='no-ip-spoofing' srcipaddr='$IP'/>
<!-- no ip spoofing -->
<rule action='drop' direction='out'>
<ip match='no' srcipaddr='$IP'/>
</rule>
</filter>
- simple filter contain only rules
---------------------------
<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='$MAC'/>
<arp match='no' srcipaddr='$IP' />
</rule>
<!-- drop if ipaddr or macaddr does not belong to guest -->
<rule action='drop' direction='in'>
<arp match='no' dstmacaddr='$MAC'/>
<arp match='no' dstipaddr='$IP' />
</rule>
<!-- allow all other request or reply packets -->
<rule action='allow' direction='inout'>
<arp opcode='request'/>
<arp opcode='reply'/>
</rule>
</filter>
- $IP, $MAC represent the guests configured IP,MAC values
If the above seems acceptable for the moment, I would suggest we
verify that this is actually implementable or if we missed something.
Yes, those examples capture what I was trying to describe.

Regards,
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 :|
Gerhard Stenzel
2010-01-26 13:49:04 UTC
Permalink
Post by Daniel P. Berrange
There's no need for ipaddr there - the XML schema already allows
for a
<ip address='10.0.0.1'/>
within the <interface> tag here. We already have MAC address as
a separate tag too. We could likely add VLAN in a similar way.
agreed.

We will start with the implementation and send a patch or rather a
series once we have them.

Thanks.
--
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
Stefan Berger
2010-01-26 15:16:23 UTC
Permalink
Post by Daniel P. Berrange
Post by Gerhard Stenzel
...
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
...
Post by Daniel P. Berrange
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
...
Post by Daniel P. Berrange
I don't think that '<firewall>' is the top level object to be managed
here. I would suggest that '<firewall>' and '<template>' elements are
redundant, and that <filter> should be for the top level managed objects.
The libvirt API would allow listing of existing filters,
creating / deleting
Post by Gerhard Stenzel
Post by Daniel P. Berrange
filters and updating the config. The <filter> element would
allow some kind
Post by Gerhard Stenzel
Post by Daniel P. Berrange
of <include> element to allow a complex filter to be built out
of multiple
Post by Gerhard Stenzel
Post by Daniel P. Berrange
simpler filters.
Regards,
Daniel
Daniel,
- guest contains a single filter reference per interface
----------
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' ipaddr='10.0.0.1'/>
</interface>
There's no need for ipaddr there - the XML schema already allows
for a
<ip address='10.0.0.1'/>
within the <interface> tag here. We already have MAC address as
a separate tag too. We could likely add VLAN in a similar way.
A VM may be allowed to generate traffic on multiple VLANs (having multiple
different VLAN interfaces inside the VM). For that we may need different
rules per VLAN traffic that the VM is allowed to send traffic on.

Since we only reference the filter in the interface XML, I suppose that we
need to rely on higher layers to take care of migrating those
filters and referenced sub(-sub)-filters to the target host. Correct?

Stefan
Daniel P. Berrange
2010-01-26 15:22:58 UTC
Permalink
Post by Daniel P. Berrange
Post by Daniel P. Berrange
Post by Gerhard Stenzel
...
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
...
Post by Daniel P. Berrange
What was the idea with the empty attributes here ? Are those
implying that the attribute value is to be filled in with the
value from the domain XML ? If so I'd probably make that more
explicit using something like $IP and $MAC to represent the
guest configured IP/MAC
...
Post by Daniel P. Berrange
I don't think that '<firewall>' is the top level object to be
managed
Post by Daniel P. Berrange
Post by Gerhard Stenzel
Post by Daniel P. Berrange
here. I would suggest that '<firewall>' and '<template>' elements
are
Post by Daniel P. Berrange
Post by Gerhard Stenzel
Post by Daniel P. Berrange
redundant, and that <filter> should be for the top level managed
objects.
Post by Daniel P. Berrange
Post by Gerhard Stenzel
Post by Daniel P. Berrange
The libvirt API would allow listing of existing filters,
creating / deleting
Post by Gerhard Stenzel
Post by Daniel P. Berrange
filters and updating the config. The <filter> element would
allow some kind
Post by Gerhard Stenzel
Post by Daniel P. Berrange
of <include> element to allow a complex filter to be built out
of multiple
Post by Gerhard Stenzel
Post by Daniel P. Berrange
simpler filters.
Regards,
Daniel
Daniel,
- guest contains a single filter reference per interface
----------
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' ipaddr='10.0.0.1'/>
</interface>
There's no need for ipaddr there - the XML schema already allows
for a
<ip address='10.0.0.1'/>
within the <interface> tag here. We already have MAC address as
a separate tag too. We could likely add VLAN in a similar way.
A VM may be allowed to generate traffic on multiple VLANs (having multiple
different VLAN interfaces inside the VM). For that we may need different
rules per VLAN traffic that the VM is allowed to send traffic on.
Since we only reference the filter in the interface XML, I suppose that we
need to rely on higher layers to take care of migrating those
filters and referenced sub(-sub)-filters to the target host. Correct?
Yes, management apps are responsible for ensuring that each host within
a "migration pool" has the same configuration for all relevant areas,
including storage mount points / device naming, network device naming,
firewall configuration, etc, etc

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 :|
Stefan Berger
2010-02-18 13:53:22 UTC
Permalink
Post by Gerhard Stenzel
Daniel,
- guest contains a single filter reference per interface
----------
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' ipaddr='10.0.0.1'/>
</interface>
</devices>
</domain>
As the implementation of this progresses and we make design decision, we
now introduced attributes and values for the
filters to be passed in the format of

att%d='<attribute>' val%d='<value>'

thus we would rewrite the above example to:

<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' att0='IP' val0='10.0.0.1'/>
</interface>
</devices>
</domain>

This allows us to pass any necessary parameters to the filters for
instantiation in
the respective environment. So, if a filter is to be instantiated and
holds the variable
XYZ, then one may add

att1='XYZ' val1='<some value>'
Post by Gerhard Stenzel
- complex filter include other filter and can contain rules
-----------------------
<filter name='demofilter'>
<include href='drop-all'/>
<include href='no-arp-spoofing' srcipaddr='$IP'/>
--> <include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'.
Post by Gerhard Stenzel
<include href='no-mac-spoofing'/>
<include href='no-ip-spoofing' srcipaddr='$IP'/>
<!-- no ip spoofing -->
<rule action='drop' direction='out'>
<ip match='no' srcipaddr='$IP'/>
</rule>
</filter>
So any referenced filter, also as shown above in the demofilter.xml, could
hold environment-specific values for required variables.
A filter requiring a variable that is not passed is not instantiated and
will prevent interface creation / attachment or the start
of the VM.
Further, if an attribute value pair (IP) as shown here is passed from the
domain XML and another value as shown here in the referenced filter
is again set, the one from further 'up' is used, i.e., IP=10.0.0.1 rather
than IP=1.2.3.4.

Does this sound ok?

Regards,
Stefan
Matthias Bolte
2010-02-18 14:15:47 UTC
Permalink
Post by Gerhard Stenzel
Daniel,
- guest contains a single filter reference per interface
----------
<domain type='kvm'>
  <name>demo</name>
  <memory>256000</memory>
  <devices>
    <interface type="bridge">
      <filter name='demofilter' ipaddr='10.0.0.1'/>
    </interface>
  </devices>
</domain>
As the implementation of this progresses and we make design decision, we now
introduced attributes and values for the
filters to be passed in the format of
att%d='<attribute>' val%d='<value>'
<domain type='kvm'>
 <name>demo</name>
 <memory>256000</memory>
 <devices>
   <interface type="bridge">
     <filter name='demofilter' att0='IP' val0='10.0.0.1'/>
   </interface>
 </devices>
</domain>
This allows us to pass any necessary parameters to the filters for
instantiation in
the respective environment. So, if a filter is to be instantiated and holds
the variable
XYZ, then one may add
att1='XYZ' val1='<some value>'
Passing parameters this way seems a bit unexpected for XML. How about
something like this:

<interface type="bridge">
<filter name='demofilter'>
<parameter name='IP' value='10.0.0.1'/>
</filter>
</interface>
Post by Gerhard Stenzel
- complex filter include other filter and can contain rules
-----------------------
<filter name='demofilter'>
  <include href='drop-all'/>
  <include href='no-arp-spoofing' srcipaddr='$IP'/>
-->   <include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'.
And the same pattern for the includes:

<include href='no-arp-spoofing'>
<parameter name='IP' value='1.2.3.4'/>
</include>

Matthias
Stefan Berger
2010-02-18 14:33:36 UTC
Permalink
Post by Matthias Bolte
Post by Gerhard Stenzel
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' att0='IP' val0='10.0.0.1'/>
</interface>
</devices>
</domain>
This allows us to pass any necessary parameters to the filters for
instantiation in
the respective environment. So, if a filter is to be instantiated and holds
the variable
XYZ, then one may add
att1='XYZ' val1='<some value>'
Passing parameters this way seems a bit unexpected for XML. How about
<interface type="bridge">
<filter name='demofilter'>
<parameter name='IP' value='10.0.0.1'/>
</filter>
</interface>
Also a possibility...

Stefan
Stefan Berger
2010-02-18 15:45:41 UTC
Permalink
"Daniel P. Berrange", veillard, libvir-list, Vivek Kashyap
Post by Gerhard Stenzel
<domain type='kvm'>
<name>demo</name>
<memory>256000</memory>
<devices>
<interface type="bridge">
<filter name='demofilter' att0='IP' val0='10.0.0.1'/>
</interface>
</devices>
</domain>
This allows us to pass any necessary parameters to the filters for
instantiation in
the respective environment. So, if a filter is to be instantiated and holds
the variable
XYZ, then one may add
att1='XYZ' val1='<some value>'
Passing parameters this way seems a bit unexpected for XML. How about
<interface type="bridge">
<filter name='demofilter'>
<parameter name='IP' value='10.0.0.1'/>
</filter>
</interface>
I think we'll change this to ...

<interface type="bridge">
<filterref ref='demofilter'>
<parameter name='IP' value='10.0.0.1'/>
</filter>
</interface>
Post by Gerhard Stenzel
Post by Gerhard Stenzel
- complex filter include other filter and can contain rules
-----------------------
<filter name='demofilter'>
<include href='drop-all'/>
<include href='no-arp-spoofing' srcipaddr='$IP'/>
--> <include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'.
... and this to ...
<include href='no-arp-spoofing'>
<parameter name='IP' value='1.2.3.4'/>
</include>
<filterref ref='no-arp-spoofing'>
<parameter name='IP' value='1.2.3.4'/>
</include>

... to be consistent.


Thanks for feedback.

Stefan
Matthias
Gerhard Stenzel
2010-02-22 12:45:20 UTC
Permalink
On Thu, 2010-02-18 at 10:45 -0500, Stefan Berger wrote:
....
Post by Stefan Berger
<filterref ref='no-arp-spoofing'>
<parameter name='IP' value='1.2.3.4'/>
</include>
... to be consistent.
Thanks for feedback.
Stefan
Post by Matthias Bolte
Matthias
--
libvir-list mailing list
https://www.redhat.com/mailman/listinfo/libvir-list
Hi, here is a preview of a chapter which is eventually intended for the
libvirt application development guide. It is not final yet, but I feel
now would be a good moment to gather some first feedback and to
"finalise" the XML schema which is used in the examples.

------------------------------------------------------------------------

1. Network Filter

1.1. Overview

1.2. XML Filter Description Format

1.2.1. Complex Filter

1.2.2. Simple Filters

1.3. Retrieving Information About Filter

1.3.1. TBD


Chapter 1. Network Filter
---------------------------

1.1. Overview

1.2. XML Filter Description Format

1.2.1. Complex Filter

1.2.2. Simple Filters

1.3. Retrieving Information About Filter

1.3.1. TBD

This section covers the management and definition of network filters
using the libvirt API.


1.1. Overview
--------------

The configuration of network filters can be examined and modified with
functions in the virTBSL API. This is useful for setting up filter rules
to control which network packets are allowed from and to a guest
domains.
Currently, filters for Ethernet (MAC) frames, ARP packet data and IP
header information are possible.


1.2. XML Filter Description Format
-----------------------------------

The current Relax NG schema definition of the XML that is
produced/accepted by TBD can be found in the filter.rng. Filtering is
currently enabled by adding a filterref element to the interface
description of a domain XML file. The filterref element has a filter
atttribute which references the corresponding filter definition like in
the following example.

<domain type='kvm' id='1'>
<name>build1</name>
<uuid>c7ac4ad9-e5ce-4c93-b380-013c85663e39</uuid>
<memory>262144</memory>
<currentMemory>262144</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc-0.11'>hvm</type>
<loader>/usr/lib/xen/boot/hvmloader</loader>
<kernel>/etc/libvirt/qemu/bzImage</kernel>
<initrd>/etc/libvirt/qemu/i686-rootfs.i686.cpio.gz</initrd>
<cmdline>kvmguest=1</cmdline>
<boot dev='hd'/>
</os>
<features>
<acpi/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<disk type='file' device='disk'>
<source file='/etc/libvirt/qemu/i686-rootfs.i686.ext2'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<disk type='file' device='cdrom'>
<target dev='hdc' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='1' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<interface type='network'>
<mac address='d0:0f:d0:0f:02:01'/>
<source network='mynet'/>
<model type='virtio'/>
<filterref filter='demofilter'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/1'/>
<target port='0'/>
</serial>
<console type='pty' tty='/dev/pts/1'>
<source path='/dev/pts/1'/>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>



Example 1.1. XML definition for a guest.


Network filters are specified using rules or by referencing other
filters
via filterref. This allows to construct complex filters from simpler,
potentially predefined filters.


1.2.1. Complex Filter

The named filters in the following examples are complex filters, which
include other, potentially predefined, filters. Included filters can
take
parameters, which are specified via an attX-valX pair (X starts at 0).

<filter name='demofilter'>
<filterref filter='no-arp-spoofing'/>
<filterref filter='no-mac-spoofing'/>
<filterref filter='no-ip-spoofing'/>
<filterref filter='no-mac-broadcast'/>
<filterref filter='allow-dhcp'>
<parameter name='DHCPSERVER' value='10.3.2.1'/>
</filterref>
<filterref filter='no-other-l2-traffic'/>
</filter>


Example 1.2. XML definition for a complex filetr.


This is a pure Layer 2 filter configuration:

<filter name='demofilter2'>
<filterref filter='no-mac-spoofing'/>
<filterref filter='no-mac-broadcast'/>
<filterref filter='allow-arp'/>
<filterref filter='allow-ipv4'/>
<filterref filter='no-other-l2-traffic'/>
</filter>


Example 1.3. XML definition for another complex filetr.


1.2.2. Simple Filters

The following examples of simple filters are predefined and address
distint filter requirements. The predefined no-arp-spoofing filter drops
all ARP packets

* originating from the guest if they contain other than the guests IP
or MAC address

* destined for the guest if they contain other than the guests IP or
MAC address

It accepts all request or reply ARP packets.

<filter name='no-arp-spoofing' chain='arp'>
<uuid>f88f1932-debf-4aa1-9fbe-f10d3aa4bc95</uuid>

<!-- no arp spoofing -->
<!-- drop if ipaddr or macaddr does not belong to guest -->
<rule action='drop' direction='out'>
<arp match='no' srcmacaddr='$MAC'/>
</rule>
<rule action='drop' direction='out'>
<arp match='no' srcipaddr='$IP' />
</rule>
<!-- drop if ipaddr or macaddr odes not belong to guest -->
<rule action='drop' direction='in'>
<arp match='no' dstmacaddr='$MAC'/>
</rule>
<rule action='drop' direction='in'>
<arp match='no' dstipaddr='$IP' />
</rule>
<!-- accept only request or reply packets -->
<rule action='accept' direction='inout'>
<arp opcode='request'/>
</rule>
<rule action='accept' direction='inout'>
<arp opcode='reply'/>
</rule>
<!-- drop everything else -->
<rule action='drop' direction='inout'/>
</filter>


Example 1.4. XML definition to prevent ARP spoofing.


The predefined no-mac-spoofing filter drops all ethernet packets from
the
guest containing other than the guests MAC address as the source MAC
address.

<filter name='no-mac-spoofing' chain='ipv4'>
<rule action='drop' direction='out'>
<mac match='no' srcmacaddr='$MAC' />
</rule>
</filter>


Example 1.5. XML definition to prevent MAC spoofing.


The predefined no-ip-spoofing filter drops all IP packets from the guest
containing other than the guests IP address as the source IP address.

<filter name='no-ip-spoofing' chain='ipv4'>

<!-- no ip spoofing -->
<!-- drop if srcipaddr is not the address of the guest -->
<rule action='drop' direction='out'>
<ip match='no' srcipaddr='$IP' />
</rule>

<!-- not doing anything with receiving side to prevent eavesdropping
-->
</filter>


Example 1.6. XML definition to prevent IP spoofing.


The predefined no-mac-broadcast filter drops all ethernet packets with
the broadcast mac address as destination.

<filter name='no-mac-broadcast' chain='ipv4'>
<!-- drop if destination mac is bcast mac addr. -->
<rule action='drop' direction='out'>
<mac dstmacaddr='ff:ff:ff:ff:ff:ff' />
</rule>

<!-- not doing anything with receiving side ... -->
</filter>


Example 1.7. XML definition to prevent outgoing broadcasts.


The predefined allow-dhcp filter allows DHCP requests and replies from
the specified DHCP server.

<filter name='allow-dhcp' chain='ipv4'>

<!-- accept outgoing DHCP requests -->
<!-- not, this rule must be avaluated before general MAC broadcast
traffic is discarded since DHCP requests use MAC broadcast -->
<rule action='accept' direction='out'>
<ip srcipaddr='0.0.0.0'
dstipaddr='255.255.255.255'
protocol='udp'
srcportstart='68'
dstportstart='67' />
</rule>

<!-- accept incoming DHCP responses from a specific DHCP server
parameter DHPCSERVER needs to be passed from where this filter
is
referenced -->
<rule action='accept' direction='in'>
<ip srcipaddr='$DHCPSERVER'
protocol='udp'
srcportstart='67'
dstportstart='68'/>
</rule>

</filter>


Example 1.8. XML definition to allow DHCP requests and replys.


The predefined no-ip-multicast filter drops all ethernet packets with
the
multicast IP address as destination.

<filter name='no-ip-multicast' chain='ipv4'>

<!-- drop if destination IP address is in the 224.0.0.0/4 subnet -->
<rule action='drop' direction='out'>
<ip dstipaddr='224.0.0.0' dstipmask='4' />
</rule>

<!-- not doing anything with receiving side ... -->
</filter>


Example 1.9. XML definition to prevent multicast


The predefined no-other-l2-traffic filter drops all layer 2 packets
which
did not match other rules.

<filter name='no-other-l2-traffic'>

<!-- drop all other l2 traffic than for which rules have been
written for
Note: this rule should be the last on in the 'root' chain -->
<rule action='drop' direction='inout'/>

</filter>


Example 1.10. XML definition to drop all other layer 2 traffic.


<filter name='allow-arp' chain='arp'>
<rule direction='inout' action='accept'/>
</filter>


Example 1.11. XML definition to allow arp traffic.


<filter name='allow-ipv4' chain='ipv4'>
<rule direction='inout' action='accept'/>
</filter>


Example 1.12. XML definition to allow IPV4 traffic.
------------------------------------------------------------------------
--
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
Daniel P. Berrange
2010-03-01 16:15:56 UTC
Permalink
Post by Gerhard Stenzel
Hi, here is a preview of a chapter which is eventually intended for the
libvirt application development guide. It is not final yet, but I feel
now would be a good moment to gather some first feedback and to
"finalise" the XML schema which is used in the examples.
Thanks, this is a good idea !
Post by Gerhard Stenzel
------------------------------------------------------------------------
1. Network Filter
1.1. Overview
1.2. XML Filter Description Format
1.2.1. Complex Filter
1.2.2. Simple Filters
1.3. Retrieving Information About Filter
1.3.1. TBD
Chapter 1. Network Filter
---------------------------
1.1. Overview
1.2. XML Filter Description Format
1.2.1. Complex Filter
1.2.2. Simple Filters
1.3. Retrieving Information About Filter
1.3.1. TBD
This section covers the management and definition of network filters
using the libvirt API.
1.2.2. Simple Filters
The following examples of simple filters are predefined and address
distint filter requirements. The predefined no-arp-spoofing filter drops
all ARP packets
* originating from the guest if they contain other than the guests IP
or MAC address
* destined for the guest if they contain other than the guests IP or
MAC address
It accepts all request or reply ARP packets.
<filter name='no-arp-spoofing' chain='arp'>
Perhaps we should call that 'chain' attribute 'protocol' instead since
that appears to be what you're representing there. I'm wondering how
this should interact with the <filterref> element. eg, you might have
chain='ipv4' on the main filter, and then a <filterref> pointing to
a chain='arp'. One way would be to declare that a <filter> can contain
either <rule> or <filterref>, but not a mixture of both.
Post by Gerhard Stenzel
<uuid>f88f1932-debf-4aa1-9fbe-f10d3aa4bc95</uuid>
<!-- no arp spoofing -->
<!-- drop if ipaddr or macaddr does not belong to guest -->
<rule action='drop' direction='out'>
<arp match='no' srcmacaddr='$MAC'/>
</rule>
<rule action='drop' direction='out'>
<arp match='no' srcipaddr='$IP' />
</rule>
<!-- drop if ipaddr or macaddr odes not belong to guest -->
<rule action='drop' direction='in'>
<arp match='no' dstmacaddr='$MAC'/>
</rule>
<rule action='drop' direction='in'>
<arp match='no' dstipaddr='$IP' />
</rule>
<!-- accept only request or reply packets -->
<rule action='accept' direction='inout'>
<arp opcode='request'/>
</rule>
<rule action='accept' direction='inout'>
<arp opcode='reply'/>
</rule>
<!-- drop everything else -->
<rule action='drop' direction='inout'/>
</filter>
Generally, your proposal looks good to me.

Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
Gerhard Stenzel
2010-02-04 12:07:59 UTC
Permalink
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Daniel,
we could achieve something similar with the following construct:

<xi:include href="demofilter.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>

This would also have the advantage that the filter rules do not clutter
up the domain xml, but the migration of the rules might be simpler to
implement.
What is your thinking about this approach?
--
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
Daniel P. Berrange
2010-02-04 13:40:57 UTC
Permalink
Post by Gerhard Stenzel
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Daniel,
<xi:include href="demofilter.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
This would also have the advantage that the filter rules do not clutter
up the domain xml, but the migration of the rules might be simpler to
implement.
What is your thinking about this approach?
This addresses the problem from the public facing XML point of view, but
not from the internal implementation. If we have an explicitly separate
filter that can be referenced from multiple places, then the internal
libvirt implmentation can optimize this to only create 1 set of iptables
rules that are used to apply to all guests referencing the filter. If
by constrast you do the includes at the XML document level, then the
internal implementation cannot practically use a shared set of rules
and so you'll end up with the same rulesets having to be duplicated in
iptables for each guest, which could cause scalability limitations

Regards,
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 :|
Matthias Bolte
2010-02-04 13:50:29 UTC
Permalink
Post by Gerhard Stenzel
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC.  I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
   <filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Daniel,
<xi:include href="demofilter.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
This would also have the advantage that the filter rules do not clutter
up the domain xml, but the migration of the rules might be simpler to
implement.
What is your thinking about this approach?
--
Best regards,
Gerhard Stenzel,
Such an include mechanism was suggest by Dan before, but I don't think
that XInclude is a good approach, because this will make the XML
handling more complicated.

The main libvirt functions to define/create a new guest are
virDomainDefineXML and virDomainCreateXML. Both take the domain XML
description a string. They don't take filenames. Using XInclude
introduces the need for filenames to be able to reference them by the
href attribute of an XInclude element. Even if libvirt stores the
filter rules as files internally this should be considered as an
implementation detail. IMHO exposing paths to internal files isn't a
good design decision. The same is true for virDomainGetXMLDesc, it
would have to expose paths to internal files to be read by management
applications using libvirt.

I think the best approach to handle the filter setup while being able
build complex filter from simpler parts is an include mechanism, but
not using XInclude or reference the filter parts by filename, but by
filter name.

<domain>
<devices>
<interface>
<filter name='demofilter'/>
</interface>
</devices>
</domain>

<filter name='demofilter'>
<include filter='dropall'/>
...
</filter>

<filter name='dropall'>
...
</filter>

libvirt would have API to handle filters by name and their XML
description in string form, no file handling involved. Maybe something
like this in line with the rest of the libvirt API:

virConnectListFilters to list all known filters
virFilterDefineXML to define a filter from an XML description in string form
virFilterUndefine to undefine an existing filter
virFilterGetXMLDesc to get the XML description in string form of an
existing filter
virFilterLookupByName to find a filter by name
...

Matthias
Stefan Berger
2010-02-04 14:16:35 UTC
Permalink
libvir-list, Gerhard Stenzel, Vivek Kashyap
Post by Gerhard Stenzel
Post by Daniel P. Berrange
The shear size of the ruleset inside the <interface> element is
rather alarming to me. Imagine if you have a guest with more
than one NIC. I'm inclined to suggest that the <interface>
element in the domain XML description should only have a single
rule
<filter name='BLAH'/>
and if apps wish to construct a filter, from multiple independant
sub-filters, then that should be done against the filter object's
config, rather than the domain object's config.
Daniel,
<xi:include href="demofilter.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
This would also have the advantage that the filter rules do not clutter
up the domain xml, but the migration of the rules might be simpler to
implement.
What is your thinking about this approach?
--
Best regards,
Gerhard Stenzel,
Such an include mechanism was suggest by Dan before, but I don't think
that XInclude is a good approach, because this will make the XML
handling more complicated.
The main libvirt functions to define/create a new guest are
virDomainDefineXML and virDomainCreateXML. Both take the domain XML
description a string. They don't take filenames. Using XInclude
introduces the need for filenames to be able to reference them by the
href attribute of an XInclude element. Even if libvirt stores the
filter rules as files internally this should be considered as an
implementation detail. IMHO exposing paths to internal files isn't a
good design decision. The same is true for virDomainGetXMLDesc, it
would have to expose paths to internal files to be read by management
applications using libvirt.
I think the best approach to handle the filter setup while being able
build complex filter from simpler parts is an include mechanism, but
not using XInclude or reference the filter parts by filename, but by
filter name.
The problem with the references is the migratability. In my opinion, the
filters attached to a virtual machine's interface should migrate to a
destination host completely transparently using 'virsh migrate' and allow
migration to fail if the instantiation of the rule fails due to for
example a missing ebtables/iptables support module, but not due to missing
filter XML. This means that in the simple case where the VM had a filter
rule no-ip-spoofing active on an interface on the source this same
filtering should become active on the destination. However, most VMs will
have much more complex rules and may use references to existing templates
and add their own interface specific rules on top of that. Now how do you
migrate that? How do you handle cases where a template on the source was
referenced and may be missing on the destination or if the template on the
destination is different (ignore it?). I guess the more involved solution
would be to migrate the whole tree of referenced filters and using
internal APIs to again make them available on the host, failing if filters
with same names already exists, succeeding for others. Not sure whether
the migration protocol can handle that...
<domain>
<devices>
<interface>
<filter name='demofilter'/>
</interface>
</devices>
</domain>
<filter name='demofilter'>
<include filter='dropall'/>
...
</filter>
<filter name='dropall'>
...
</filter>
libvirt would have API to handle filters by name and their XML
description in string form, no file handling involved. Maybe something
virConnectListFilters to list all known filters
virFilterDefineXML to define a filter from an XML description in string form
virFilterUndefine to undefine an existing filter
virFilterGetXMLDesc to get the XML description in string form of an
existing filter
virFilterLookupByName to find a filter by name
...
Yes, initial prototype provides similar functions but does not solve the
migration problem ...

Stefan
Matthias
--
libvir-list mailing list
https://www.redhat.com/mailman/listinfo/libvir-list
Stefan Berger
2010-01-13 21:42:23 UTC
Permalink
Post by Daniel Veillard
Post by Stefan Berger
Hello!
[...]
Post by Daniel Veillard
Post by Stefan Berger
raw network throughput performance hit on their system due to the
evaluation of every packet passing through the filtering chains, do not
have to use these capabilities. An initial implementation would be done
for libvirt's Qemu support.
It's relatively clear that this would not work with devices exposed
natively to the domain, say though PCI passthough. I'm wondering what
Future SR-IOV devices may be programmable and provide at least a subset
of the filtering that can be done with this XML. In that case we would
probably need hardware specific drivers in libvirt that can issue proper
ioctl()s with the proper parameters to activate the corresponding
filtering.
Post by Daniel Veillard
other case of limitiations could be found. Also this may not map well
for other kind of hypervisors like VMWare, right ?
I don't know much about the API that VMWare is exposing. Maybe only a
certain subset of what would be possible with this XML could be applied
to their API, if such functionality exist. Otherwise, if libvirt
can run ebtables and iptables commands on their management VM and
all traffic passes through VM=specific network interface (tap) in that VM,
it *should* work as well.
Post by Daniel Veillard
Post by Stefan Berger
As stated above, the application of firewall rules on virtual machines
will require some form of XML description that lets the user choose what
type of filtering is to be performed. In effect the user needs to be able
to tell libvirt which ebtables and iptables rules to generate so that the
appropriate filtering can be done. We realize that ebtables and iptables
have lots of capabilities but think that we need to restrict which
capabilities can actually be 'reached' through this XML.
The following proposal is based on an XML as defined by the DMTF (
http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf, slide
10) with extensions for processing of ARP packets.It gives control over
the evaluation of Ethernet (MAC) frames, ARP packet data and IP header
Humpf, extending astandard XML schemas is really bad practice. Even if
you think that the extension may be accepted later, it may have
different semantic for the same construct and that's a disaster.
I would at least put the new elements in a separate namespace to
avoid something insane if DMTF extends its specification.
Yes, we could do that. As said, this was meant as a draft.
Post by Daniel Veillard
Post by Stefan Berger
<FilterEntry>
<Action>DROP|ACCEPT</Action> <!-- from FilterEntry -->
<TrafficType>incoming [to VM]|outgoing [from VM]</TrafficType>
<Hdr8021Filter>
<HdrSrcMACAddr8021> </HdrSrcMACAddr8021>
<HdrSrcMACMask8021> </HdrSrcMACMask8021>
<HdrDestMACAddr8021> </HdrDestMACAddr8021>
<HdrDestMACMask8021> </HdrDestMACMask8021>
<HdrProtocolID8021> numeric and/or string?
</HdrProtocolID8021>
<HdrPriorityValue8021></HdrPriorityValue8021>
<HdrVLANID8021> </HdrVLANID8021>
</Hdr8021Filter>
<ARPFilter>
<HWType> </HWType>
<ProtocolType> </ProtocolType>
<OPCode> </OPCode>
<SrcMACAddr> </SrcMACAddr>
<SrcIPAddr> </SrcIPAddr>
<DestMACAddr> </DestMACAddr>
<DestIPAddr> </DestIPAddr>
</ARPFilter>
<IPHeadersFilter>
<HdrIPVersion> </HdrIPVersion>
<HdrSrcAddress> </HdrSrcAddress>
<HdrSrcMask> </HdrSrcMask>
<HdrDestAddress> </HdrDestAddress>
<HdrDestMask> </HdrDestMask>
<HdrProtocolID> numeric and/or string?
</HdrProtocolID>
Post by Daniel Veillard
Post by Stefan Berger
<HdrSrcPortStart> </HdrSrcPortStart>
<HdrSrcPortEnd> </HdrSrcPortEnd>
<HdrDestPortStart> </HdrDestPortStart>
<HdrDestPortEnd> </HdrDestPortEnd>
<HdrDSCP> </HdrDSCP>
</IPHeadersFilter>
</FilterEntry>
hum the types for each values should be made explicit if possible,
But in general I find that extremely bulky for a single entry, while
I would expect any domain to have a dozen filters or so just for
simple stuff. I wonder if empty default should just be dropped, so
that basically if you're filtering on a MAC address you don't carry
a bunch of unused fields.
Of course empty XML elements would not be shown. The above XML is meant
to show all the network packet 'elements' that can be tested and for which

also ebtables and iptables support exists. Also only a certain combination
of the above elements would be set for a specific corresponding ebtables
command.

An example for a (template) XML for testing against MAC spoofing
could be this XML here, which drops all IPv4 packets that don't have
the proper MAC address set.

<FilterEntry>
<Action>DROP</Action>
<TrafficType>outgoing</TrafficType>
<Hdr8021Filter>
<HdrSrcMACAddr8021>![THIS_MAC]</HdrSrcMACAddr8021>
</Hdr8021Filter>
<IPHeadersFilter>
<HdrIPVersion>4</HdrIPVersion>
</IPHeadersFilter>
</FilterEntry>
Post by Daniel Veillard
Post by Stefan Berger
Since the ebtables and iptables command cannot accept all possible
parameters at the same time, only a certain subset of the above parameters
may be set for any given filter command. Higher level application writers
will likely use a library that lets them choose which features they would
want to have enforced, such as no-broadcast or no-multicast,
enforcement
Post by Daniel Veillard
Post by Stefan Berger
of MAC spoofing prevention or ARP poisoning prevention, which then
generates this lower level XML rules in the appropriate order of the
rules.
I wonder if a tailored set of simpler XML matching what is actually
possible and getting away from the DMTF records wouldn't be better,
since the original spec is extended on the feature side and the
applicability is restricted on the implementation side, I'm not sure I
see the point of trying to be compatible.
If we want to give the user full control over the ebtables and iptables
features,
an XML as the one above would be necessary. A more higher level XML may
look as
follows:

<firewall>
<no-mac-spoofing/>
<no-ip-spoofing address="9.59.241.151"/>
<ether-allow protocols='ARP,IPv4'/>
[...]
</firewall>

This XML only gives the user control over the features that have been
explicitly implemented in libvirt, i.e., the driver would know what the
corresponding ebtables commands are to enforce no-mac-spoofing, in which
order the ebtable rules need to be organized and when to create new user
defined
ebtables (ebtables -N) to provide a more efficient evaluation of the
filtering.
The XSL trafo that Daniel Berrange mentioned would likely not be possible
with this XML, since the ordering, depending on the chosen security
features, may
be tricky to support with a transformation.

In the explicit XML above, the user would be expected to put the rules
into
proper order and likely would somehow need to provide user defined table
names
into which the individual rules need to be put. With this XML here, this
would
be automatically handled by the libvirt implementation.
Post by Daniel Veillard
Post by Stefan Berger
Further, we will introduce filter pools where a collection of the above
filter rules can be stored and referenced to by virtual machines'
individual interface. A reference to such a filter pool entry will be
given in the interface description and may look as in the following draft
<interface type='bridge'>
<source bridge='virbr0'/>
<script path='vif-bridge'/>
<firewall>
<reference profile='generic-layer2' ip_address='10.0.0.1'/>
<reference profile='VM-specific-layer3'/>
</firewall>
</interface>
the devil is in the details, basically how you would template
the profiles based on the strings in the reference. I.e. what the
profile would look like and how for example ip_address='10.0.0.1'
would be instancied in the profile use.
We thought that maybe the HdrSrcMACAddr8021 XML element could have
[THIS_MAC]
as content, which would then need to become concrete when instantiated.
Similarly we could put [THIS_IP] into the XML element testing for
source (and destination) IP address. So the ip_address above would be
passed into the function instantiating the rules for the VM.
Post by Daniel Veillard
Post by Stefan Berger
Further, we would introduce the management of filter 'pools'. Considering
existing functionality in libvirt and CLI commands for similar type of
virsh nwfilter-create <file>
virsh nwfilter-destroy <profile name>
virsh nwfilter-list <options>
virsh nwfilter-dumpxml <profile name>
virsh nwfilter-update <filename> (performs an update on an existing
profile replacing all rules)
virsh nwfilter-edit <profile name>
virsh nwfilter-create-from <profile name>
Please let us know what you think of this proposal.
The feature looks interesting ! It looks it should be applicable to
at least qemu and xen, I'm not so sure about LXC or VirtualBox, and
looks unlikely for VMWare unless they have a matching capability (might
be possible since it's based at least partly on DMTF).
It would work with any technology that uses an ethernet interface in
the host, i.e., a tap or backend interface, through which all the VM's
network
traffic passes. All firewall rules would be conditioned on the VM's
interface
name and jump into a VM-specific rules tree.

As for VirtualBox, since it is Qemu based and probably has a tap
interface,
this should also work. I have never used LXC, so I cannot say much about
it,
but it would also require a network interface in the host onto which
ebtables and iptables could condition their rules on
(ebtables -A ... -i <tap interface name> ...).


One other thing to consider is whether pools should actually be used. The
problem with
the pools may arise when trying to migrate VMs. If the target host does
not have
the same named pool, then higher layer software would need to migrate the
firewall rules
first so the same rules can be enforced on the target as well. If,
however, the rules
are directly in the interface XML of the VM description, then migration
would be
done using 'virsh migrate', since the VM description migrates anyway.

Regards,
Stefan
Post by Daniel Veillard
I'm not sure reusing the DMTF format actually helps much, it also has
its risks due to the extension.
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit
http://xmlsoft.org/
Post by Daniel Veillard
http://veillard.com/ | virtualization library http://libvirt.org/
Matthias Bolte
2010-01-13 22:30:44 UTC
Permalink
Post by Stefan Berger
Post by Daniel Veillard
Post by Stefan Berger
Hello!
[...]
[...]
Post by Stefan Berger
Post by Daniel Veillard
other case of limitiations could be found. Also this may not map well
for other kind of hypervisors like VMWare, right ?
I don't know much about the API that VMWare is exposing. Maybe only a
certain subset of what would be possible with this XML could be applied
to their API, if such functionality exist. Otherwise, if libvirt
can run ebtables and iptables commands on their management VM and
all traffic passes through VM=specific network interface (tap) in that VM,
it *should* work as well.
VMware ESX hosts allow to configure the host level firewall via the
remote VI API. But AFAIK there is no virtual machine level firewall.

You're not supposed to do something like that in the service console,
doing anything in the service console is not supported in general.
Also there is no libvirtd in the service console because of that and
because it is not necessary. The ESX driver does everything using the
remote VI API.

Matthias
Dimitrios Pendarakis
2010-01-14 00:09:02 UTC
Permalink
Note that this is the case for the standard VMware ESX vSwitch. However,
the Cisco Nexus 1000v,
which is an optional virtual switch for ESX, does appear to provide (guest)
VM firewall capabilities.
See for example the section on "isolation and protection" and ACLs in the
link below:

http://www.cisco.com/en/US/prod/collateral/switches/ps9441/ps9902/dmz_virtualization_vsphere4_nexus1000V.pdf

In terms of interfaces, the 1000v claims a CLI (likely similar to physical
Cisco switches), support for SNMP
and an XML API.

Thanks,
Dimitrios



From: Matthias Bolte <***@googlemail.com>

To: Stefan Berger/Watson/***@IBMUS

Cc: Gerhard Stenzel <***@de.ibm.com>, libvir-***@redhat.com, Vivek
Kashyap/Beaverton/***@IBMUS

Date: 01/13/2010 05:43 PM

Subject: Re: [libvirt] [RFC] Proposal for introduction of network traffic filtering
capabilities for filtering of network traffic from and to VMs
Post by Stefan Berger
Post by Daniel Veillard
Post by Stefan Berger
Hello!
[...]
[...]
Post by Stefan Berger
Post by Daniel Veillard
other case of limitiations could be found. Also this may not map well
for other kind of hypervisors like VMWare, right ?
I don't know much about the API that VMWare is exposing. Maybe only a
certain subset of what would be possible with this XML could be applied
to their API, if such functionality exist. Otherwise, if libvirt
can run ebtables and iptables commands on their management VM and
all traffic passes through VM=specific network interface (tap) in that VM,
it *should* work as well.
VMware ESX hosts allow to configure the host level firewall via the
remote VI API. But AFAIK there is no virtual machine level firewall.

You're not supposed to do something like that in the service console,
doing anything in the service console is not supported in general.
Also there is no libvirtd in the service console because of that and
because it is not necessary. The ESX driver does everything using the
remote VI API.

Matthias
Glennie Vignarajah
2010-01-15 09:24:55 UTC
Permalink
Le 14/01/2010 vers 01:09, dans le message intitulé "Re: [libvirt] [RFC]
Proposal for introduction of network traffic filtering capabilities for
filtering of network traffic from and to VMs", Dimitrios Pendarakis(Dimitrios
Pendarakis <***@us.ibm.com>) a écrit:


Hi,
Post by Dimitrios Pendarakis
Note that this is the case for the standard VMware ESX vSwitch. However,
the Cisco Nexus 1000v,
which is an optional virtual switch for ESX, does appear to provide (guest)
VM firewall capabilities.
OpenVswitch project (http://openvswitch.org/) seems to provide the same thing
for KVM, Xen and Virtualbox. This should be wonderfull if the VM based
filtering is done using OpenVswitch capabilities...
--
http://www.glennie.fr
If the only tool you have is hammer, you tend to see every problem as a nail.
Vivek Kashyap
1970-01-01 00:00:00 UTC
Permalink
Post by Stefan Berger
Post by Daniel Veillard
The feature looks interesting ! It looks it should be applicable to
at least qemu and xen, I'm not so sure about LXC or VirtualBox, and
looks unlikely for VMWare unless they have a matching capability (might
be possible since it's based at least partly on DMTF).
It would work with any technology that uses an ethernet interface in
the host, i.e., a tap or backend interface, through which all the VM's
network
traffic passes. All firewall rules would be conditioned on the VM's
interface
name and jump into a VM-specific rules tree.
As for VirtualBox, since it is Qemu based and probably has a tap
interface,
this should also work. I have never used LXC, so I cannot say much about
it,
but it would also require a network interface in the host onto which
ebtables and iptables could condition their rules on
(ebtables -A ... -i <tap interface name> ...).
It should be applicable to lx. LXC networking (http://lxc.sourceforge.net/network/configuration.php) can be setup using virtual interfaces and bridge.

I believe for VMware one would need to write a backend that can translate from
this xml to the VMware APIs. The xml spec can stay the same since as you
note it is derived from DMTF (and what is already supported in physical
switches).

Vivek
__

Vivek Kashyap
Linux Technology Center, IBM
Loading...