Краткое резюме: Перенаправленный порт работает из внешнего мира, но из внутренней сети, использующей внешний IP-адрес, соединение отклоняется.
Это упрощенная ситуация, чтобы облегчить объяснение:
У меня есть компьютер, на котором запущена служба на порту 12345. Этот компьютер имеет внутренний IP-адрес 192.168.1.100 и напрямую подключен к модему / маршрутизатору, который имеет внутренний IP-адрес 192.168.1.1 и внешний (общедоступный, статический) IP-адрес 1.2.3.4. (Маршрутизатор - TP-LINK TD-w8960N) Я настроил переадресацию порта (виртуальный сервер) на порт 12345, чтобы перейти на порт 12345 по адресу 192.168.1.100.
Если я запускаю telnet 192.168.1.100 12345 с того же компьютера, все работает. Но запущенный telnet 1.2.3.4 12345 сообщает, что соединение отклонено. Если я сделаю это на другом компьютере (в той же внутренней сети, подключенной к маршрутизатору), произойдет то же самое. Может показаться, что переадресация портов не работает. Тем не мение...
Если я запускаю службу онлайн-проверки портов на моем внешнем IP-адресе и служебном порту, он говорит, что порт открыт, и я вижу, как удаленный сервер подключается и немедленно закрывает соединение. И используя другой компьютер, подключенный к Интернету через мобильное соединение, я также могу использовать telnet 1.2.3.4 12345, и я получаю рабочее соединение.
Таким образом, переадресация портов, похоже, работает, однако использование внешнего IP-адреса из внутренней сети - нет. Я понятия не имею, что может быть причиной этого, поскольку у меня работает другая установка, очень похожая на эту (другой маршрутизатор). Я могу получить доступ к службе, работающей на сервере, изнутри сети как через внутренний, так и через внешний IP.
Примечание: Я знаю, что могу просто использовать внутренний IP-адрес внутри сети для доступа к этой услуге. Но если у меня есть ноутбук, который должен иметь возможность делать это как изнутри, так и снаружи, было бы неприятно постоянно переключаться между 1.2.3.4 и 192.168.1.100 в конфигурации программного обеспечения.
Выход маршрутизатора:
> iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 224.0.0.0/3
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 to:192.168.1.101
DNAT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:25 to:192.168.1.101
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:110 to:192.168.1.101
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:12345 to:192.168.1.102
DNAT udp -- 0.0.0.0/0 192.168.1.1 udp dpt:53 to:217.118.96.203
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 192.168.1.0/24 0.0.0.0/0
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Я нашел для работы следующее - взято из http://www.tomshardware.com/forum/12532-42-iptables-access-local-server-external
Пример: (внешний IP 1.1.1.1, внутренняя сеть 192.168.1.0/24, веб-сервер 192.168.1.10, маршрутизатор 192.168.1.1)
Подключитесь через SSH и введите:
iptables -t nat -A PREROUTING -d 1.1.1.1 -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10
Повторите эти действия для каждого перенаправленного порта.
Затем введите следующее правило ONE SNAT:
iptables -t nat -A POSTROUTING -d 192.168.1.10 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
Кажется, он работает нормально, но я не могу понять, как его сохранить, чтобы пережить перезапуск маршрутизатора.
В связи с этим отказано, похоже, здесь интересен. Если бы это была проблема с маршрутизацией, telnet отключил бы тайм-аут или отказался от маршрута к хосту. Я бы начал с трассировки пакетов на ящике, на котором размещена служба, и попытался бы снова подключиться через общедоступный IP-адрес. Это, по крайней мере, поможет вам увидеть, проходит ли соединение через маршрутизатор. Если это произойдет, вам следует больше копать на хосте. Если это не проходит, скорее всего, проблема связана с брандмауэром или каким-либо другим параметром конфигурации на маршрутизаторе. Вы можете попробовать другой роутер.
Где-то должен быть настроен IP-контроль, блокирующий ваш доступ. Вы написали, что это работает для вас в аналогичной настройке, и я могу подтвердить, что это также работает для меня в очень похожей настройке.
Вы пытались запустить tcpdump на сетевом интерфейсе на 192.168.1.100, чтобы увидеть, приходят ли пакеты вообще на порт 12345?
tcpdump -i eth0 port 12345
С какого IP-адреса приходят пакеты? Возможно, ваше приложение блокирует этот диапазон IP-адресов?
Вы проверили свои конфигурации /etc/hosts.deny и /etc/hosts.allow?
Насколько я знаю, вы не можете этого сделать.
Попытайтесь трассировать соединение, любой хост во внутренней сети выбирает 192.168.1.1 в качестве следующего перехода для 1.2.3.4, тогда маршрутизатор должен обрабатывать это соединение, но я думаю, что он не может перенаправить соединение изнутри внутрь.
Вы должны видеть, какой уровень контроля у вас есть на маршрутизаторе, если это был сервер Linux, вы могли бы играть с iptables, но подобное устройство не предлагает такого уровня контроля над конфигурацией сети.
Конечно, это не сработает! Когда вы отправляете пакеты с подключенного к локальной сети хоста на 1.2.3.4:12345, пакеты проходят по маршруту по умолчанию к вашему маршрутизатору, который меняет адрес назначения на 192.168.1.100. Все в порядке. Но когда сервер пытается ответить, он видит, что исходный адрес (он остается исходным, 192.168.1.xx) находится в той же локальной сети, и отправляет пакеты напрямую, а не через маршрутизатор. Итак, ваш хост не понимает эти ответы, поскольку их исходный адрес (192.168.1.100) не совпадает с адресом назначения исходных пакетов (1.2.3.4)!
Лучшие решения:
iptables
на сервере на локальный адрес SNAT до 1.2.3.4