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

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

У меня есть Linux-бокс с двумя сетевыми картами для проверки трафика, проходящего через порт 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-прокси с использованием Charles (http://www.charlesproxy.com/) для записи.

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

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

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

Спасибо!

Изменить: немного поиграв с ним, я смог заставить его работать для определенного хоста. Когда я изменяю свои 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, идет на этот хост - есть идеи, почему целевой хост удаляется?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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