Я запускаю несколько контейнеров Linux, каждый из которых запускает веб-приложение, на моем хосте Ubuntu. Для доступа к веб-приложениям я использую iptables
переадресовать порт:
sudo iptables -t nat -A PREROUTING -p tcp --dport <port> -j DNAT --to-destination #<container_ip>:<port>
Это хорошо работает, если трафик идет из вне моего хозяина. Если запрос выполняется локальным хостом, он не работает:
curl <host_ip>:<port> #works (from outside the host)
curl <container_ip>:<port> #works (from inside the host)
curl 127.0.0.1:<port> #doesn't work (from inside the host)
Я понимаю, что пакет, приходящий с localhost, не проходит через правило DNAT iptables, и поэтому он не работает. Есть ли способ заставить это работать?
@ Бриго: Это неверно. Таблица nat может содержать цепочку OUTPUT. Проблема в том, что цепочка PREROUTING таблицы nat не применяется к интерфейсу обратной связи.
@rmonjo, используйте цепочку OUTPUT в дополнение к цепочке PREROUTING:
iptables -t nat -A OUTPUT -o lo -p tcp --dport <port> -j DNAT \
--to-destination #<container_ip>:<port>
Изменить: это не работает. Я думал о цели REDIRECT, которая не решит эту проблему.
Я потратил много времени, пытаясь заставить iptables сделать этот трюк, но каким-то образом, если вы добавите цель dnat в выходную цепочку таблицы nat, дальнейшая обработка пакета, похоже, остановится.
Отладку iptables можно выполнить с помощью такого трюка: http://backreference.org/2010/06/11/iptables-debugging/
Графический обзор потока пакетов в Linux также помогает: http://inai.de/images/nf-packet-flow.png
я обратился к xinetd для решения своей проблемы, см. Перенаправление конечной точки (на локальном хосте) туннеля SSH -L на другую машину