
Hi Dan, On Thu, 2007-04-05 at 02:44 +0100, Daniel P. Berrange wrote:
Warning, this is a long & complicated email with lots of horrible details :-)
I've long been a little confused with the way iptables & bridging interacts, so set out to do some experiments. I added a -j LOG rule to every single chain in both the filter & nat tables, and then tried various traffic patterns, to see which chains were traversed & in which order.
Nice work ...
Scenario 2: Virtual network ===========================
net.bridge.bridge-nf-call-iptables = 1
Host: eth0 -> Internet virbr0 -> MASQUERADE to eth0
Guest: vif1.0 -> virbr0
Traffic: Guest -> Google ------------------------
Out:
NAT-PREROUTING IN=virbr0 OUT= PHYSIN=vif1.0 SRC=192.168.122.47 DST=64.233.167.99 FORWARD IN=virbr0 OUT=eth0 PHYSIN=vif1.0 SRC=192.168.122.47 DST=64.233.167.99 NAT-POSTROUTING IN= OUT=eth0 PHYSIN=vif1.0 SRC=192.168.122.47 DST=64.233.167.99
This really suprises me - I would have expected another one like: FORWARD IN=virbr0 OUT=virbr0 PHYSIN=vif1.0 PHYSOUT=virb0 SRC=192.168.122.47 DST=64.233.167.99 Is it because the packets are coming in on bridge interface we don't see any physdev matching? So, we would see it with Guest->Guest?
For virtual networks there are basically 3 types of networking config we need to represent in terms of iptables rules, and these need to work for scenrios 1 & 2 - ie regardless of the magic sysctl knob.
Well, IMHO, we should never be switching off the sysctl knob ourselves - i.e. we shouldn't have it in xen/scripts/network-bridge - but I take the point that a user might switch it off.
Problem: The INPUT rules are missing altogether for the isolated virtual network so potentially DHCP/DNS will be blocked Solution: Add them - simple bug.
I fixed this in CVS, didn't I?
Problem: The POSTROUTING rule is too generic so it matches pretty much any kind of traffic, from any virtual network, or even from VPN devices setup by VPNC. Solution: Only masquerade traffic whose source address is within the netmask associated with the virtual network in question
Problem: The FORWARD rule is too generic, forwarding traffic to/from the virtual network regardless of whether the dest/src IP address is within the netmask associated with the virtual network. Assuming the first problem is setup to only masquerade valid IP addresses from the virtual network, this rule would then allow guests to spoof their IP and have it forwarded off-host. Solution: Only forward packets whose IP address is within the netmask associated with the virtual network
Problem: The policy of the FORWARD rule is ACCEPT, and/or later user defined rules may inadvertently match on traffic from the virtual network, again allowing through spoof traffic, or traffic from what should be an isolated virtual network Solution: There needs to be a catch-all REJECT rule associated with every bridge device, in both directions
Problem: There is an extra physdev match per bridge device, and per guest device. This is basically unneccessary since the previous rule sets will already have allowed through the traffic. The physdev matches also only work if net.bridge.bridge-nf-call-iptables = 1 Solution: Simply remove the per-device matches
Problem: The POSTROUTING rule has a physdev match applied, which only works if net.bridge.bridge-nf-call-iptables = 1. Solution: Remove physdev match & masquerade based on network address associated with the virtual network
I guess the two main differences are 1) avoid physdev based rules because they don't work with net.bridge.bridge-nf-call-iptables = 1 and 2) use network address based rules which I avoided because of pure superstition and the feeling that IP based matching on a bridge was just ugly. I haven't spent long thinking about these changes, but on the face of it they all look well thought out and sensible. Definitely worth giving it a shot. Cheers, Mark.