У меня есть выделенный сервер от serverloft.eu, но из-за некоторой сетевой безопасности я не могу использовать мостовую сеть на моем сервере. Итак, я настроил все свои IP-адреса на основной eth0 и использовал NAT для пересылки трафика с основного eth0 во внутреннюю сеть. Но у меня возникла проблема, службы на моих виртуальных серверах не могут подключиться к себе с помощью общедоступного IP-адреса, т.е. telnet 192.168.122.3 80 работает нормально, но telnet pub.lic.ip.xx 80 раз. (При входе на виртуальную машину с ip 192.168.122.3)
Мой скрипт iptables выглядит так:
#!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
Что мне не хватает?
С маскирующим NAT (будь то NAT в iptables или простой NAT в пользовательском маршрутизаторе / брандмауэре) невозможно получить доступ к внешнему IP из внутренней сети. В этом случае преобразование адресов закончится пакетом с тем же адресом источника и назначения и никогда не вернется через фильтр, чтобы его адрес был преобразован обратно в исходный внутренний IP-адрес.
Я знаю, что это не совсем жизнеспособное решение, если вы используете виртуальную сеть внутри одной машины, но я обычно обходил это, используя DNS с разделенным горизонтом с NAT (внутренними) IP-адресами для внутреннего обзора и внешним IP-адресом для внешний вид.
После долгого чтения и тестирования я наконец нашел решение, я изменил свой скрипт iptables на это:
#!/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
Что я сделал, так это то, что я добавил -j SNAT
со своего внутреннего IP на внешний.
Лучшим решением было бы написать правило, которое перезаписывает общедоступный IP-адрес (x.x.x.x
) на 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