Iptables – How to setup IPTables on KVM host – iptables-persistent is being ignored

iptableskvm-virtualizationlibvirtnetworking

I'm trying to setup some specific IPTables rules on an ubuntu 14.04.1 host that runs some KVM guests.

The box has multiple NICs with multiple IP addresses and the guests use different addresses based on their function.

I normally use iptables-persistent to achieve this, but for some reason, the rules under /etc/iptables/rules.v4 are not being loaded at boot time. iptables-persistent works correctly when libvirt is not installed.

If I run '/etc/init.d/iptables-persistent start' then the rules are loaded and the setup is as I expect. But at boot they are not. I've tried creating a very simple rules.v4 file to debug this, but it is still not loaded.

The init symlink for iptables-persistent exists at /etc/rc2.d/S37iptables-persistent

I have confirmed that ufw is disabled. I have also removed the nwfilter rules from /etc/libvirt/nwfilter and virsh nwfilter-list does not display any entries.

Any idea what else might be setting these rules and how I customise them as I want them ?

ufw status output

# ufw status
Status: inactive

virsh nwfilter-list output

# virsh nwfilter-list
 UUID                                  Name                 
------------------------------------------------------------------

contents of /etc/iptables/rules.v4

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LOG_AND_DROP - [0:0]
-A INPUT -s 192.168.10.0/24 -i br0 -j ACCEPT
-A INPUT -s 192.168.11.0/24 -i br0 -j ACCEPT
-A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7
-A LOG_AND_DROP -j DROP
COMMIT

output of iptables -L -n after boot (unwanted result)

# iptables -L -n -v
Chain INPUT (policy ACCEPT 12 packets, 912 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67
    0     0 ACCEPT     udp  --  tunnelbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  tunnelbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 ACCEPT     udp  --  tunnelbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
    0     0 ACCEPT     tcp  --  tunnelbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67
    0     0 ACCEPT     udp  --  mgmtbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  mgmtbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 ACCEPT     udp  --  mgmtbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
    0     0 ACCEPT     tcp  --  mgmtbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67
  193 17300 ACCEPT     all  --  br0    *       192.168.10.0/24      0.0.0.0/0           
    0     0 ACCEPT     all  --  br0    *       192.168.11.0/24      0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.122.0/24     ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  virbr0 *       192.168.122.0/24     0.0.0.0/0           
    0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  tunnelbr0 tunnelbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      tunnelbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  tunnelbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  mgmtbr0 mgmtbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      mgmtbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  mgmtbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 132 packets, 17456 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            udp dpt:68
    0     0 ACCEPT     udp  --  *      tunnelbr0  0.0.0.0/0            0.0.0.0/0            udp dpt:68
    0     0 ACCEPT     udp  --  *      mgmtbr0  0.0.0.0/0            0.0.0.0/0            udp dpt:68

Chain LOG_AND_DROP (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 7 prefix "iptables deny: "
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0 

Output of iptables -L -n -v after running /etc/init.d/iptables-persistent start (expected result)

# iptables -L -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   13   920 ACCEPT     all  --  br0    *       192.168.10.0/24      0.0.0.0/0           
    0     0 ACCEPT     all  --  br0    *       192.168.11.0/24      0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 8 packets, 1104 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain LOG_AND_DROP (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 7 prefix "iptables deny: "
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Best Answer

All of the "extra" rules you are seeing were added by the libvirt daemon to support (and secure) virtual networking for your virtual machine guests. You generally do not need to worry about these rules (and should not try to persist them, as then they would be duplicated at next boot).

It's also clear that all of your persistent firewall rules were added to the firewall.

It was between difficult and impossible to discern either of these facts without that critical -v switch for the `iptables command.