4

I have a dedicated server from serverloft.eu, but due to some network security I cannot use bridge networking on my server. So I have setup all my IPs to the main eth0, and used NAT to forward trafic from the main eth0 to the internal network. But I have encounted a problem, services on my virtual servers cannot connect to itself using the public ip, ie. telnet 192.168.122.3 80 works fine, but telnet pub.lic.ip.xx 80 times out. (When entered on the virual machine with ip 192.168.122.3)

My iptables script looks like this:

#!bin/sh

iptables -F

iptables -t nat -F

iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

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

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

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

What am I missing?

3 Answers 3

3

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.

1

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.

1
  • There's a mistake on the MASQUARADE line, instead of -d ! it should be ! -d.
    – Tombart
    Mar 17, 2016 at 23:52
0

A better solution would be to write a rule that rewrite the public IP address (x.x.x.x) to localhost:

iptables -t nat -A OUTPUT -d x.x.x.x/32 -p tcp -m tcp --dport 80 \
         -j DNAT --to-destination 127.0.0.1:80

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .