[Libvir] iptables masquerade rule overexpansive

On my system, libvirt-0.4.0-2ubuntu6 added the following rule to allow my virtual hosts NATted access to the outside world:
Chain POSTROUTING (policy ACCEPT 33904 packets, 2146K bytes) pkts bytes target prot opt in out source destination 779 102K MASQUERADE all -- * * 192.168.65.0/24 0.0.0.0/0
This resulted in *all* traffic being masqueraded, even between two different VMs -- preventing hostbased authentication between these VMs. To temporarily resolve this, I added an additional rule, as follows:
Chain POSTROUTING (policy ACCEPT 34049 packets, 2160K bytes) pkts bytes target prot opt in out source destination 156 9752 ACCEPT all -- * * 192.168.65.0/24 192.168.65.0/24 865 109K MASQUERADE all -- * * 192.168.65.0/24 0.0.0.0/0
The network definition being used was as follows:
<network> <name>default</name> <uuid>a7c5b18c-9d38-40ed-9b12-8b1a27013b85</uuid> <bridge name="virbr%d" /> <forward/> <ip address="192.168.65.253" netmask="255.255.255.0"/> </network>
I'm frankly unclear on why the packets attempted to forward through .253 in any event -- the routing tables on both VMs refer to 192.168.65.0/24 as part of the local network, so my expectation is that no attempt to route through the default gateway should have occurred. In any event, having libvirt extend the MASQUERADE rule to avoid impacting traffic between hosts on the virtual network -- or adding a paired ACCEPT, as I did above -- would probably be a Good Thing.

On Thu, Mar 27, 2008 at 01:23:25PM -0500, Charles Duffy wrote:
On my system, libvirt-0.4.0-2ubuntu6 added the following rule to allow my virtual hosts NATted access to the outside world:
Chain POSTROUTING (policy ACCEPT 33904 packets, 2146K bytes) pkts bytes target prot opt in out source destination 779 102K MASQUERADE all -- * * 192.168.65.0/24 0.0.0.0/0
This resulted in *all* traffic being masqueraded, even between two different VMs -- preventing hostbased authentication between these VMs. To temporarily resolve this, I added an additional rule, as follows:
Chain POSTROUTING (policy ACCEPT 34049 packets, 2160K bytes) pkts bytes target prot opt in out source destination 156 9752 ACCEPT all -- * * 192.168.65.0/24 192.168.65.0/24 865 109K MASQUERADE all -- * * 192.168.65.0/24 0.0.0.0/0
The network definition being used was as follows:
<network> <name>default</name> <uuid>a7c5b18c-9d38-40ed-9b12-8b1a27013b85</uuid> <bridge name="virbr%d" /> <forward/> <ip address="192.168.65.253" netmask="255.255.255.0"/> </network>
I'm frankly unclear on why the packets attempted to forward through .253 in any event -- the routing tables on both VMs refer to 192.168.65.0/24 as part of the local network, so my expectation is that no attempt to route through the default gateway should have occurred.
This is probably a result of the sysctl settings in the host. I imagine you have net.bridge.bridge-nf-call-iptables = 1 which will cause bridged traffic to be passed into iptables even though it is doing link layer bridging which would ordinarily only hit the ebtables filters.
In any event, having libvirt extend the MASQUERADE rule to avoid impacting traffic between hosts on the virtual network -- or adding a paired ACCEPT, as I did above -- would probably be a Good Thing.
Instead of having the separate ACCEPT rule I think it would be sufficient to replace the 0.0.0.0/0 target with ! 192.168.65.0/24, eg iptables -t nat -A POSTROUTING --source 192.168.65.0/24 --destination ! 192.168.65.0/24 -j MASQUERADE so it will masquerade traffic which is leaving the ip range of the virtual network only, and leave ip traffic between the VMs & VM<->host alone. Dan. -- |: Red Hat, Engineering, Boston -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Daniel P. Berrange wrote:
Instead of having the separate ACCEPT rule I think it would be sufficient to replace the 0.0.0.0/0 target with ! 192.168.65.0/24, eg
iptables -t nat -A POSTROUTING --source 192.168.65.0/24 --destination ! 192.168.65.0/24 -j MASQUERADE
so it will masquerade traffic which is leaving the ip range of the virtual network only, and leave ip traffic between the VMs & VM<->host alone.
I considered that -- but while it will work as long as the default forward rule is ACCEPT, it could result in hosts being unable to communicate with each other if the default rule for the table is otherwise. That said, it's certainly easier... patch attached.

On Thu, Mar 27, 2008 at 03:35:54PM -0500, Charles Duffy wrote:
Daniel P. Berrange wrote:
Instead of having the separate ACCEPT rule I think it would be sufficient to replace the 0.0.0.0/0 target with ! 192.168.65.0/24, eg
iptables -t nat -A POSTROUTING --source 192.168.65.0/24 --destination ! 192.168.65.0/24 -j MASQUERADE
so it will masquerade traffic which is leaving the ip range of the virtual network only, and leave ip traffic between the VMs & VM<->host alone.
I considered that -- but while it will work as long as the default forward rule is ACCEPT, it could result in hosts being unable to communicate with each other if the default rule for the table is otherwise.
The default rule shouldn't come into play, because we add explicit rules to allow direct guest<->guest and guest<->host traffic already 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 state 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 Regards, Dan. -- |: Red Hat, Engineering, Boston -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Thu, Mar 27, 2008 at 03:35:54PM -0500, Charles Duffy wrote:
Daniel P. Berrange wrote:
Instead of having the separate ACCEPT rule I think it would be sufficient to replace the 0.0.0.0/0 target with ! 192.168.65.0/24, eg
iptables -t nat -A POSTROUTING --source 192.168.65.0/24 --destination ! 192.168.65.0/24 -j MASQUERADE
so it will masquerade traffic which is leaving the ip range of the virtual network only, and leave ip traffic between the VMs & VM<->host alone.
I considered that -- but while it will work as long as the default forward rule is ACCEPT, it could result in hosts being unable to communicate with each other if the default rule for the table is otherwise.
That said, it's certainly easier... patch attached.
I've applied this patch to CVS, Regards, Dan. -- |: Red Hat, Engineering, Boston -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (2)
-
Charles Duffy
-
Daniel P. Berrange