Перенаправление порта iptables не работает для localhost

55

Я хочу перенаправить весь трафик с порта 443 на внутренний порт 8080. Я использую этот конфиг для iptables:

iptables -t nat -I PREROUTING --source 0/0 --destination 0/0 -p tcp \
         --dport 443 -j REDIRECT --to-ports 8080

Это работает для всех внешних клиентов. Но если я пытаюсь получить доступ к порту 443 с той же машины, я получаю сообщение об ошибке соединения отказано.

wget https://localhost

Как я могу расширить правило iptables для перенаправления локального трафика тоже?

Крис
источник
В этом разделе приводится более общий ответ: serverfault.com/questions/380447/iptables-preroute-localhost
Jeroen
1
Может ли кто-нибудь с репутацией добавить обратную косую черту в команду до разрыва строки?
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

69

PREROUTING не используется интерфейсом обратной связи, вам также необходимо добавить правило OUTPUT:

iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 8080
Энди
источник
3
Нет необходимости в первом правиле. Локально сгенерированные пакеты не проходят через цепочку PREROUTING.
Халед
9
Я добавил первоначальное правило для конкуренции, так как он хочет, чтобы внешний трафик также перенаправлял. Правило не нуждается в источнике / назначении, если они только говорят, чтобы принять все IP
Энди
о, извинения, я не видел ваш ответ, когда я ответил.
Энди
Привет, Энди, я все еще получаю Соединение с server.com | <ip> |: 443 ... не удалось: соединение отклонено.
Крис
Привет Крис, это Соединение с localhost | 127.0.0.1 | 443 или это домен? Если последний и вы запускаете его со своего сервера, у вас может быть проблема внутренней маршрутизации. Вы можете проверить это дважды, попробовав wget server.com:8080 (хотя я предполагаю, что причина, по которой вы переадресовываете порт, в том, что он заблокирован извне?) У моего собственного VPC есть такая проблема, однако вы могли бы обойти это, определив домен как 127.0.0.1 в вашем файле / etc / hosts.
Энди
10

Для перенаправления пакетов с локального хоста на другую машину действует правило:

 iptables -t nat -A OUTPUT -o lo -d 127.0.0.1 -p tcp --dport 443 -j DNAT  --to-destination 10.x.y.z:port

будет работать, НО вам также нужно включить эту опцию в ядре:

sysctl -w net.ipv4.conf.all.route_localnet=1

Без настройки ядра это не сработает.


источник
Это тоже сработало бы. Я думаю, что делать все это в iptables чище.
quadruplebucky
На самом деле, настройка ядра необходима, если место назначения находится на другом компьютере, на линии виртуальной машины или на удаленном компьютере.
это не так, если у вас есть два правила, предложенные Энди выше.
quadruplebucky
Извините, я говорил о переадресации на другую машину, где DNAT не работает. Я искал этот ответ для решения проблемы, когда пытался переслать что-то, что, по его мнению, подключалось к localhost, к контейнеру на той же машине. например, запуск сервера имен в контейнере для локальных запросов.
На самом деле, это зависит от версии ядра> = 3.6, по-видимому.
quadruplebucky
3

Как насчет этого?

iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-port 8080

Афанасий
источник
2

Вы сказали, что получили сообщение об ошибке соединения отказано Это означает, что не существует локального процесса, прослушивающего порт, к которому вы пытаетесь подключиться! Чтобы проверить процессы прослушивания, используйте команду:

$ sudo netstat -lnp | grep 8080

После применения правила у вас должен быть процесс, прослушивающий порт 8080 для подключения.

Похоже, у вас должно быть следующее правило:

$ iptables -t nat -I OUTPUT --source 0/0 --destination 0/0 -p tcp
                                       --dport 443 -j REDIRECT --to-ports 8080

Помните, что вы отправляете с локального хоста. Итак, вам нужно перенаправить выходной пакет.

Халед
источник
1
Спасибо за ваш ответ. Процесс прослушивает порт 8080. Поэтому я хочу перенаправить весь трафик на этот порт.
Крис
Вы уверены, что процесс также прослушивает интерфейс цикла? Это может только слушать на вашем физическом интерфейсе. Как правило, ваш веб-сервер должен будет слушать 0.0.0.0, а не, скажем, 192.168.10.0
MrMajestyk