mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-27 07:22:07 +03:00
5e760a91ab
This patch adds another example to the nwfilter html page and provides 2 solutions for how to write a filter meeting the given requirements using newly added features.
1785 lines
61 KiB
HTML
1785 lines
61 KiB
HTML
<html>
|
|
<body>
|
|
<h1>Network Filters</h1>
|
|
|
|
<ul id="toc">
|
|
</ul>
|
|
|
|
<p>
|
|
This page provides an introduction to libvirt's network filters,
|
|
their goals, concepts and XML format.
|
|
</p>
|
|
|
|
<h2><a name="goals">Goals and background</a></h2>
|
|
|
|
<p>
|
|
The goal of the network filtering XML is to enable administrators
|
|
of a virtualized system to configure and enforce network traffic
|
|
filtering rules on virtual
|
|
machines and manage the parameters of network traffic that
|
|
virtual machines
|
|
are allowed to send or receive.
|
|
The network traffic filtering rules are
|
|
applied on the host when a virtual machine is started. Since the
|
|
filtering rules
|
|
cannot be circumvented from within
|
|
the virtual machine, it makes them mandatory from the point of
|
|
view of a virtual machine user.
|
|
<br><br>
|
|
The network filter subsystem allows each virtual machine's network
|
|
traffic filtering rules to be configured individually on a per
|
|
interface basis. The rules are
|
|
applied on the host when the virtual machine is started and can be modified
|
|
while the virtual machine is running. The latter can be achieved by
|
|
modifying the XML description of a network filter.
|
|
<br><br>
|
|
Multiple virtual machines can make use of the same generic network filter.
|
|
When such a filter is modified, the network traffic filtering rules
|
|
of all running virtual machines that reference this filter are updated.
|
|
<br><br>
|
|
Network filtering support is available <span class="since">since 0.8.1
|
|
(Qemu, KVM)</span>
|
|
</p>
|
|
|
|
<h2><a name="nwfconcepts">Concepts</a></h2>
|
|
<p>
|
|
The network traffic filtering subsystem enables configuration
|
|
of network traffic filtering rules on individual network
|
|
interfaces that are configured for certain types of
|
|
network configurations. Supported network types are
|
|
</p>
|
|
<ul>
|
|
<li><code>network</code></li>
|
|
<li><code>ethernet</code> -- must be used in bridging mode</li>
|
|
<li><code>bridge</code></li>
|
|
<li><code>direct</code> -- only protocols mac, arp, ip and ipv6
|
|
can be filtered</li>
|
|
</ul>
|
|
<p>
|
|
The interface XML is used to reference a top-level filter. In the
|
|
following example, the interface description references
|
|
the filter <code>clean-traffic</code>.
|
|
</p>
|
|
<pre>
|
|
...
|
|
<devices>
|
|
<interface type='bridge'>
|
|
<mac address='00:16:3e:5d:c7:9e'/>
|
|
<filterref filter='clean-traffic'/>
|
|
</interface>
|
|
</devices>
|
|
...</pre>
|
|
|
|
<p>
|
|
Network filters are written in XML and may either contain references
|
|
to other filters, contain rules for traffic filtering, or
|
|
hold a combination of both. The above referenced filter
|
|
<code>clean-traffic </code> is a filter that only contains references to
|
|
other filters and no actual filtering rules. Since references to
|
|
other filters can be used, a <i>tree</i> of filters can be built.
|
|
The <code>clean-traffic</code> filter can be viewed using the
|
|
command <code>virsh nwfilter-dumpxml clean-traffic</code>.
|
|
<br><br>
|
|
As previously mentioned, a single network filter can be referenced
|
|
by multiple virtual machines. Since interfaces will typically
|
|
have individual parameters associated with their respective traffic
|
|
filtering rules, the rules described in a filter XML can
|
|
be parameterized with variables. In this case, the variable name
|
|
is used in the filter XML and the name and value are provided at the
|
|
place where the filter is referenced. In the
|
|
following example, the interface description has been extended with
|
|
the parameter <code>IP</code> and a dotted IP address as value.
|
|
</p>
|
|
<pre>
|
|
...
|
|
<devices>
|
|
<interface type='bridge'>
|
|
<mac address='00:16:3e:5d:c7:9e'/>
|
|
<filterref filter='clean-traffic'>
|
|
<parameter name='IP' value='10.0.0.1'/>
|
|
</filterref>
|
|
</interface>
|
|
</devices>
|
|
...</pre>
|
|
|
|
<p>
|
|
In this particular example, the <code>clean-traffic</code> network
|
|
traffic filter will be instantiated with the IP address parameter
|
|
10.0.0.1 and enforce that the traffic from this interface will
|
|
always be using 10.0.0.1 as the source IP address, which is
|
|
one of the purposes of this particular filter.
|
|
<br><br>
|
|
</p>
|
|
|
|
<h3><a name="nwfconceptsvars">Usage of variables in filters</a></h3>
|
|
<p>
|
|
|
|
Two variables names have so far been reserved for usage by the
|
|
network traffic filtering subsystem: <code>MAC</code> and
|
|
<code>IP</code>.
|
|
<br><br>
|
|
<code>MAC</code> is the MAC address of the
|
|
network interface. A filtering rule that references this variable
|
|
will automatically be instantiated with the MAC address of the
|
|
interface. This works without the user having to explicitly provide
|
|
the MAC parameter. Even though it is possible to specify the MAC
|
|
parameter similar to the IP parameter above, it is discouraged
|
|
since libvirt knows what MAC address an interface will be using.
|
|
<br><br>
|
|
The parameter <code>IP</code> represents the IP address
|
|
that the operating system inside the virtual machine is expected
|
|
to use on the given interface. The <code>IP</code> parameter
|
|
is special in so far as the libvirt daemon will try to determine
|
|
the IP address (and thus the IP parameter's value) that is being
|
|
used on an interface if the parameter
|
|
is not explicitly provided but referenced.
|
|
For current limitations on IP address detection, consult the
|
|
<a href="#nwflimits">section on limitations</a> on how to use this
|
|
feature and what to expect when using it.
|
|
<br><br>
|
|
The following is the XML description of the network filer
|
|
<code>no-arp-spoofing</code>. It serves as an example for
|
|
a network filter XML referencing the <code>MAC</code> and
|
|
<code>IP</code> parameters. This particular filter is referenced by the
|
|
<code>clean-traffic</code> filter.
|
|
</p>
|
|
<pre>
|
|
<filter name='no-arp-spoofing' chain='arp'>
|
|
<uuid>f88f1932-debf-4aa1-9fbe-f10d3aa4bc95</uuid>
|
|
<rule action='drop' direction='out' priority='300'>
|
|
<mac match='no' srcmacaddr='$MAC'/>
|
|
</rule>
|
|
<rule action='drop' direction='out' priority='350'>
|
|
<arp match='no' arpsrcmacaddr='$MAC'/>
|
|
</rule>
|
|
<rule action='drop' direction='out' priority='400'>
|
|
<arp match='no' arpsrcipaddr='$IP'/>
|
|
</rule>
|
|
<rule action='drop' direction='in' priority='450'>
|
|
<arp opcode='Reply'/>
|
|
<arp match='no' arpdstmacaddr='$MAC'/>
|
|
</rule>
|
|
<rule action='drop' direction='in' priority='500'>
|
|
<arp match='no' arpdstipaddr='$IP'/>
|
|
</rule>
|
|
<rule action='accept' direction='inout' priority='600'>
|
|
<arp opcode='Request'/>
|
|
</rule>
|
|
<rule action='accept' direction='inout' priority='650'>
|
|
<arp opcode='Reply'/>
|
|
</rule>
|
|
<rule action='drop' direction='inout' priority='1000'/>
|
|
</filter>
|
|
</pre>
|
|
|
|
<p>
|
|
Note that referenced variables are always prefixed with the
|
|
$ (dollar) sign. The format of the value of a variable
|
|
must be of the type expected by the filter attribute in the
|
|
XML. In the above example, the <code>IP</code> parameter
|
|
must hold a dotted IP address in decimal numbers format.
|
|
Failure to provide the correct
|
|
value type will result in the filter not being instantiatable
|
|
and will prevent a virtual machine from starting or the
|
|
interface from attaching when hotplugging is used. The types
|
|
that are expected for each XML attribute are shown
|
|
below.
|
|
</p>
|
|
|
|
<h2><a name="nwfelems">Element and attribute overview</a></h2>
|
|
|
|
<p>
|
|
The root element required for all network filters is
|
|
named <code>filter</code> with two possible attributes. The
|
|
<code>name</code> attribute provides a unique name of the
|
|
given filter. The <code>chain</code> attribute is optional but
|
|
allows certain filters to be better organized for more efficient
|
|
processing by the firewall subsystem of the underlying host.
|
|
Currently the system only supports the chains <code>root,
|
|
ipv4, ipv6, arp and rarp</code>.
|
|
</p>
|
|
|
|
<h3><a name="nwfelemsRefs">References to other filters</a></h3>
|
|
<p>
|
|
Any filter may hold references to other filters. Individual
|
|
filters may be referenced multiple times in a filter tree but
|
|
references between filters must not introduce loops (directed
|
|
acyclic graph).
|
|
<br><br>
|
|
The following shows the XML of the <code>clean-traffic</code>
|
|
network filter referencing several other filters.
|
|
</p>
|
|
<pre>
|
|
<filter name='clean-traffic'>
|
|
<uuid>6ef53069-ba34-94a0-d33d-17751b9b8cb1</uuid>
|
|
<filterref filter='no-mac-spoofing'/>
|
|
<filterref filter='no-ip-spoofing'/>
|
|
<filterref filter='allow-incoming-ipv4'/>
|
|
<filterref filter='no-arp-spoofing'/>
|
|
<filterref filter='no-other-l2-traffic'/>
|
|
<filterref filter='qemu-announce-self'/>
|
|
</filter>
|
|
</pre>
|
|
|
|
<p>
|
|
To reference another filter, the XML node <code>filterref</code>
|
|
needs to be provided inside a <code>filter</code> node. This
|
|
node must have the attribute <code>filter</code> whose value contains
|
|
the name of the filter to be referenced.
|
|
<br><br>
|
|
New network filters can be defined at any time and
|
|
may contain references to network filters that are
|
|
not known to libvirt, yet. However, once a virtual machine
|
|
is started or a network interface
|
|
referencing a filter is to be hotplugged, all network filters
|
|
in the filter tree must be available. Otherwise the virtual
|
|
machine will not start or the network interface cannot be
|
|
attached.
|
|
</p>
|
|
|
|
<h3><a name="nwfelemsRules">Filter rules</a></h3>
|
|
<p>
|
|
The following XML shows a simple example of a network
|
|
traffic filter implementing a rule to drop traffic if
|
|
the IP address (provided through the value of the
|
|
variable IP) in an outgoing IP packet is not the expected
|
|
one, thus preventing IP address spoofing by the VM.
|
|
</p>
|
|
<pre>
|
|
<filter name='no-ip-spoofing' chain='ipv4'>
|
|
<uuid>fce8ae33-e69e-83bf-262e-30786c1f8072</uuid>
|
|
<rule action='drop' direction='out' priority='500'>
|
|
<ip match='no' srcipaddr='$IP'/>
|
|
</rule>
|
|
</filter>
|
|
</pre>
|
|
|
|
<p>
|
|
A traffic filtering rule starts with the <code>rule</code>
|
|
node. This node may contain up to three attributes
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
action -- mandatory; must either be <code>drop</code> or <code>accept</code> if
|
|
the evaluation of the filtering rule is supposed to drop or accept
|
|
a packet
|
|
</li>
|
|
<li>
|
|
direction -- mandatory; must either be <code>in</code>, <code>out</code> or
|
|
<code>inout</code> if the rule is for incoming,
|
|
outgoing or incoming-and-outgoing traffic
|
|
</li>
|
|
<li>
|
|
priority -- optional; the priority of the rule controls the order in
|
|
which the rule will be instantiated relative to other rules.
|
|
Rules with lower value will be instantiated and therefore evaluated
|
|
before rules with higher value.
|
|
Valid values are in the range of 0 to 1000. If this attribute is not
|
|
provided, the value 500 will automatically be assigned.
|
|
</li>
|
|
<li>
|
|
statematch -- optional; possible values are '0' or 'false' to
|
|
turn the underlying connection state matching off; default is 'true'
|
|
<br>
|
|
Also read the section on <a href="#nwfelemsRulesAdv">advanced configuration</a>
|
|
topics.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
The above example indicates that the traffic of type <code>ip</code>
|
|
will be asscociated with the chain 'ipv4' and the rule will have
|
|
priority 500. If for example another filter is referenced whose
|
|
traffic of type <code>ip</code> is also associated with the chain
|
|
'ipv4' then that filter's rules will be ordered relative to the priority
|
|
500 of the shown rule.
|
|
<br><br>
|
|
A rule may contain a single rule for filtering of traffic. The
|
|
above example shows that traffic of type <code>ip</code> is to be
|
|
filtered.
|
|
</p>
|
|
|
|
<h4><a name="nwfelemsRulesProto">Supported protocols</a></h4>
|
|
<p>
|
|
The following sections enumerate the list of protocols that
|
|
are supported by the network filtering subsystem. The
|
|
type of traffic a rule is supposed to filter on is provided
|
|
in the <code>rule</code> node as a nested node. Depending
|
|
on the traffic type a rule is filtering, the attributes are
|
|
different. The above example showed the single
|
|
attribute <code>srcipaddr</code> that is valid inside the
|
|
<code>ip</code> traffic filtering node. The following sections
|
|
show what attributes are valid and what type of data they are
|
|
expecting. The following datatypes are available:
|
|
</p>
|
|
<ul>
|
|
<li>UINT8 : 8 bit integer; range 0-255</li>
|
|
<li>UINT16: 16 bit integer; range 0-65535</li>
|
|
<li>MAC_ADDR: MAC adrress in dotted decimal format, i.e., 00:11:22:33:44:55</li>
|
|
<li>MAC_MASK: MAC address mask in MAC address format, i.e., FF:FF:FF:FC:00:00</li>
|
|
<li>IP_ADDR: IP address in dotted decimal format, i.e., 10.1.2.3</li>
|
|
<li>IP_MASK: IP address mask in either dotted decimal format (255.255.248.0) or CIDR mask (0-32)</li>
|
|
<li>IPV6_ADDR: IPv6 address in numbers format, i.e., FFFF::1</li>
|
|
<li>IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR mask (0-128)</li>
|
|
<li>STRING: A string</li>
|
|
</ul>
|
|
<p>
|
|
<br><br>
|
|
Every attribute except for those of type IP_MASK or IPV6_MASK can
|
|
be negated using the <code>match</code>
|
|
attribute with value <code>no</code>. Multiple negated attributes
|
|
may be grouped together. The following
|
|
XML fragment shows such an example using abstract attributes.
|
|
</p>
|
|
<pre>
|
|
[...]
|
|
<rule action='drop' direction='in'>
|
|
<protocol match='no' attribute1='value1' attribute2='value2'/>
|
|
<protocol attribute3='value3'/>
|
|
</rule>
|
|
[...]
|
|
</pre>
|
|
<p>
|
|
Rules perform a logical AND evaluation on all values of the given
|
|
protocol attributes. Thus, if a single attribute's value does not match
|
|
the one given in the rule, the whole rule will be skipped during
|
|
evaluation. Therefore, in the above example incoming traffic
|
|
will only be dropped if
|
|
the protocol property attribute1 does not match value1 AND
|
|
the protocol property attribute2 does not match value2 AND
|
|
the protocol property attribute3 matches value3.
|
|
<br><br>
|
|
</p>
|
|
|
|
|
|
<h5><a name="nwfelemsRulesProtoMAC">MAC (Ethernet)</a></h5>
|
|
<p>
|
|
Protocol ID: <code>mac</code>
|
|
<br>
|
|
Note: Rules of this type should go into the <code>root</code> chain.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>protocolid</td>
|
|
<td>UINT16 (0x600-0xffff), STRING</td>
|
|
<td>Layer 3 protocol ID</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
Valid Strings for <code>protocolid</code> are: arp, rarp, ipv4, ipv6
|
|
</p>
|
|
<pre>
|
|
[...]
|
|
<mac match='no' srcmacaddr='$MAC'/>
|
|
[...]
|
|
</pre>
|
|
|
|
<h5><a name="nwfelemsRulesProtoARP">ARP/RARP</a></h5>
|
|
<p>
|
|
Protocol ID: <code>arp</code> or <code>rarp</code>
|
|
<br>
|
|
Note: Rules of this type should either go into the
|
|
<code>root</code> or <code>arp/rarp</code> chain.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>hwtype</td>
|
|
<td>UINT16</td>
|
|
<td>Hardware type</td>
|
|
</tr>
|
|
<tr>
|
|
<td>protocoltype</td>
|
|
<td>UINT16</td>
|
|
<td>Protocol type</td>
|
|
</tr>
|
|
<tr>
|
|
<td>opcode</td>
|
|
<td>UINT16, STRING</td>
|
|
<td>Opcode</td>
|
|
</tr>
|
|
<tr>
|
|
<td>arpsrcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>Source MAC address in ARP/RARP packet</td>
|
|
</tr>
|
|
<tr>
|
|
<td>arpdstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>Destination MAC address in ARP/RARP packet</td>
|
|
</tr>
|
|
<tr>
|
|
<td>arpsrcipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Source IP address in ARP/RARP packet</td>
|
|
</tr>
|
|
<tr>
|
|
<td>arpdstipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Destination IP address in ARP/RARP packet</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
Valid strings for the <code>Opcode</code> field are:
|
|
Request, Reply, Request_Reverse, Reply_Reverse, DRARP_Request,
|
|
DRARP_Reply, DRARP_Error, InARP_Request, ARP_NAK
|
|
<br><br>
|
|
</p>
|
|
|
|
<h5><a name="nwfelemsRulesProtoIP">IPv4</a></h5>
|
|
<p>
|
|
Protocol ID: <code>ip</code>
|
|
Note: Rules of this type should either go into the
|
|
<code>root</code> or <code>ipv4</code> chain.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>protocol</td>
|
|
<td>UINT8, STRING</td>
|
|
<td>Layer 4 protocol identifier</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid source ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid source ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid destination ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid destination ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
Valid strings for <code>protocol</code> are:
|
|
tcp, udp, udplite, esp, ah, icmp, igmp, sctp
|
|
<br><br>
|
|
</p>
|
|
|
|
|
|
<h5><a name="nwfelemsRulesProtoIPv6">IPv6</a></h5>
|
|
<p>
|
|
Protocol ID: <code>ipv6</code>
|
|
Note: Rules of this type should either go into the
|
|
<code>root</code> or <code>ipv6</code> chain.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Destination IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to destination IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>protocol</td>
|
|
<td>UINT8</td>
|
|
<td>Layer 4 protocol identifier</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid source ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid source ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid destination ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid destination ports; requires <code>protocol</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
Valid strings for <code>protocol</code> are:
|
|
tcp, udp, udplite, esp, ah, icmpv6, sctp
|
|
<br><br>
|
|
</p>
|
|
|
|
<h5><a name="nwfelemsRulesProtoTCP-ipv4">TCP/UDP/SCTP</a></h5>
|
|
<p>
|
|
Protocol ID: <code>tcp</code>, <code>udp</code>, <code>sctp</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid source ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid source ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid destination ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid destination ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
|
|
<h5><a name="nwfelemsRulesProtoICMP">ICMP</a></h5>
|
|
<p>
|
|
Protocol ID: <code>icmp</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>type</td>
|
|
<td>UINT16</td>
|
|
<td>ICMP type</td>
|
|
</tr>
|
|
<tr>
|
|
<td>code</td>
|
|
<td>UINT16</td>
|
|
<td>ICMP code</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
<h5><a name="nwfelemsRulesProtoMisc">IGMP, ESP, AH, UDPLITE, 'ALL'</a></h5>
|
|
<p>
|
|
Protocol ID: <code>igmp</code>, <code>esp</code>, <code>ah</code>, <code>udplite</code>, <code>all</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstmacmask</td>
|
|
<td>MAC_MASK</td>
|
|
<td>Mask applied to MAC address of destination</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IP_MASK</td>
|
|
<td>Mask applied to destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IP_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IP_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
|
|
<h5><a name="nwfelemsRulesProtoTCP-ipv6">TCP/UDP/SCTP over IPV6</a></h5>
|
|
<p>
|
|
Protocol ID: <code>tcp-ipv6</code>, <code>udp-ipv6</code>, <code>sctp-ipv6</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid source ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid source ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportstart</td>
|
|
<td>UINT16</td>
|
|
<td>Start of range of valid destination ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstportend</td>
|
|
<td>UINT16</td>
|
|
<td>End of range of valid destination ports</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
|
|
<h5><a name="nwfelemsRulesProtoICMPv6">ICMPv6</a></h5>
|
|
<p>
|
|
Protocol ID: <code>icmpv6</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Destination IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to destination IPv6 address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>type</td>
|
|
<td>UINT16</td>
|
|
<td>ICMPv6 type</td>
|
|
</tr>
|
|
<tr>
|
|
<td>code</td>
|
|
<td>UINT16</td>
|
|
<td>ICMPv6 code</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
<h5><a name="nwfelemsRulesProtoMiscv6">IGMP, ESP, AH, UDPLITE, 'ALL' over IPv6</a></h5>
|
|
<p>
|
|
Protocol ID: <code>igmp-ipv6</code>, <code>esp-ipv6</code>, <code>ah-ipv6</code>, <code>udplite-ipv6</code>, <code>all-ipv6</code>
|
|
<br>
|
|
Note: The chain parameter is ignored for this type of traffic
|
|
and should either be omitted or set to <code>root</code>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Attribute </th>
|
|
<th> Datatype </th>
|
|
<th> Semantics </th>
|
|
</tr>
|
|
<tr>
|
|
<td>srcmacaddr</td>
|
|
<td>MAC_ADDR</td>
|
|
<td>MAC address of sender</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to source IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipaddr</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Destination IPv6 address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipmask</td>
|
|
<td>IPV6_MASK</td>
|
|
<td>Mask applied to destination IPv6 address</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>srcipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>srcipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of source IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipfrom</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>Start of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>dstipto</td>
|
|
<td>IPV6_ADDR</td>
|
|
<td>End of range of destination IP address</td>
|
|
</tr>
|
|
<tr>
|
|
<td>comment <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>text with max. 256 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td>state <span class="since">(Since 0.8.5)</span></td>
|
|
<td>STRING</td>
|
|
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
<br><br>
|
|
</p>
|
|
|
|
<h3><a name="nwfelemsRulesAdv">Advanced Filter Configuration Topics</a></h3>
|
|
<p>
|
|
The following sections discuss advanced filter configuration
|
|
topics.
|
|
</p>
|
|
<h4><a name="nwfelemsRulesAdvTracking">Connection tracking</a></h4>
|
|
<p>
|
|
The network filtering subsystem (on Linux) makes use of the connection
|
|
tracking support of iptables. This helps in enforcing the
|
|
directionality of network traffic (state match) as well as
|
|
counting and limiting the number of simultaneous connections towards
|
|
a VM. As an example, if a VM has TCP port 8080
|
|
open as a server, clients may connect to the VM on port 8080.
|
|
Connection tracking and enforcement of directionality then prevents
|
|
the VM from initiating a connection from
|
|
(TCP client) port 8080 to the host back to a remote host.
|
|
More importantly, tracking helps to prevent
|
|
remote attackers from establishing a connection back to a VM. For example,
|
|
if the user inside the VM established a connection to
|
|
port 80 on an attacker site, then the attacker will not be able to
|
|
initiate a connection from TCP port 80 back towards the VM.
|
|
By default the connection state match that enables connection tracking
|
|
and then enforcement of directionality of traffic is turned on. <br>
|
|
The following shows an example XML fragement where this feature has been
|
|
turned off for incoming connections to TCP port 12345.
|
|
</p>
|
|
<pre>
|
|
[...]
|
|
<rule direction='in' action='accept' statematch='false'>
|
|
<tcp dstportstart='12345'/>
|
|
</rule>
|
|
[...]
|
|
</pre>
|
|
<p>
|
|
This now allows incoming traffic to TCP port 12345, but would also
|
|
enable the initiation from (client) TCP port 12345 within the VM,
|
|
which may or may not be desirable.
|
|
</p>
|
|
|
|
<h4><a name="nwfelemsRulesAdvLimiting">Limiting Number of Connections</a></h4>
|
|
<p>
|
|
To limit the number of connections a VM may establish, a rule must
|
|
be provided that sets a limit of connections for a given
|
|
type of traffic. If for example a VM
|
|
is supposed to be allowed to only ping one other IP address at a time
|
|
and is supposed to have only one active incoming ssh connection at a
|
|
time, the following XML fragment can be used to achieve this.
|
|
</p>
|
|
<pre>
|
|
[...]
|
|
<rule action='drop' direction='in' priority='400'>
|
|
<tcp connlimit-above='1'/>
|
|
</rule>
|
|
<rule action='accept' direction='in' priority='500'>
|
|
<tcp dstportstart='22'/>
|
|
</rule>
|
|
<rule action='drop' direction='out' priority='400'>
|
|
<icmp connlimit-above='1'/>
|
|
</rule>
|
|
<rule action='accept' direction='out' priority='500'>
|
|
<icmp/>
|
|
</rule>
|
|
<rule action='accept' direction='out' priority='500'>
|
|
<udp dstportstart='53'/>
|
|
</rule>
|
|
<rule action='drop' direction='inout' priority='1000'>
|
|
<all/>
|
|
</rule>
|
|
[...]
|
|
</pre>
|
|
<p>
|
|
Note that the rule for the limit has to logically appear
|
|
before the rule for accepting the traffic.<br>
|
|
An additional rule for letting DNS traffic to port 22
|
|
go out the VM has been added to avoid ssh sessions not
|
|
getting established for reasons related to DNS lookup failures
|
|
by the ssh daemon. Leaving this rule out may otherwise lead to
|
|
fun-filled debugging joy (symptom: ssh client seems to hang
|
|
while trying to connect).
|
|
<br><br>
|
|
Lot of care must be taken with timeouts related
|
|
to tracking of traffic. An ICMP ping that
|
|
the user may have terminated inside the VM may have a long
|
|
timeout in the host's connection tracking system and therefore
|
|
not allow another ICMP ping to go through for a while. Therefore,
|
|
the timeouts have to be tuned in the host's sysfs, i.e.,
|
|
</p>
|
|
|
|
<pre>
|
|
echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
|
|
</pre>
|
|
<p>
|
|
sets the ICMP connection tracking timeout to 3 seconds. The
|
|
effect of this is that once one ping is terminated, another
|
|
one can start after 3 seconds.<br>
|
|
Further, we want to point out that a client that for whatever
|
|
reason has not properly closed a TCP connection may cause a
|
|
connection to be held open for a longer period of time,
|
|
depending to what timeout the <code>TCP established</code> state
|
|
timeout has been set to on the host. Also, idle connections may time
|
|
out in the connection tracking system but can be reactivated once
|
|
packets are exchanged. However, a newly initiated connection may force
|
|
an idle connection into TCP backoff if the number of allowed connections
|
|
is set to a too low limit, the new connection is established
|
|
and hits (not exceeds) the limit of allowed connections and for
|
|
example a key is pressed on the old ssh session, which now has become
|
|
unresponsive due to its traffic being dropped.
|
|
Therefore, the limit of connections should be rather high so that
|
|
fluctuations in new TCP connections don't cause odd
|
|
traffic behavior in relaton to idle connections.
|
|
</p>
|
|
|
|
<h2><a name="nwfcli">Command line tools</a></h2>
|
|
<p>
|
|
The libvirt command line tool <code>virsh</code> has been extended
|
|
with life-cycle support for network filters. All commands related
|
|
to the network filtering subsystem start with the prefix
|
|
<code>nwfilter</code>. The following commands are available:
|
|
<p>
|
|
<ul>
|
|
<li>nwfilter-list : list UUIDs and names of all network filters</li>
|
|
<li>nwfilter-define : define a new network filter or update an existing one</li>
|
|
<li>nwfilter-undefine : delete a network filter given its name; it must not be currently in use</li>
|
|
<li>nwfilter-dumpxml : display a network filter given its name</li>
|
|
<li>nwfilter-edit : edit a network filter given its name</li>
|
|
</ul>
|
|
|
|
<h2><a name="nwfexamples">Pre-existing network filters</a></h2>
|
|
<p>
|
|
The following is a list of example network filters that are
|
|
automatically installed with libvirt.</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Name </th>
|
|
<th> Description </th>
|
|
</tr>
|
|
<tr>
|
|
<td> no-arp-spoofing </td>
|
|
<td> Prevent a VM from spoofing ARP traffic; this filter
|
|
only allows ARP request and reply messages and enforces
|
|
that those packets contain the MAC and IP addresses
|
|
of the VM.</td>
|
|
</tr>
|
|
<tr>
|
|
<td> allow-dhcp </td>
|
|
<td> Allow a VM to request an IP address via DHCP (from any
|
|
DHCP server)</td>
|
|
</tr>
|
|
<tr>
|
|
<td> allow-dhcp-server </td>
|
|
<td> Allow a VM to request an IP address from a specified
|
|
DHCP server. The dotted decimal IP address of the DHCP
|
|
server must be provided in a reference to this filter.
|
|
The name of the variable must be <i>DHCPSERVER</i>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td> no-ip-spoofing </td>
|
|
<td> Prevent a VM from sending of IP packets with
|
|
a source IP address different from the one
|
|
in the packet. </td>
|
|
</tr>
|
|
<tr>
|
|
<td> no-ip-multicast </td>
|
|
<td> Prevent a VM from sending IP multicast packets. </td>
|
|
</tr>
|
|
<tr>
|
|
<td> clean-traffic </td>
|
|
<td> Prevent MAC, IP and ARP spoofing. This filter references
|
|
several other filters as building blocks. </td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
Note that most of the above filters are only building blocks and
|
|
require a combination with other filters to provide useful network
|
|
traffic filtering.
|
|
The most useful one in the above list is the <i>clean-traffic</i>
|
|
filter. This filter itself can for example be combined with the
|
|
<i>no-ip-multicast</i>
|
|
filter to prevent virtual machines from sending IP multicast traffic
|
|
on top of the prevention of packet spoofing.
|
|
</p>
|
|
|
|
<h2><a name="nwfwrite">Writing your own filters</a></h2>
|
|
|
|
<p>
|
|
Since libvirt only provides a couple of example networking filters, you
|
|
may consider writing your own. When planning on doing so
|
|
there are a couple of things
|
|
you may need to know regarding the network filtering subsystem and how
|
|
it works internally. Certainly you also have to know and understand
|
|
the protocols very well that you want to be filtering on so that
|
|
no further traffic than what you want can pass and that in fact the
|
|
traffic you want to allow does pass.
|
|
<br><br>
|
|
The network filtering subsystem is currently only available on
|
|
Linux hosts and only works for Qemu and KVM type of virtual machines.
|
|
On Linux
|
|
it builds upon the support for <code>ebtables</code>, <code>iptables
|
|
</code> and <code>ip6tables</code> and makes use of their features.
|
|
From the above list of supported protocols the following ones are
|
|
implemented using <code>ebtables</code>:
|
|
</p>
|
|
<ul>
|
|
<li>mac</li>
|
|
<li>arp, rarp</li>
|
|
<li>ip</li>
|
|
<li>ipv6</li>
|
|
</uL>
|
|
|
|
<p>
|
|
All other protocols over IPv4 are supported using iptables, those over
|
|
IPv6 are implemented using ip6tables.
|
|
<br><br>
|
|
On a Linux host, all traffic filtering instantiated by libvirt's network
|
|
filter subsystem first passes through the filtering support implemented
|
|
by ebtables and only then through iptables or ip6tables filters. If
|
|
a filter tree has rules with the protocols <code>mac</code>,
|
|
<code>arp</code>, <code>rarp</code>, <code>ip</code>, or <code>ipv6</code>
|
|
ebtables rules will automatically be instantiated.
|
|
<br>
|
|
The role of the <code>chain</code> attribute in the network filter
|
|
XML is that internally a new user-defined ebtables table is created
|
|
that then for example receives all <code>arp</code> traffic coming
|
|
from or going to a virtual machine, if the chain <code>arp</code>
|
|
has been specified. Further, a rule is generated in an interface's
|
|
<code>root</code> chain that directs all ipv4 traffic into the
|
|
user-defined chain. Therefore, all ARP traffic rules should then be
|
|
placed into filters specifying this chain. This type of branching
|
|
into user-defined tables is only supported with filtering on the ebtables
|
|
layer.
|
|
<br>
|
|
As an example, it is
|
|
possible to filter on UDP traffic by source and destination ports using
|
|
the <code>ip</code> protocol filter and specifying attributes for the
|
|
protocol, source and destination IP addresses and ports of UDP packets
|
|
that are to be accepted. This allows
|
|
early filtering of UDP traffic with ebtables. However, once an IP or IPv6
|
|
packet, such as a UDP packet,
|
|
has passed the ebtables layer and there is at least one rule in a filter
|
|
tree that instantiates iptables or ip6tables rules, a rule to let
|
|
the UDP packet pass will also be necessary to be provided for those
|
|
filtering layers. This can be
|
|
achieved with a rule containing an approriate <code>udp</code> or
|
|
<code>udp-ipv6</code> traffic filtering node.
|
|
</p>
|
|
|
|
<h3><a name="nwfwriteexample">Example custom filter</a></h3>
|
|
<p>
|
|
As an example we want to now build a filter that fulfills the following
|
|
list of requirements:
|
|
</p>
|
|
<ul>
|
|
<li>prevents a VM's interface from MAC, IP and ARP spoofing</li>
|
|
<li>opens only TCP ports 22 and 80 of a VM's interface</li>
|
|
<li>allows the VM to send ping traffic from an interface
|
|
but not let the VM be pinged on the interface</li>
|
|
<li>allows the VM to do DNS lookups (UDP towards port 53)</li>
|
|
</ul>
|
|
<p>
|
|
The requirement to prevent spoofing is fulfilled by the existing
|
|
<code>clean-traffic</code> network filter, thus we will reference this
|
|
filter from our custom filter.
|
|
<br>
|
|
To enable traffic for TCP ports 22 and 80 we will add 2 rules to
|
|
enable this type of traffic. To allow the VM to send ping traffic
|
|
we will add a rule for ICMP traffic. For simplicity reasons
|
|
we allow general ICMP traffic to be initated from the VM, not
|
|
just ICMP echo request and response messages. To then
|
|
disallow all other traffic to reach or be initated by the
|
|
VM we will then need to add a rule that drops all other traffic.
|
|
Assuming our VM is called <i>test</i> and
|
|
the interface we want to associate our filter with is called <i>eth0</i>,
|
|
we name our filter <i>test-eth0</i>.
|
|
The result of these considerations is the following network filter XML:
|
|
</p>
|
|
<pre>
|
|
<filter name='test-eth0'>
|
|
<!-- reference the clean traffic filter to prevent
|
|
MAC, IP and ARP spoofing. By not providing
|
|
and IP address parameter, libvirt will detect the
|
|
IP address the VM is using. -->
|
|
<filterref filter='clean-traffic'/>
|
|
|
|
<!-- enable TCP ports 22 (ssh) and 80 (http) to be reachable -->
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='22'/>
|
|
</rule>
|
|
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='80'/>
|
|
</rule>
|
|
|
|
<!-- enable general ICMP traffic to be initiated by the VM;
|
|
this includes ping traffic -->
|
|
<rule action='accept' direction='out'>
|
|
<icmp/>
|
|
</rule>
|
|
|
|
<!-- enable outgoing DNS lookups using UDP -->
|
|
<rule action='accept' direction='out'>
|
|
<udp dstportstart='53'/>
|
|
</rule>
|
|
|
|
<!-- drop all other traffic -->
|
|
<rule action='drop' direction='inout'>
|
|
<all/>
|
|
</rule>
|
|
|
|
</filter>
|
|
</pre>
|
|
<p>
|
|
Note that none of the rules in the above XML contain the
|
|
IP address of the VM as either source or destination address, yet
|
|
the filtering of the traffic works correctly. The reason is that
|
|
the evaluation of the rules internally happens on a
|
|
per-interface basis and the rules are evaluated based on the knowledge
|
|
about which (tap) interface has sent or will receive the packet rather
|
|
than what their source or destination IP address may be.
|
|
<br><br>
|
|
An XML fragment for a possible network interface description inside
|
|
the domain XML of the <code>test</code> VM could then look like this:
|
|
</p>
|
|
<pre>
|
|
[...]
|
|
<interface type='bridge'>
|
|
<source bridge='mybridge'/>
|
|
<filterref filter='test-eth0'/>
|
|
</interface>
|
|
[...]
|
|
</pre>
|
|
|
|
<p>
|
|
To more strictly control the ICMP traffic and enforce that only
|
|
ICMP echo requests can be sent from the VM
|
|
and only ICMP echo responses be received by the VM, the above
|
|
<code>ICMP</code> rule can be replaced with the following two rules:
|
|
</p>
|
|
<pre>
|
|
<!-- enable outgoing ICMP echo requests-->
|
|
<rule action='accept' direction='out'>
|
|
<icmp type='8'/>
|
|
</rule>
|
|
|
|
<!-- enable incoming ICMP echo replies-->
|
|
<rule action='accept' direction='in'>
|
|
<icmp type='0'/>
|
|
</rule>
|
|
</pre>
|
|
|
|
<h3><a name="nwfwriteexample2nd">Second example custom filter</a></h3>
|
|
<p>
|
|
In this example we now want to build a similar filter as in the
|
|
example above, but extend the list of requirements with an
|
|
ftp server located inside the VM. Further, we will be using features
|
|
that have been added in <span class="since">version 0.8.5</span>.
|
|
The requirements for this filter are:
|
|
</p>
|
|
<ul>
|
|
<li>prevents a VM's interface from MAC, IP and ARP spoofing</li>
|
|
<li>opens only TCP ports 22 and 80 of a VM's interface</li>
|
|
<li>allows the VM to send ping traffic from an interface
|
|
but not let the VM be pinged on the interface</li>
|
|
<li>allows the VM to do DNS lookups (UDP towards port 53)</li>
|
|
<li>enable an ftp server (in active mode) to be run inside the VM
|
|
</ul>
|
|
<p>
|
|
The additional requirement of allowing an ftp server to be run inside
|
|
the VM maps into the requirement of allowing port 21 to be reachable
|
|
for ftp control traffic as well as enabling the VM to establish an
|
|
outgoing tcp connection originating from the VM's TCP port 20 back to
|
|
the ftp client (ftp active mode). There are several ways of how this
|
|
filter can be written and we present 2 solutions.
|
|
<br><br>
|
|
The 1st solution makes use of the <code>state</code> attribute of
|
|
the TCP protocol that gives us a hook into the connection tracking
|
|
framework of the Linux host. For the VM-initiated ftp data connection
|
|
(ftp active mode) we use the <code>RELATED</code> state that allows
|
|
us to detect that the VM-initiated ftp data connection is a consequence of
|
|
( or 'has a relationship with' ) an existing ftp control connection,
|
|
thus we want to allow it to let packets
|
|
pass the firewall. The <code>RELATED</code> state, however, is only
|
|
valid for the very first packet of the outgoing TCP connection for the
|
|
ftp data path. Afterwards, the state to compare against is
|
|
<code>ESTABLISHED</code>, which then applies equally
|
|
to the incoming and outgoing direction. All this is related to the ftp
|
|
data traffic originating from TCP port 20 of the VM. This then leads to
|
|
the following solution
|
|
<span class="since">(since 0.8.5 (Qemu, KVM, UML))</span>:
|
|
</p>
|
|
<pre>
|
|
<filter name='test-eth0'>
|
|
<!-- reference the clean traffic filter to prevent
|
|
MAC, IP and ARP spoofing. By not providing
|
|
and IP address parameter, libvirt will detect the
|
|
IP address the VM is using. -->
|
|
<filterref filter='clean-traffic'/>
|
|
|
|
<!-- enable TCP port 21 (ftp-control) to be reachable -->
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='21'/>
|
|
</rule>
|
|
|
|
<!-- enable TCP port 20 for VM-initiated ftp data connection
|
|
related to an existing ftp control connection -->
|
|
<rule action='accept' direction='out'>
|
|
<tcp srcportstart='20' state='RELATED,ESTABLISHED'/>
|
|
</rule>
|
|
|
|
<!-- accept all packets from client on the ftp data connection -->
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='20' state='ESTABLISHED'/>
|
|
</rule>
|
|
|
|
<!-- enable TCP ports 22 (ssh) and 80 (http) to be reachable -->
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='22'/>
|
|
</rule>
|
|
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='80'/>
|
|
</rule>
|
|
|
|
<!-- enable general ICMP traffic to be initiated by the VM;
|
|
this includes ping traffic -->
|
|
<rule action='accept' direction='out'>
|
|
<icmp/>
|
|
</rule>
|
|
|
|
<!-- enable outgoing DNS lookups using UDP -->
|
|
<rule action='accept' direction='out'>
|
|
<udp dstportstart='53'/>
|
|
</rule>
|
|
|
|
<!-- drop all other traffic -->
|
|
<rule action='drop' direction='inout'>
|
|
<all/>
|
|
</rule>
|
|
|
|
</filter>
|
|
</pre>
|
|
<p>
|
|
Before trying out a filter using the <code>RELATED</code> state,
|
|
you have to make sure that the approriate connection tracking module
|
|
has been loaded into the host's kernel. Depending on the version of the
|
|
kernel, you must run either one of the following two commands before
|
|
the ftp connection with the VM is established.
|
|
</p>
|
|
<pre>
|
|
modprobe nf_conntrack_ftp # where available or
|
|
|
|
modprobe ip_conntrack_ftp # if above is not available
|
|
</pre>
|
|
<p>
|
|
If other protocols than ftp are to be used in conjunction with the
|
|
<code>RELATED</code> state, their corresponding module must be loaded.
|
|
Modules exist at least for the protocols ftp, tftp, irc, sip,
|
|
sctp, and amanda.
|
|
</p>
|
|
<p>
|
|
The 2nd solution makes uses the state flags of connections more
|
|
than the previous solution did.
|
|
In this solution we take advantage of the fact that the
|
|
<code>NEW</code> state of a connection is valid when the very
|
|
first packet of a traffic flow is seen. Subsequently, if the very first
|
|
packet of a flow is accepted, the flow becomes a connection and enters
|
|
the <code>ESTABLISHED</code> state. This allows us to write a general
|
|
rule for allowing packets of <code>ESTABLISHED</code> connections to
|
|
reach the VM or be sent by the VM.
|
|
We write specific rules for the very first packets identified by the
|
|
<code>NEW</code> state and for which ports they are acceptable. All
|
|
packets for ports that are not explicitly accepted will be dropped and
|
|
therefore the connection will not go into the <code>ESTABLISHED</code>
|
|
state and any subsequent packets be dropped.
|
|
</p>
|
|
|
|
<pre>
|
|
<filter name='test-eth0'>
|
|
<!-- reference the clean traffic filter to prevent
|
|
MAC, IP and ARP spoofing. By not providing
|
|
and IP address parameter, libvirt will detect the
|
|
IP address the VM is using. -->
|
|
<filterref filter='clean-traffic'/>
|
|
|
|
<!-- let the packets of all previously accepted connections reach the VM -->
|
|
<rule action='accept' direction='in'>
|
|
<all state='ESTABLISHED'/>
|
|
</rule>
|
|
|
|
<!-- let the packets of all previously accepted and related connections be sent from the VM -->
|
|
<rule action='accept' direction='out'>
|
|
<all state='ESTABLISHED,RELATED'/>
|
|
</rule>
|
|
|
|
<!-- enable traffic towards port 21 (ftp), 22 (ssh) and 80 (http) -->
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='21' dstportend='22' state='NEW'/>
|
|
</rule>
|
|
|
|
<rule action='accept' direction='in'>
|
|
<tcp dstportstart='80' state='NEW'/>
|
|
</rule>
|
|
|
|
<!-- enable general ICMP traffic to be initiated by the VM;
|
|
this includes ping traffic -->
|
|
<rule action='accept' direction='out'>
|
|
<icmp state='NEW'/>
|
|
</rule>
|
|
|
|
<!-- enable outgoing DNS lookups using UDP -->
|
|
<rule action='accept' direction='out'>
|
|
<udp dstportstart='53' state='NEW'/>
|
|
</rule>
|
|
|
|
<!-- drop all other traffic -->
|
|
<rule action='drop' direction='inout'>
|
|
<all/>
|
|
</rule>
|
|
|
|
</filter>
|
|
|
|
</pre>
|
|
|
|
<h2><a name="nwflimits">Limitations</a></h2>
|
|
<p>
|
|
The following sections list (current) limitations of the network
|
|
filtering subsystem.
|
|
</p>
|
|
|
|
<h3><a name="nwflimitsIP">IP Address Detection</a></h3>
|
|
<p>
|
|
In case a network filter references the variable
|
|
<i>IP</i> and no variable was defined in any higher layer
|
|
references to the filter, IP address detection will automatically
|
|
be started when the filter is to be instantiated (VM start, interface
|
|
hotplug event). Only IPv4
|
|
addresses can be detected and only a single IP address
|
|
legitimately in use by a VM on a single interface will be detected.
|
|
In case a VM was to use multiple IP address on a single interface
|
|
(IP aliasing),
|
|
the IP addresses would have to be provided explicitly either
|
|
in the network filter itself or as variables used in attributes'
|
|
values. These
|
|
variables must then be defined in a higher level reference to the filter
|
|
and each assigned the value of the IP address that the VM is expected
|
|
to be using.
|
|
Different IP addresses in use by multiple interfaces of a VM
|
|
(one IP address each) will be independently detected.
|
|
<br><br>
|
|
Once a VM's IP address has been detected, its IP network traffic
|
|
may be locked to that address, if for example IP address spoofing
|
|
is prevented by one of its filters. In that case the user of the VM
|
|
will not be able to change the IP address on the interface inside
|
|
the VM, which would be considered IP address spoofing.
|
|
<br><br>
|
|
In case a VM is resumed after suspension or migrated, IP address
|
|
detection will be restarted.
|
|
</p>
|
|
|
|
<h3><a name="nwflimitsmigr">VM Migration</a></h3>
|
|
<p>
|
|
VM migration is only supported if the whole filter tree
|
|
that is referenced by a virtual machine's top level filter
|
|
is also available on the target host. The network filter
|
|
<i>clean-traffic</i>
|
|
for example should be available on all libvirt installations
|
|
of version 0.8.1 or later and thus enable migration of VMs that
|
|
for example reference this filter. All other
|
|
custom filters must be migrated using higher layer software. It is
|
|
outside the scope of libvirt to ensure that referenced filters
|
|
on the source system are equivalent to those on the target system
|
|
and vice versa.
|
|
<br><br>
|
|
Migration must occur between libvirt insallations of version
|
|
0.8.1 or later in order not to lose the network traffic filters
|
|
associated with an interface.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|