Настройка прозрачного SSL-прокси

14

У меня есть linux box с двумя сетевыми картами для проверки трафика, проходящего через порт 80. Одна карта используется для выхода в Интернет, другая подключена к сетевому коммутатору. Суть в том, чтобы иметь возможность проверять весь трафик HTTP и HTTPS на устройствах, подключенных к этому коммутатору, в целях отладки.

Я написал следующие правила для iptables:

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

192.168.2.1:1337 у меня есть прозрачный http-прокси, использующий для записи Чарльза ( http://www.charlesproxy.com/ ).

Все хорошо для порта 80, но когда я добавляю аналогичные правила для порта 443 (SSL), указывающего на порт 1337, я получаю сообщение об ошибке с неверным сообщением через Чарльза.

Я использовал SSL-прокси на том же компьютере раньше с Чарльзом ( http://www.charlesproxy.com/documentation/proxying/ssl-proxying/ ), но по какой-то причине мне не удалось сделать это прозрачно. Некоторые ресурсы, которые я гуглил, говорят, что это невозможно - я готов принять это как ответ, если кто-то может объяснить почему.

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

Благодарность!

Редактировать: немного поиграв, я смог заставить его работать на конкретном хосте. Когда я изменяю свои iptables следующим образом (и открываю 1338 в charles для обратного прокси):

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.2.1:1338
-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1338

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

Я могу получить ответ, но без хоста назначения. В обратном прокси-сервере, если я просто указываю, что все, начиная с 1338, направляется на конкретный хост, на который я хотел попасть, он выполняет рукопожатие правильно, и я могу включить прокси-сервер SSL для проверки связи.

Настройка менее чем идеальна, потому что я не хочу предполагать, что все, начиная с 1338, отправляется на этот хост - есть идеи, почему хост хоста удаляется?

еще раз спасибо

badunk
источник
Какие конкретные проблемы у вас возникли? Это возможно, так как вы доверяете сертификатам, которые он генерирует динамически - это может быть MITM, который может перехватывать текст сообщения и при этом клиенту по-прежнему доверять соединению.
Шейн Мэдден
Я отредактировал свое сообщение - я думаю, что хост назначения
удален

Ответы:

10

Вы видите те же проблемы, которые не позволяют использовать несколько сертификатов на одном IP-адресе / порте (без использования указания имени сервера) .

В обычном HTTP ваш прозрачный прокси может сказать, к какому хосту клиент хочет подключиться, заглянув в Hostзаголовок.

Когда прозрачный прокси-сервер HTTPS MITM получает запрос, он не может знать, какое имя хоста клиент запрашивал в первую очередь. (Я даже не уверен, что он может получить IP-адрес с этими правилами, которые, по крайней мере, позволили бы ему угадать, используя обратный поиск DNS, хотя это вряд ли сработает в общем случае.)

  • Чтобы получить ожидаемое имя хоста, прокси-сервер MITM должен прочитать Hostзаголовок HTTP-сообщения, что может произойти только после успешного рукопожатия.
  • Для успешного установления связи прокси-сервер MITM должен сгенерировать сертификат подделки, соответствующий ожидаемому имени хоста.

В результате прокси-сервер MITM не может знать, какой сертификат нужно сгенерировать до рукопожатия.

Это может работать с непрозрачным прокси-сервером MITM, потому что вы, по крайней мере, получите желаемое имя хоста через CONNECTметод HTTP .

Bruno
источник
Это объяснило мне большое спасибо! Я чувствую, что могу начать задавать правильные вопросы. Как можно настроить прозрачный SSL-прокси? Какое рукопожатие?
Badunk
1
@badunk, я не думаю, что вы можете, если вы отключите все проверки сертификатов на стороне клиента.
Бруно
Еще один способ получить правильное имя хоста для прокси-сервера состоит в том, чтобы самому запросить целевой IP-адрес для получения сертификата, прежде чем продолжить рукопожатие между клиентом и прокси-сервером.
Бруно
mitmproxy - это HTTPS-прокси. Вам не нужно отключать проверку всех сертификатов, но вы должны установить сертификат mitmproxy, так как он будет использоваться для всех соединений https.
Тайлер
3

Просто немного базовой информации по этой теме.

Я знаю только несколько устройств, которые могут успешно выполнить это действие. Однако они на самом деле не доступны для широкой публики. Я сам использую Fortinet Fortigate с SSL Offloading.

То, что это в основном делает; он перехватывает SSL-соединение, установленное с хостом, и дешифрует соединение на аппаратном уровне, затем проверяет, куда вы хотите перейти, и принимает решение о брандмауэре на основе этой информации.

После этого он устанавливает собственное соединение с этим хостом для извлечения данных и переподписывает исходный запрос клиенту, используя CA, предоставленный пользователем. Для обеспечения бесперебойной работы требуется наличие CA в доверенном корневом CA на клиенте.

Подобные установки используются в организациях для обеспечения соблюдения политики компании в отношении использования Интернета. Поскольку использование Active Directory позволяет легко установить CA вашей компании на клиентах, это не создает проблем для крупных организаций.

Это ЕДИНСТВЕННЫЙ способ, которым вы можете сделать это без создания ручного прокси, так как трафик SSL зашифрован. По сути, это MITM, поэтому важно, чтобы были рассмотрены все правовые вопросы.

Йохен Оонинкс
источник
1

Есть еще несколько предложений по этому другому вопросу, которые вы, возможно, видели: прозрачные мифы и факты о SSL-прокси . И есть эта ссылка, которая объясняет, как именно настроить Squid, чтобы он стал прозрачным SSL-прокси. Это не то, что вы ищете, но это может, по крайней мере, дать вам представление о том, что может пойти не так.

Правила iptables кажутся нормальными, но я понятия не имею, может ли используемое вами прокси-программное обеспечение выполнять то, что вы пытаетесь сделать. Документация, безусловно, утверждает, что это так.

chutz
источник
0

Чтобы добавить к решению Бруно, я немного исследовал и хотел поделиться тем, как я получил еще одно не совсем идеальное быстрое решение.

После настройки этих iptables я могу установить обратный прокси-сервер на порт 1338 и переслать его на локальный хост на порт 1337. Поскольку порт 1337 является прозрачным http-прокси и данные были расшифрованы, он примет заголовок узла и сделает его пунктом назначения. хост.

Основным недостатком является то, что я по сути преобразовал соединение https в http - это не всегда работает с каждым сервером (не говоря уже о дыре в безопасности, которую я открываю из этого).

Я работал в рамках моего программного обеспечения. Я полагаю, что более чистое решение, согласно Бруно, предполагает, что весь трафик с 1338 года должен быть расшифрован. После расшифровки проверьте хост назначения и затем прокси-запрос с использованием SSL.

badunk
источник
Не уверен, что я понимаю, конечно, вы не делаете правильную https://связь с точки зрения клиента с этим?
Бруно