Назад | Перейти на главную страницу

Перенаправление портов с помощью iptables

я получил lo (127.0.0.1) и eth0 (172.17.0.8). Я хочу перенаправить пакеты, которые попадают в 127.0.0.1:80 к 172.17.42.1:80 (маршрут от eth0).

Я попытался

iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.1 -j DNAT --to 172.17.42.1:80

Но когда я сделаю curl localhost:80 Я не получаю ответа, когда делаю curl 172.17.42.1:80 это просто работает.

Когда вы пытаетесь связаться с localhost, ваш исходный адрес - 127.0.0.1, как и ваш конечный адрес. Итак, пакет выглядит примерно так:

 | SRC        |  DST       |
 | 127.0.0.1  |  127.0.0.1 |

Поскольку пакеты, которые генерируются локально, сначала проходят цепочку OUTPUT, вы изменяете пакет правилом DNAT:

iptables -t nat -A OUTPUT \
         -d 127.0.0.1 \
         -p tcp --dport 80 \
         -j DNAT \
         --to 172.17.42.1:80

После цепочки OUTPUT пакет выглядит так:

 | SRC        |  DST        |
 | 127.0.0.1  |  172.17.42.1 |

Итак, первая ошибка, которую вы видите, заключается в том, что даже если этот пакет маршрутизируется за пределы исходного устройства, пункт назначения не знает, как правильно его вернуть. Таким образом, вам также необходимо добавить дополнительное правило SNAT:

iptables -t nat -A POSTROUTING \
         -d 172.17.42.1 \
         -p tcp --dport 80 \
         -j SNAT \
         --to-source <your_ip_addr>

Теперь пакет будет выглядеть довольно корректно для выхода из сети (адрес источника будет публичным адресом этого устройства, а не адресом localhost).

Но это пока не решит вашу боль.

Решения о маршрутизации пакетов, сгенерированных на локальной машине, принимаются в двух местах.

  • перед цепочкой OUTPUT
  • после OUTPUT цепочки и до POSTROUTING

Решение для этого пакета будет принято на втором этапе, до того, как IP-адрес источника будет перезаписан в цепочке POSTROUTING ...

Таким образом, механизм безопасности ядра отбрасывает пакет, потому что по умолчанию ядро ​​отказывается маршрутизировать пакеты с src 127.0.0.1. Значит, даже mangle вместе с fwmark нам здесь не поможет. Для этого нужно включить route_localnet. Это индивидуальная переменная, которая позволяет использовать 127/8 для целей локальной маршрутизации (по умолчанию 0 - он же отключен).

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

В вашем случае вы можете смело заменить «все» на имя исходящего интерфейса.

Теперь пакеты будут маршрутизироваться в соответствии с предыдущими правилами в таблице, и, поскольку у нас есть POSTROUTING SNAT, мы исправим исходный ip 127.0.0.1 и перепишем его.

Надеюсь это поможет.

PS. извините перед 2-3 правками, здесь 5 утра, а я все еще не сплю :)

Прежде чем сразу перейти к правилам брандмауэра, следует также выполнить простую проверку пересылки. Скорее, как когда проверяют, подключен ли шнур питания, прежде чем разбирать оборудование.

Бегать:

cat /proc/sys/net/ipv4/ip_forward

Если вы получите ноль, IPv4 не будет пересылать. Вам нужно будет включить это.

Чтобы включить его немедленно и временно для проверки поведения:

echo 1 > /proc/sys/net/ipv4/ip_forward

Вышеупомянутое включает его для машины, но просто изменяет настройку ядра на лету и не будет "сохранен".

Отредактируйте файл sysctl.conf, чтобы внести правильные постоянные изменения и обеспечить следующие настройки:

net.ipv4.ip_forward = 1