Hello, The iptables MASQUERADE target's source address selection doesn't work for overlapping networks on an interface. The real-world scenario behind this case is a VPN tunnel set up using racoon in a roadwarrior scenario. The VPN gateway offers a dynamic tunnel IP via ISAKMP mode config which is then added to the outgoing interface (typically PPP or something like that). Routing selects the tunnel IP as source address for secure subnets and IPsec policies are applied then. This works - until MASQUERADE enters the game. Test case: # ip addr add 10.0.0.1/16 dev dummy0 # ip addr add 10.0.1.1/24 dev dummy0 # ip link set dummy0 up # ip route show dev dummy0 10.0.1.0/24 proto kernel scope link src 10.0.1.1 10.0.0.0/16 proto kernel scope link src 10.0.0.1 # ping -c1 10.0.0.2 -> tcpdump: IP 10.0.0.1 > 10.0.0.2: ICMP echo request # ping -c1 10.0.1.2 -> tcpdump: IP 10.0.1.1 > 10.0.1.2: ICMP echo request # iptables -t nat -A POSTROUTING -o dummy0 -j MASQUERADE # ping -c1 10.0.0.2 -> tcpdump: IP 10.0.0.1 > 10.0.0.2: ICMP echo request # ping -c1 10.0.1.2 -> tcpdump: IP 10.0.0.1 > 10.0.1.2: ICMP echo request This is due to masquerade_tg() not considering routing decisions. This is fine with non-overlapping networks. In this case, inet_select_addr() is sufficient. With overlapping networks inet_select_addr() is not sufficient, because it just selects the first matching address, while the correct source address can only be retrieved from routing. regards Mario -- Good, Fast, Cheap: Pick any two (you can't have all three). -- RFC 1925, 7a
Attachment:
signature.asc
Description: Digital signature