Переадресация порта в интерфейсе обратной связи на удаленный 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, и это привело к немедленному "отказ в соединении".
1 ответ
Я бы использовал socat для этого:
socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379
Возможно, вы захотите запустить это с помощью супервизора или аналогичного инструмента. На убунту:
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
Он также автоматически запустится во время загрузки.