Iptables – Simultaneous iptables POSTROUTING for SNAT and MASQUERADE block outgoing ssh

iptables

I am using iptables on a virtualized host to distribute services using one IP to different virtual machines(VMs). This works well with DNAT in PREROUTING and SNAT in POSTROUTING. Furthermore I am able to access the internet from the virtual machine by using MASQUERADE in the POSTROUTING.

My problems start, if I try to use ssh from a VM that provides the webserver and has SNAT configured for packets coming from this VM. It only works, once I disable SNAT.

Is it possible to limit SNAT to replies to external request (eg. webserver requests, incoming FTP or DNS) while masquerading traffic originating from the VM? Interestingly, simple things like wget from the VM work correctly.

The relevant part from iptables:

:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -p tcp -s 192.168.x.y -o xenbr1 -j SNAT --to a.b.c.d
-A POSTROUTING -p udp -s 192.168.x.y -o xenbr1 -j SNAT --to a.b.c.d
-A POSTROUTING -s 192.168.0.0/255.255.0.0 -j MASQUERADE

Best Answer

Replace

-A POSTROUTING -s 192.168.0.0/255.255.0.0 -j MASQUERADE

With

-A POSTROUTING -s 192.168.0.0/255.255.0.0 -o <internet interface> -j MASQUERADE

in the configuration. This makes sure that only packets routed to the outgoing interface of dom0 will be masqueraded.