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.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
docs/formatnwfilter.html.in | 180
+++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 179 insertions(+), 1 deletion(-)
Index: libvirt-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/docs/formatnwfilter.html.in
@@ -1468,7 +1468,8 @@
<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 no let the VM be pinged on the interface</li>
+ 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
@@ -1510,6 +1511,11 @@
<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/>
@@ -1556,6 +1562,178 @@
</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 shall be:
+ </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-initated 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 origination 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>