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