Использование iptables для перенаправления всего исходящего трафика Docker обратно в контейнер.

Вопрос или проблема

Я застрял на этой проблеме весь день и надеюсь, что какой-нибудь эксперт по iptables прочитает это и сможет мне помочь.

Я хотел бы заставить весь исходящий трафик моих контейнеров Docker проходить через прокси socks5.

Это самое близкое, к чему я пришел:

iptables -t nat -N REDSOCKS
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -d 240.0.0.0/4 -j RETURN

iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -p tcp -j DNAT --to-destination 172.17.0.1:12345
iptables -t nat -A OUTPUT -s 172.20.0.0/16 -j REDSOCKS
iptables -t nat -A PREROUTING -s 172.20.0.0/16 -j REDSOCKS

Это работает почти идеально, но прокси socks5 не может определить исходящий IP адрес.

Удаленный адрес всегда ‘127.0.0.1’

Есть ли способ сохранить исходящий IP адрес?

Пример сценария

  1. Я применил вышеуказанные правила iptables на своем хосте Docker
  2. У меня есть контейнер Docker с адресом 172.20.0.2
  3. Внутри этого контейнера я делаю curl к example.com
  4. Трафик перенаправляется на 172.17.0.1:12345 (машина-хост Docker)
  5. Сервер, работающий на 12345, показывает удаленный IP адрес как ‘127.0.0.1’
  6. Я хотел бы, чтобы удаленный IP адрес отображался как 172.20.0.2

Спасибо всем, кто сможет попробовать помочь мне с этим.

С сетевой точки зрения, если исходный IP равен адресу назначения, это приводит к проблеме безопасности, известной как атака Land.

Я применил вышеуказанные правила iptables на своем хосте Docker

На хосте -t nat -A OUTPUT перенаправляет исходящий трафик вашего хоста. Вам это не нужно, если вы просто хотите перенаправить трафик контейнера. Использование -t nat -I PREROUTING достаточно, чтобы перенаправить трафик контейнера.

И вот несколько советов, которые вы можете попробовать, не уверены. Надеюсь, это поможет:

  • Так как это iptables хоста, попробуйте изменить -j DNAT --to-destination 172.17.0.1:12345 на -j DNAT --to-destination 127.0.0.1:12345

  • iptables -I INPUT -j ACCEPT, чтобы разрешить входящий трафик от контейнеров. Я думаю, что ваш хост этого не разрешал, так что исходный IP всегда был (и мог быть только) 127.0.0.1

  • Прокси socks5? Вам нужен мост протокола прокси, чтобы использовать socks5 с iptables.

    контейнер -> хост -> мост redsocks к socks5 -> socks5
    
  • Наконец, если это по-прежнему не работает, это может быть ошибка Linux в NAT, как я столкнулся здесь. Эта проблема была решена после обновления Linux. Я не знаю, просто предполагаю

Ответ или решение

Переадресация всех исходящих соединений Docker-контейнеров через SOCKS5-прокси с помощью iptables

Ваша задача — перенаправить все исходящие соединения Docker-контейнеров через SOCKS5-прокси, при этом сохранив оригинальный IP-адрес источника. Проблема, с которой вы столкнулись, заключается в том, что исходящий IP-адрес отображается как 127.0.0.1 из-за механизмов NAT, используемых в Linux.

Понимание проблемы

В вашем текущем решении вы используете правила iptables для переадресации трафика. Однако, в результате применения этих правил, IP-адрес источника трафика из контейнера замещается на IP-адрес хоста, и поэтому SOCKS5-прокси не может определить оригинальный IP. Это связано с тем, как работает NAT (Network Address Translation) — он заменяет адреса источника и назначения пакетами, что может создавать проблемы с идентификацией источников трафика.

Предложения по исправлению

  1. Изменение правил iptables:
    Убедитесь, что вы не переадресовываете трафик на 172.17.0.1, а вместо этого используете 127.0.0.1, чтобы избежать замены IP-адреса. Измените правило DNAT следующим образом:

    iptables -t nat -A REDSOCKS -s 172.20.0.0/16 -p tcp -j DNAT --to-destination 127.0.0.1:12345
  2. Разрешение входящих соединений:
    Добавьте правило для разрешения входящих соединений от контейнеров на хосте:

    iptables -I INPUT -p tcp -s 172.20.0.0/16 -j ACCEPT

    Это правило обеспечит, что хост примет соединения, исходящие от контейнеров с указанного диапазона IP-адресов.

  3. Использование REDSOCKS:
    Хорошей практикой будет добавление моста между REDSOCKS и SOCKS5. Используйте REDSOCKS для преобразования трафика из своей сети в SOCKS5, как показано ниже:

    container -> host -> REDSOCKS -> SOCKS5

    Убедитесь, что ваш REDSOCKS настроен для работы с входящим трафиком.

  4. Проверка настроек Linux:
    В некоторых версиях Linux могут возникать проблемы с NAT, которые могут помешать правильной работе ваших iptables. Рекомендуется обновить ядро системы до последней версии, если вы подозреваете, что это может быть источником проблемы.

  5. Отладка:
    Используйте отладочные инструменты, такие как tcpdump, для анализа трафика и определения, какие адреса фактически используются в заголовках пакетов. Это может помочь выявить проблему.

tcpdump -i any -nn host 172.20.0.2

Таким образом, вы сможете увидеть, какие IP-адреса отображаются в трафике, и будут ли они соответствовать вашим ожиданиям.

Заключение

Следуя данным рекомендациям, вы сможете настроить iptables для корректной переадресации исходящих соединений Docker-контейнеров через SOCKS5-прокси, сохраняя оригинальный IP-адрес каждого соединения. Это улучшит безопасность и позволит точно отслеживать активность пользователей приложений в контейнерах. Порекомендуйте также периодически проверять обновления системы и документации по iptables, чтобы гарантировать, что ваше решение остается актуальным.

Оцените материал
Добавить комментарий

Капча загружается...