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

Перенаправление порта на интерфейсе обратной связи на удаленный IP / порт

У меня есть два контейнера Docker, которые я пытаюсь объединить в сеть определенным образом. В контейнере A работает сервер Redis на порту 6379. В контейнере B работает интерактивная оболочка, и ему требуется доступ к Redis. Используя функцию связывания Docker, пользователь внутри контейнера B может подключиться к Redis через 10.1.0.2:6379, который проходит через виртуальный интерфейс eth0, настроенный Docker.

В контейнере B будет запущена программа, которая ожидает, что Redis будет доступен на порте 6379 на интерфейсе обратной связи. Предположим, что эту программу нельзя настроить так, чтобы она указывала на другой IP-адрес.

Я хочу перенаправить трафик с 127.0.0.1:6379 на 10.1.0.2:6379. Я пробовал несколько вариантов правил iptables для таблицы NAT, но либо получаю сообщение «В соединении отказано» при попытке подключиться к локальному адресу / порту, либо соединение просто зависает навсегда. Какие правила iptables можно использовать для достижения этого эффекта?

Вот одна из вещей, которые я пробовал:

$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A INPUT -d 10.1.0.2/32 -p tcp -m tcp --dport 6379 -j SNAT --to-source 127.0.0.1
-A OUTPUT -p tcp -m tcp --dport 6379 -j DNAT --to-destination 10.1.0.2:6379

Попытка подключиться к Redis с redis-cli использование приведенных выше правил просто зависает навсегда. Я пробовал такую ​​версию, которая использует PREROUTING / POSTROUTING вместо INPUT / OUTPUT, и это привело к немедленному отказу в соединении.

Я бы использовал для этого socat:

socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379

Возможно, вы захотите запустить это с помощью супервизора или аналогичного инструмента. В Ubuntu:

apt-get install socat supervisor

cat > /etc/supervisor/conf.d/redis-socat.conf << EOF
[program:redis-socat]
command = socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379
autorestart = true
user = nobody
EOF

supervisorctl reload

Теперь вы можете запустить / остановить процесс redis-socat, используя:

supervisorctl start redis-socat 
supervisorctl stop redis-socat

Он также автоматически запускается во время загрузки.