Вопрос или проблема
Я застрял на этой проблеме весь день и надеюсь, что какой-нибудь эксперт по 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 адрес?
Пример сценария
- Я применил вышеуказанные правила iptables на своем хосте Docker
- У меня есть контейнер Docker с адресом
172.20.0.2
- Внутри этого контейнера я делаю curl к example.com
- Трафик перенаправляется на
172.17.0.1:12345
(машина-хост Docker) - Сервер, работающий на
12345
, показывает удаленный IP адрес как ‘127.0.0.1’ - Я хотел бы, чтобы удаленный 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) — он заменяет адреса источника и назначения пакетами, что может создавать проблемы с идентификацией источников трафика.
Предложения по исправлению
-
Изменение правил 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
-
Разрешение входящих соединений:
Добавьте правило для разрешения входящих соединений от контейнеров на хосте:iptables -I INPUT -p tcp -s 172.20.0.0/16 -j ACCEPT
Это правило обеспечит, что хост примет соединения, исходящие от контейнеров с указанного диапазона IP-адресов.
-
Использование REDSOCKS:
Хорошей практикой будет добавление моста между REDSOCKS и SOCKS5. Используйте REDSOCKS для преобразования трафика из своей сети в SOCKS5, как показано ниже:container -> host -> REDSOCKS -> SOCKS5
Убедитесь, что ваш REDSOCKS настроен для работы с входящим трафиком.
-
Проверка настроек Linux:
В некоторых версиях Linux могут возникать проблемы с NAT, которые могут помешать правильной работе ваших iptables. Рекомендуется обновить ядро системы до последней версии, если вы подозреваете, что это может быть источником проблемы. -
Отладка:
Используйте отладочные инструменты, такие какtcpdump
, для анализа трафика и определения, какие адреса фактически используются в заголовках пакетов. Это может помочь выявить проблему.
tcpdump -i any -nn host 172.20.0.2
Таким образом, вы сможете увидеть, какие IP-адреса отображаются в трафике, и будут ли они соответствовать вашим ожиданиям.
Заключение
Следуя данным рекомендациям, вы сможете настроить iptables для корректной переадресации исходящих соединений Docker-контейнеров через SOCKS5-прокси, сохраняя оригинальный IP-адрес каждого соединения. Это улучшит безопасность и позволит точно отслеживать активность пользователей приложений в контейнерах. Порекомендуйте также периодически проверять обновления системы и документации по iptables, чтобы гарантировать, что ваше решение остается актуальным.