Red Hat Bugzilla – Bug 812441
Libvirt with NAT setup nukes port forwarding into the internal network
Last modified: 2016-04-26 10:51:26 EDT
I have a host setup with one guest, setup with NAT networking. Host has public IP, guest has private (192.168.122.10, fixed).
I have $PUBLIC:80 -> 192.168.122.10:80 DNAT.
Part of /etc/sysconfig/iptables:
-A PREROUTING -p tcp -i eth0 -d $PUBLIC_IP --dport 80 -j DNAT --to 192.168.122.10:80
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -p tcp -i eth0 -d 192.168.122.10 --dport 80 -j ACCEPT
-A FORWARD -p tcp -i eth0 -d 192.168.122.10 --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
Forwarding works, but after I start libvirtd, the last reject rule gets put in from of my forwarding rules:
[firstname.lastname@example.org ~]# iptables -L FORWARD -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any virbr0 anywhere 192.168.122.0/24 state RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 any 192.168.122.0/24 anywhere
0 0 ACCEPT all -- virbr0 virbr0 anywhere anywhere
0 0 REJECT all -- any virbr0 anywhere anywhere reject-with icmp-port-unreachable
^^^ THIS RULE KILLS ALL FORWARDING TRAFFIC ^^^
0 0 REJECT all -- virbr0 any anywhere anywhere reject-with icmp-port-unreachable
1 48 ACCEPT tcp -- eth0 any anywhere dev-virt-1 tcp dpt:http
1 60 ACCEPT tcp -- eth0 any anywhere dev-virt-1 tcp dpt:ssh
^^^^ THESE ARE MY FORWARDING RULES THAT GET IGNORED ^^^
Perhaps libvirt should append instead of insert? libvirt-0.9.4-23.el6_2.7.x86_64
(In reply to comment #0)
> Perhaps libvirt should append instead of insert?
If libvirt were to append instead of insert, a *large* number of installations would lose network connectivity on their next update, because libvirt's rules would suddenly be behind system-wide rules that overrode them.
It's an unfortunate fact of the current state of iptables management that there is no central controlling authority that coordinates which rules are placed before/after which other rules. The firewalld (http://fedoraproject.org/wiki/FirewallD/) project is trying to remedy this, but I haven't heard of any plans to try and get it into RHEL6.
Strictly from the point of view of libvirt config (regardless of the underlying implementation), I think the proper way to solve this type of problem is for libvirt's nwfilter to support "port-forward" rules that will end up putting the necessary DNAT and ACCEPT rules into iptables at the appropriate place whenever the guest is started. nwfilter already does this for standard ACCEPT rules.
There's a proposal upstream to add a <forward> element to interfaces that use qemu's "user mode" networking (in this case, the port to be forwarded, and port to forward to, etc, are all just added to the qemu commandline):
We may be able to use the same XML as an indicator to write iptables NAT rules for the guest. Of course it would be nice if we didn't need to know the guest's IP address beforehand, but that would require using the new dhcp snooping support, and I think that may only be usable from within nwfilter.
Reporter is gone, and this isn't causing many other complaints, so just closing. There's enough other network stuff that needs handling :)