1

I have a server acting as host (KVM), proxy and firewall. In order to access the services provided by the virtual machines in this host, iptables must work in order to redirect the packets properly to the guests.

The problem comes when the server shuts down (i.e.: restart or power loss). When the server starts again, ports redirections seems to be not working (i.e.: can not SSH to the guests machines or access their services using the redirected ports from the host).

At that moment, I can SSH to the host and verify iptables is running. However, I need to service iptables restart for everything to work as expected.

Why is this happening? Is it related to the use of KVM? How could I avoid having to manually restart iptables each time the server goes down?

Notice how I do not need to change iptables configuration in order to make everything work as expected, I only need to restart the service (as if the configuration was not applied properly or overwritten at some point).

UPDATE

On the host:

# chkconfig --list iptables
0:off   1:off   2:on    3:on    4:on    5:on    6:off

Comparing iptables rules before and after restarting the service:

  • The PREROUTING chain looks exactly the same.
  • The INPUT chain looks very similar. The only difference is that before restarting, there are some duplicated entries, but the order of the entries is similar as well.
  • The POSTROUTING chain looks very similar. The only difference is that before restarting, there are some duplicated entries, but the order of the entries is similar as well.
  • The FORWARD chain chain looks more different. There are some duplicated entries before restarting the service, but, the order of the entries changes before and after.

Here are the differences (the PREROUTING chain has been excluded because it looked exactly the same before and after restarting iptables):

Before

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  tcp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  udp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  all  --  10.0.0.0/24         !10.0.0.0/24        
MASQUERADE  tcp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  udp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  all  --  10.0.0.0/24         !10.0.0.0/24        

Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:53
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:67
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:67
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:53
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:67
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:67
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:3300
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:4333
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            10.0.0.0/24         state RELATED,ESTABLISHED
ACCEPT     all  --  10.0.0.0/24          0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
ACCEPT     all  --  0.0.0.0/0            10.0.0.0/24         state NEW,RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            10.0.0.0/24         state RELATED,ESTABLISHED
ACCEPT     all  --  10.0.0.0/24          0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

AFTER

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  tcp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  udp  --  10.0.0.0/24         !10.0.0.0/24         masq ports: 1024-65535
MASQUERADE  all  --  10.0.0.0/24         !10.0.0.0/24        

Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:53
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:67
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:67
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:3300
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:4333
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            10.0.0.0/24         state NEW,RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            10.0.0.0/24         state RELATED,ESTABLISHED
ACCEPT     all  --  10.0.0.0/24          0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
2
  • What does chkconfig --list iptables say?
    – John
    Feb 3, 2015 at 13:34
  • 1
    I'm betting the KVM startup scripts rewrite the iptables rules, then. What do the rules look like before you restart iptables after a server restart?
    – John
    Feb 3, 2015 at 13:40

2 Answers 2

0

Is there any chance that you are using some other script inside the file '/etc/network/interfaces' on the line "post-up iptables-restore < /etc/iptables.up.rules"

1
  • Nope. My system has other configuration files (CentOS), but grepped through all /etc/ with no success finding similar lines.
    – Peque
    Feb 4, 2015 at 10:45
0

My virtual machines use NAT networking and a virtual network controlled by libvirt, so libvirt tries to change the iptables rules to send the right traffic to the right VM but, apparently, it doesn't work properly.

Basically, libvirt is adding rules to iptables after iptables has already loaded its configuration.

Quick, dirty hack

Simple, and functional:

echo "service iptables restart" >> /etc/rc.d/rc.local

The /etc/rc.d/rc.local will be executed after all the other init scripts.

Other options (just ideas)

  • A solution may be to use libvirt "hook" scripts that can be used to do a slightly better job (see libvirt and network filtering with nat - iptables overrides).
  • Redoing the network so it doesn't use NAT (this isn't really a solution, it just means changing the server architecture).
  • Updating the server to CentOS 7 (now it uses CentOS 6) may help as well (using firewalld).

Any help extending this answer with more detailed solutions (steps to follow) or new options will be still appreciated.

Thanks to TrevorH and the people at #centos (freenode) for their kind help.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .