[libvirt] Inbound NAT and iptables rules

Karl Vogel karl.vogel at gmail.com
Mon Feb 8 11:17:24 UTC 2010


This issue has been brought up a few times, but I haven't found any real 
solution yet. The problem is with the way libvirt adds iptables rules.

I have a KVM Host with 1 public IP address, on which a few virtual 
machines run. I want to be able to direct certain ports on the public IP 
to certain virtual machine's internal IP.

For example:

	allow conneciton to 'public-ip'  tcp port: 80 to 'vm1'

Which is possible using following rules:

$ iptables -I FORWARD 1 -d vm1 -p tcp --dport 80 -j ACCEPT
$ iptables -t nat -A PREROUTING -p tcp -d public-ip --dport 80 -j DNAT 
--to-destination vm1

However the problem is that libvirt _always_ adds it's rules to the top 
of the FORWARD rules, hence it blocks any 'custom' rules to the VM machines.


ie.

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source 
destination
    39  2964 ACCEPT     all  --  *      virbr0  0.0.0.0/0 
192.168.122.0/24    state RELATED,ESTABLISHED
    39  2964 ACCEPT     all  --  virbr0 *       192.168.122.0/24 
0.0.0.0/0
     2   656 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0 
0.0.0.0/0
     2   120 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

Only established connections are allowed with the libvirt rules, hence 
the forwarded connection to port 80 will be rejected by the 4th libvirt 
rule.

The only way to make it work is to insert the rule _after_ libvirt has 
started the network.. and if the libvirt network ever gets restarted, 
the rule will be disabled since libvirt inserts it's rules at the top of 
the chain.


Is there a proper way to achieve this with libvirt ?!




More information about the libvir-list mailing list