В моей лаборатории настроен прокси-сервер squid, реплицирующий производственную проблему с библиотекой запросов python.
Настройка Squid: - Client -> Squid over HTTPS - Squid НЕ выполняет перехват TLS / Bump - отлично работает от cURL. - Пароль не требуется - Действительный сертификат на сервере squid
Вывод Curl работает нормально:
curl -I -x https://squid-signed.hacksbrain.com:3128 https://www.google.com
HTTP/1.1 200 Connection established
HTTP/2 200
date: Sat, 04 Apr 2020 00:20:50 GMT
... Content from google.com ...
Однако, когда я пытаюсь сделать вызов из Python запросов, я получаю следующую ошибку :
requests.exceptions.ProxyError: HTTPSConnectionPool(host='google.com', port=443): Max retries exceeded with url: / (Caused by ProxyError('Cannot connect to proxy.', ConnectionResetError(54, 'Connection reset by peer')))
Я перехватываю пакеты на сервере squid и вижу, что 3-стороннее рукопожатие завершено, и pu sh приходит от клиента python, за которым следует TCP RESET с сервера squid.
Я вижу следующую запись в журнале squid, которая соответствует этой попытке подключения:
1585958924.312 0 192.168.1.100 NONE/000 0 NONE error:transaction-end-before-headers - HIER_NONE/- -
Команда CONNECT для создания сквозного туннеля никогда не отправляется из python client.
def main():
proxies = {'https': 'https://squid-signed.hacksbrain.com:3128'}
headers = {'User-Agent': 'curl/7.64.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
r = requests.get('https://google.com', headers=headers, proxies=proxies)
Я подозреваю, что клиент запросов не знает, что делать с клиентом -> squid через https против http. В моей производственной среде это требуется, поскольку это аутентифицированный прокси-сервер, отправляющий учетные данные в заголовке в виде открытого текста, поэтому подключение https к squid является жестким требованием.
ОБНОВЛЕНИЕ: я открыл перехват из рабочего сеанса cURL и из сеанса python в Wireshark. Я думаю, что вижу проблему. Python запросы отправляет команду CONNECT на прокси-сервер в виде открытого текста, а не внутри туннеля https. Я не вижу такого поведения из рабочего захвата cURL. ![python packet capture](https://i.stack.imgur.com/3hLx3.png)