Service can't connect to self using public IP, NAT problem
With masquerade NAT (whether NAT in iptables or simple NAT in a consumer router/firewall) it's impossible to reach the external IP from the internal network. In this case, the address translation would end up with a packet with the same source and destination address, and would never make it back through the filter to have its' address translated back to the original inside IP.
I know it's not really a viable solution if you're using virtual networking internal to one machine, but I've generally gotten around this by using split-horizon DNS with NATed (internal) IPs for the inside view and the external IP for the outside view.
After a lot of reading and testing, I final found a solution, I have modified my iptables script to this:
#!/bin/sh
iptables -t nat -F
iptables -F
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P INPUT ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
iptables -A FORWARD -s 192.168.122.0/24 -j ACCEPT
iptables -A FORWARD -d 192.168.122.0/24 -j ACCEPT
iptables -A FORWARD -s ! 192.168.122.0/24 -j DROP
PORTS="22 25 110 143 587 993 995"
for port in $PORTS;
do
iptables -t nat -A PREROUTING -p tcp -d xx.xx.xx.189 --dport $port -j DNAT --to 192.168.122.2:$port
done
iptables -t nat -A POSTROUTING -s 192.168.122.2 -j SNAT --to xx.xx.xx.189
PORTS="22 80 443"
for port in $PORTS;
do
iptables -t nat -A PREROUTING -p tcp -d xx.xx.xx.173 --dport $port -j DNAT --to 192.168.122.3:$port
done
iptables -t nat -A POSTROUTING -s 192.168.122.3 -j SNAT --to xx.xx.xx.173
PORTS="22 3306 5432"
for port in $PORTS;
do
iptables -t nat -A PREROUTING -p tcp -d xx.xx.xx.174 --dport $port -j DNAT --to 192.168.122.4:$port
iptables -t nat -A PREROUTING -p udp -d xx.xx.xx.174 --dport $port -j DNAT --to 192.168.122.4:$port
done
iptables -t nat -A POSTROUTING -s 192.168.122.4 -j SNAT --to xx.xx.xx.174
What I have done is that I have added a -j SNAT
from their internal ip to their external ip.