
With fragments borrowed from David Steven's previous submission and some further modifications: A set of modifications to existing filters to handle multiple IP addresses (and MAC addresses) per interface. Also: - enable DHCP traffic from VM to any DHCP server - will require an update to a libvirt-tck data file Signed-off-by: David L Stevens <dlstevens@us.ibm.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> --- examples/xml/nwfilter/Makefile.am | 2 + examples/xml/nwfilter/clean-traffic.xml | 12 +++++++- examples/xml/nwfilter/no-arp-ip-spoofing.xml | 9 ++++++ examples/xml/nwfilter/no-arp-mac-spoofing.xml | 7 ++++ examples/xml/nwfilter/no-arp-spoofing.xml | 38 ++------------------------ examples/xml/nwfilter/no-ip-spoofing.xml | 17 ++++++++--- examples/xml/nwfilter/no-mac-spoofing.xml | 11 +++++-- 7 files changed, 52 insertions(+), 44 deletions(-) Index: libvirt-acl/examples/xml/nwfilter/Makefile.am =================================================================== --- libvirt-acl.orig/examples/xml/nwfilter/Makefile.am +++ libvirt-acl/examples/xml/nwfilter/Makefile.am @@ -9,6 +9,8 @@ FILTERS = \ allow-ipv4.xml \ clean-traffic.xml \ no-arp-spoofing.xml \ + no-arp-ip-spoofing.xml \ + no-arp-mac-spoofing.xml \ no-ip-multicast.xml \ no-ip-spoofing.xml \ no-mac-broadcast.xml \ Index: libvirt-acl/examples/xml/nwfilter/no-arp-ip-spoofing.xml =================================================================== --- /dev/null +++ libvirt-acl/examples/xml/nwfilter/no-arp-ip-spoofing.xml @@ -0,0 +1,9 @@ +<filter name='no-arp-ip-spoofing' chain='arp-ip' priority='-510'> + <!-- no arp spoofing --> + <!-- drop if ipaddr does not belong to guest --> + <rule action='return' direction='out' priority='400' > + <arp match='yes' arpsrcipaddr='$IP' /> + </rule> + <!-- drop everything else --> + <rule action='drop' direction='out' priority='1000' /> +</filter> Index: libvirt-acl/examples/xml/nwfilter/no-arp-mac-spoofing.xml =================================================================== --- /dev/null +++ libvirt-acl/examples/xml/nwfilter/no-arp-mac-spoofing.xml @@ -0,0 +1,7 @@ +<filter name='no-arp-mac-spoofing' chain='arp-mac' priority='-520'> + <rule action='return' direction='out' priority='350' > + <arp match='yes' arpsrcmacaddr='$MAC'/> + </rule> + <!-- drop everything else --> + <rule action='drop' direction='out' priority='1000' /> +</filter> Index: libvirt-acl/examples/xml/nwfilter/clean-traffic.xml =================================================================== --- libvirt-acl.orig/examples/xml/nwfilter/clean-traffic.xml +++ libvirt-acl/examples/xml/nwfilter/clean-traffic.xml @@ -1,4 +1,4 @@ -<filter name='clean-traffic'> +<filter name='clean-traffic' chain='root'> <!-- An example of a traffic filter enforcing clean traffic from a VM by - preventing MAC spoofing --> @@ -6,11 +6,21 @@ <!-- preventing IP spoofing on outgoing, allow all IPv4 in incoming --> <filterref filter='no-ip-spoofing'/> + + <rule direction='out' action='accept' priority='-650'> + <mac protocolid='ipv4'/> + </rule> + <filterref filter='allow-incoming-ipv4'/> <!-- preventing ARP spoofing/poisoning --> <filterref filter='no-arp-spoofing'/> + <!-- accept all other incoming and outgoing ARP traffic --> + <rule action='accept' direction='inout' priority='-500'> + <mac protocolid='arp'/> + </rule> + <!-- preventing any other traffic than IPv4 and ARP --> <filterref filter='no-other-l2-traffic'/> Index: libvirt-acl/examples/xml/nwfilter/no-mac-spoofing.xml =================================================================== --- libvirt-acl.orig/examples/xml/nwfilter/no-mac-spoofing.xml +++ libvirt-acl/examples/xml/nwfilter/no-mac-spoofing.xml @@ -1,5 +1,10 @@ -<filter name='no-mac-spoofing' chain='ipv4'> - <rule action='drop' direction='out' priority='10'> - <mac match='no' srcmacaddr='$MAC' /> +<filter name='no-mac-spoofing' chain='mac' priority='-800'> + <!-- return packets with VM's MAC address as source address --> + <rule direction='out' action='return'> + <mac srcmacaddr='$MAC'/> + </rule> + <!-- drop everything else --> + <rule direction='out' action='drop'> + <mac/> </rule> </filter> Index: libvirt-acl/examples/xml/nwfilter/no-arp-spoofing.xml =================================================================== --- libvirt-acl.orig/examples/xml/nwfilter/no-arp-spoofing.xml +++ libvirt-acl/examples/xml/nwfilter/no-arp-spoofing.xml @@ -1,36 +1,4 @@ -<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> - - <!-- no arp spoofing --> - <!-- drop if ipaddr or macaddr does not belong to guest --> - <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> - <!-- allow gratuitous arp --> - <rule action='accept' direction='in' priority='425'> - <arp gratuitous='true'/> - </rule> - <!-- drop if ipaddr or macaddr does not belong to guest --> - <rule action='drop' direction='in' priority='450' > - <arp match='no' arpdstmacaddr='$MAC'/> - <arp opcode='reply'/> - </rule> - <rule action='drop' direction='in' priority='500' > - <arp match='no' arpdstipaddr='$IP' /> - </rule> - <!-- accept only request or reply packets --> - <rule action='accept' direction='inout' priority='600' > - <arp opcode='request'/> - </rule> - <rule action='accept' direction='inout' priority='650' > - <arp opcode='reply'/> - </rule> - <!-- drop everything else --> - <rule action='drop' direction='inout' priority='1000' /> +<filter name='no-arp-spoofing' chain='root'> + <filterref filter='no-arp-mac-spoofing'/> + <filterref filter='no-arp-ip-spoofing'/> </filter> Index: libvirt-acl/examples/xml/nwfilter/no-ip-spoofing.xml =================================================================== --- libvirt-acl.orig/examples/xml/nwfilter/no-ip-spoofing.xml +++ libvirt-acl/examples/xml/nwfilter/no-ip-spoofing.xml @@ -1,7 +1,14 @@ -<filter name='no-ip-spoofing' chain='ipv4'> +<filter name='no-ip-spoofing' chain='ipv4-ip' priority='-710'> + <!-- allow DHCP requests --> + <rule action='accept' direction='out' priority='100'> + <ip srcipaddr='0.0.0.0' protocol='udp' srcportstart='68' srcportend='68'/> + </rule> - <!-- drop if srcipaddr is not the IP address of the guest --> - <rule action='drop' direction='out'> - <ip match='no' srcipaddr='$IP' /> - </rule> + <!-- allow all known IP addresses --> + <rule direction='out' action='return' priority='500'> + <ip srcipaddr='$IP'/> + </rule> + + <!-- drop everything else --> + <rule direction='out' action='drop' priority='1000'/> </filter>