Имею тестовую коробку VDS с реальным IP. Если я запускаю веб-сервер на физическом порте интерфейса 80, его можно открыть с другого компьютера через его IP-адрес (и порт по умолчанию 80):
python -m SimpleHTTPServer 80
Но если я попытаюсь перенаправить порт 80 с физического интерфейса eth0
к порту 8080 loopback 127.0.0.1 я могу подключить его с другого компьютера к порту 8080, но не могу подключиться к порту 80, это просто бесконечное «соединение». Похоже, перенаправления не происходит:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8080
python -m SimpleHTTPServer 8080
Что я делаю не так? :(
P.S. Сервер привязки к 127.0.0.1:8080 дает тот же результат, но это не имеет значения, поскольку сервер, работающий на 0.0.0.0:8080, будет принимать соединение, перенаправленное на 127.0.0.1:8080. НАСКОЛЬКО МНЕ ИЗВЕСТНО. :(
iptables -L
результат:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
iptables -t nat -L
результат:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:http to:127.0.0.1:8080
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
netstat -nlp
результат:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 676/sshd
tcp6 0 0 :::22 :::* LISTEN 676/sshd
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] STREAM LISTENING 7964 600/acpid /var/run/acpid.socket
unix 2 [ ACC ] STREAM LISTENING 6590 1/init @/com/ubuntu/upstart
unix 2 [ ACC ] SEQPACKET LISTENING 6760 231/udevd /run/udev/control
unix 2 [ ACC ] STREAM LISTENING 7030 345/dbus-daemon /var/run/dbus/system_bus_socket
ifconfig -a
результат:
eth0 Link encap:Ethernet HWaddr 00:16:3e:da:1a:98
inet addr:5.14.223.181 Bcast:5.14.223.255 Mask:255.255.255.0
inet6 addr: fe80::140:3eff:febe:201a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:371264 errors:0 dropped:59 overruns:0 frame:0
TX packets:2093 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:17377545 (17.3 MB) TX bytes:214428 (214.4 KB)
Interrupt:25
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:10 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:552 (552.0 B) TX bytes:552 (552.0 B)
Просто замените свое правило этим.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Он должен работать. Это перенаправит весь ваш 80-портовый трафик с eth0 на 8080-порт localhost, на котором вы запускаете tomcat.
Еще один способ сделать это без iptables (поскольку я даже не уверен, возможно ли это с iptables) - использовать службы xinetd. Чтобы использовать это, установите xinetd на свой компьютер (обычно он установлен по умолчанию). Создайте такой файл:
# vim /etc/xinted.d/tomcat
Поместите это содержимое в файл:
service tomcat
{
socket_type = stream
wait = no
user = root
redirect = 127.0.0.1 8080
bind = 10.31.33.101 80
}
Просто перезапустите службу xinted.
# service xinetd restart
И это будет работать как шарм.
Я уже некоторое время пытаюсь решить эту проблему, и хотя в конечном итоге я решил не привязывать свой серверный процесс к localhost (я использовал 0.0.0.0:PORT), какое-то время я не был уверен, куда на самом деле идут мои входящие пакеты. учитывая, что я думал, что у меня правильное правило NAT.
Ответ заключался в том, что ядро их перехватывает как марсианские пакеты, и отбросив их в сторону.
Этот сайт имеет довольно простой набор инструкций по настройке регистрации марсианских пакетов, если вы захотите узнать, происходит ли это с вами.
Другое решение - использовать nginx в качестве обратного прокси. В этом случае вы можете разрешить пакеты с портом назначения 80 через брандмауэр iptables (убедитесь, что вы не отбрасываете во время этапов FILTER и NAT - вы можете проверить, запустив sudo iptables -t nat -L -v
или sudo iptables -t filter -L -v
). Отсюда nginx прослушивает через все интерфейсы трафик, предназначенный для порта 80. Обнаружив некоторые из них, связанные с входящим HTTP-запросом, вы можете затем заставить nginx перенаправить этот запрос на localhost: 8080 (127.0.0.1:8080) с помощью директивы proxy_pass.
Сообщение @ MonomiDev Вот предоставляет вам фактическую конфигурацию nginx, которая позволит вам это сделать - а затем, если у вас не установлен nginx, есть множество руководств как здесь, в Stack, так и в Интернете, чтобы вы начали.
Что, если вы сделаете это:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j REDIRECT --to-port 80 --match comment --comment "Explain."
В последний раз, когда я использовал подобное правило DNAT, мне также пришлось добавить правило SNAT для POSTROUTING, чтобы оно работало правильно.