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

перенаправление портов iptables A -> B -> A

У меня есть хост-машина (A) с lxc-контейнером (B). Aлокальный IP-адрес 10.0.3.1 и общедоступный IP, скажем, 1.2.3.4. BЛокальный IP-адрес - 10.0.3.21.

Мне нужно, чтобы 1.2.3.4:7999 был перенаправлен на 10.0.3.1:7999, и я создал для этого следующие правила:

iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 7999 -j DNAT --to 10.0.3.21:7999
iptables -A FORWARD -p tcp -d 10.0.3.21 --dport 7999 -j ACCEPT

Когда я подключаюсь к A (1.2.3.4:7999) из внешнего мира я успешно подключаюсь. Но я падаю, когда пытаюсь подключиться к B из A (время соединения истекло).

Какие правила мне нужно создать, чтобы иметь возможность подключаться к 1.2.3.4:7999 из 10.0.3.1?

У тебя есть Шпилька NAT ситуация здесь, которую ваши текущие правила iptables не поддерживают. Когда контейнер отправляет запрос, пакет выглядит так:

10.0.3.21:12345 -> 1.2.3.4:7999

Затем шлюз отправляет пакет к этому DNAT и отправляет его обратно в контейнер:

10.0.3.21:12345 -> 10.0.3.21:7999

Контейнер получает пакеты и отправляет ответ, который выглядит следующим образом:

10.0.3.21:7999 -> 10.0.3.21:12345

т.е. он напрямую обращается к самому контейнеру. Но порт 12345 не знает о соединении с 10.0.3.21:7999, потому что соединение было с 1.2.3.4:7999, и поэтому ответ игнорируется.

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

iptables -t NAT -A POSTROUTING -o lxcbr0 -d 10.0.3.21 -s 10.0.3.21 -j SNAT --to 10.0.3.1

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

Первоначальный запрос

S: 1.2.3.4
D: 1.2.3.4

DNAT

S: 1.2.3.4
D: 10.0.3.21

На этом этапе хост A принимает решение направиться к 10.0.3.21 используя частный сетевой интерфейс.

ОТВЕТИТЬ

S: (IP of default GW interface on B)
D: 1.2.3.4

Ответный пакет от B пересечет шлюз по умолчанию и, скорее всего, вернется к A на своем общедоступном интерфейсе, после чего пакет отбрасывается, поскольку в таблице отслеживания соединений нет соответствующей записи.


Решение

Добавьте следующее правило, чтобы ответ проходил по тому же пути, что и запрос.

iptables -t nat -I POSTROUTING -s 1.2.3.4 -d 10.0.3.21 -o (interface of 10.0.3.1) -j SNAT --to 10.0.3.1