Есть несколько проблем с вашей попыткой:
localhost
означает, что соединения инициируются с хоста, а не маршрутизируются с другого хоста. Таким образом, требуется цепочка OUTPUT
, а не цепочка PREROUTING
, поскольку маршрутизация изначально не использовалась. 127.0.0.1
, также должен быть изменен после изменения пункта назначения. Для этого требуется дополнительное правило POSTROUTING
. Необязательное совпадение -m conntrack --ctstate DNAT
проверит, что первый OUTPUT
действительно совпал первым, и это не попытка спуфинга. 127.0.0.0/8
обрабатывается особым образом в стеке маршрутизации, и пакет будет отброшен до того, как сработает правило POSTROUTING
. Чтобы удалить специальную обработку и разрешить маршрутизацию «вне» блока 127.0.0.0/8
,на интерфейсе, на котором будет происходить перенаправление, флагroute_localnet
должен быть установлен в 1, иначе ничего из вышеперечисленного будет недостаточно. Поскольку интерфейс неизвестен из Вопроса, имя интерфейса извлекается из маршрута и помещается в переменную. Адаптируйте его, если это необходимо. Вы также можете использовать интерфейс all
псевдо -для глобальной установки флага .
Так что, в конце концов, это сводится к (как root или с использованиемsudo
):
iptables -t nat -A OUTPUT -p tcp --dport 9099 -j DNAT --to-destination 172.17.0.2:8080
iptables -t nat -A POSTROUTING -s 127.0.0.0/8 -d 172.17.0.2 -m conntrack --ctstate DNAT -j MASQUERADE
interface=$(ip -o route get 172.17.0.2 | grep -o 'dev [^ ][^ ]*'|sed 's/^dev //')
echo 1 > /proc/sys/net/ipv4/conf/$(interface)/route_localnet
После всего сказанного вам следует попробовать использовать адрес, отличный от -127.0.0.0/8
, но все же локальный для хоста. Это может упростить ситуацию, не требуяroute_localnet
(и, возможно, иногда не требуя дополнительного правила POSTROUTING
).