Httpie: HTTPie игнорирует системные сертификаты

Созданный на 9 июн. 2016  ·  20Комментарии  ·  Источник: httpie/httpie

HTTPie игнорирует системные сертификаты

http --debug -j https://example_using_my_ca.com

HTTPie 0.9.3
HTTPie data: /home/lukas/.httpie
Requests 2.10.0
Pygments 1.6
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] linux

>>> requests.request(**{'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': '',
 'files': DataDict(),
 'headers': {'Accept': b'application/json',
             'Content-Type': b'application/json',
             'User-Agent': b'HTTPie/0.9.3'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://example_using_my_ca.com',
 'verify': True})

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 351, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 814, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py", line 289, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/ssl_.py", line 308, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3.4/ssl.py", line 365, in wrap_socket
    _context=self)
  File "/usr/lib/python3.4/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python3.4/ssl.py", line 828, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 403, in send
    timeout=timeout
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 604, in urlopen
    raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/http", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.4/dist-packages/httpie/core.py", line 115, in main
    response = get_response(args, config_dir=env.config.directory)
  File "/usr/local/lib/python3.4/dist-packages/httpie/client.py", line 48, in get_response
    response = requests_session.request(**kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 585, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 477, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

Для справки, curl отлично работает: curl https://example_using_my_ca.com

Все 20 Комментарий

Имеет ли смысл использовать ssl.get_default_verify_paths () для получения путей по умолчанию?

Я бы предложил следующее поведение:

Если --verify передается параметр, отличный от no или yes, передать параметр запросам.

Если --verify установлено в yes:
1) если REQUESTS_CA_BUNDLE установлен, передать True для проверки запросов.
2) переменная среды elif ssl.get_default_verify_paths (). Openssl_cafile_env установлена, передайте это запросам проверки
4) переменная окружения elif ssl.get_default_verify_paths (). Openssl_capath_env установлен передать, что для проверки запросов
5) elif ssl.get_default_verify_paths (). Capath не равен None, передайте это запросам verify
6) иначе передать True для проверки запросов

но обратите внимание, что ssl.get_default_verify_paths доступен только с python3.4

@luv не только доступен только в версиях 3.4+ и 2.7.10+, но он не работает на всех платформах. Вот почему запросы работают над своей собственной проблемой, чтобы решить эту проблему для людей. Пожалуйста, прекратите постоянно комментировать httpie. Это проблема, которая существует в запросах, а не в httpie IMO.

@ sigmavirus24, черт возьми ? Понятия не имею, что вы подразумеваете под постоянным комментированием, но что бы то ни было, я вижу, что вы даже не являетесь участником httpie. Я полагаю просто тупой тролль: /

беглый взгляд на исходный код curl, чтобы увидеть, как выглядит рабочая реализация ....

Не обращая внимания на все эти ifdefs amiga и VMS и поддержку множества разных ssl-библиотек, это на самом деле довольно глупо и не использует методы поиска openssl X509_ * (как, например, используемые в get_default_verify_paths () в Python SSL-модуле).

Вместо этого curl просто перебирает множество известных местоположений во время компиляции (см. Этот m4dness https://github.com/curl/curl/blob/master/acinclude.m4#L2560), а затем явно поддерживает переопределение с помощью (CURL_CA_BUNDLE и ) Переменные среды SSL_CERT_DIR и SSL_CERT_FILE во время выполнения (опять же без использования таких вещей, как X509_get_default_cert_file_env ()). Вот и все.

А как насчет реализации того же подхода на чистом питоне? (Да, это выглядит чертовски быстро и грязно, но работает для curl!), Но добавлена ​​поддержка Windows (ssl.enum_certificates?) И OS X (здесь не уверен, но python, похоже, использует поставляемую Apple библиотеку openssl в OS X 10.6+. так что это уже должно быть хорошо!).

@luv благодарит за отчет, но, пожалуйста, будьте внимательнее к другим участникам. @ sigmavirus24 - основной разработчик запросов, на которые httpie полагается для всего HTTP и без которых он даже не существовал бы, поэтому его точка зрения чрезвычайно актуальна.

обратите внимание, что это не будет исправлено в запросах до выпуска 3.0.0 ... даже SSL_CERT_FILE не будет поддерживаться из-за возможных проблем совместимости https://github.com/kennethreitz/requests/pull/2903

кстати Я не хотел вести себя неуважительно, я действительно думал, что он / она занимается троллингом :) Я изо всех сил старался помочь найти решение проблемы и кого-то, кто ни разу не участвовал в проекте (я проверил участников HTTPie, потому что я был действительно удивлен такой враждебной реакцией) в основном говорил мне заткнуться: /

@luv Я не говорил тебе заткнуться. На этот выпуск подписались 763 человека. 100% из них _могут_ получать электронные письма об этом (но это, вероятно, больше похоже на 70% или ~ 534). Это означает, что вы сгенерировали (в течение 2 часов после открытия проблемы) ~ 1602 письма (возможно, более или менее). Другими словами, вы рассылаете людям поток таких сознательных сообщений. Лучший способ документировать новую информацию, когда никто не ответил вам, - это отредактировать исходное сообщение.

Наконец, добавление кода - не единственный вклад в проект. Если вы хотите увидеть все вклады в проект, вы можете использовать такой проект, как octohatrack . Я ответил на несколько запросов, связанных с ошибками на httpie для @jkbrzt, потому что у них нет времени следить за разработкой запросов. Когда я вижу здесь ошибку, связанную с запросами, я отвечаю, потому что в 99% случаев она уже устранена. К счастью для @jkbrzt , раньше

В качестве побочного примечания, «они» - это столько же символов, сколько «он / она», и применимо гораздо более широко, поскольку оно также может использоваться для обозначения одного человека.

так мы исправим это?

@jkbrzt Я бы назвал это функцией, а не ошибкой. Умышленно, что запросы работают одинаково в Windows, * nixes и BSD, и на самом деле многие системные дистрибутивы запросов активно удаляют такое поведение и указывают на хранилище / пакет системных сертификатов. Поэтому, если пользователям необходимо такое поведение, они могут использовать версию запросов, упакованную их системными дистрибьюторами с HTTPie (и, возможно, системную упаковку HTTPie).

Что касается «исправления», это зависит от вашего определения фиксированного. Эта функция будет добавлена ​​в запросы. В этот момент HTTPie получит поведение бесплатно. Если HTTPie вместо этого сочтет это более высоким приоритетом (что @jkbrzt может делать по своему усмотрению), они могут дублировать усилия по разработке, чтобы создать выпуск, который сделает это раньше.

Поскольку кажется, что вы используете linux, @luv , вы можете воспользоваться тем фактом, что в вашем дистрибутиве Linux почти наверняка есть версия запросов, которая сегодня использует хранилище сертификатов системы. Запросы упакованы в каждом дистрибутиве Linux, который я проверял, и почти каждый из этих дистрибутивов использует свое системное хранилище сертификатов. Если это не так, возможно, вам следует сообщить об ошибке сопровождающему пакета Requests этого дистрибутива.

такая же проблема с HTTPie, установленным через apt (ubuntu 14.04lts)

@luv , это удивительно, потому что я точно знаю, что запросы 14.04 и 16.04 используют системное хранилище сертификатов. Как вы устанавливали запросы?

Я удалил все «запросы» и «httpie» версии, чтобы убедиться, что используется дистрибутив ubuntu для httpie, и вы правы, я все еще использовал httpie из PyPI. Ubuntu httpie выдает ошибку «ImportError: невозможно импортировать имя is_windows», что является известной проблемой.

Я думаю, что забыл запустить «pip3 uninstall» и запустил только «pip uninstall», так как мне пришлось использовать python3, чтобы получить работающий ssl.

Прошу прощения у 761 человека, который "спамил" их описанием моей настройки httpie.

Я использую Gentoo Linux, httpie-0.9.9 и requests-2.18.4 (последняя версия, доступная в Gentoo), установленная для всей системы менеджером пакетов, другие версии не установлены (у меня даже не установлен pip). Другие инструменты (openssl s_client, sslclient, curl) обнаруживают установленный локальный сертификат CA и работают нормально, но httpie не работает:

$ openssl s_client -quiet -connect localhost:8082                                              
depth=1 CN = Local CA home.lan
verify return:1
depth=0 CN = localhost
verify return:1
^C
$ http -v https://localhost:8082/                                                              

http: error: SSLError: HTTPSConnectionPool(host='localhost', port=8082): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),)) while doing GET request to URL: https://localhost:8082/

Должен ли я что-то обновить, чтобы оно работало?

@powerman Это более подходящий вопрос для распространителей этих пакетов gentoo.

@ sigmavirus24 Почему? Мой вопрос в том, что эти запросы / версии httpie должны обрабатывать системный список CA или нет. Если да, то, вероятно, в моей системе что-то неправильно настроено или есть ошибка. Если нет, то какая версия мне нужна, чтобы он работал.

@powerman ничего не изменилось. Ни один из них не поддерживает пакеты сертификатов вашей системы, но если вы установили оба из диспетчера пакетов вашего дистрибутива, скорее всего, они исправили программное обеспечение, чтобы использовать их. Если вы использовали пакеты, доступные в Gentoo, и они не используют системные сертификаты, то это проблема Gentoo.

Просто собираюсь добавить один дополнительный комментарий по этому поводу: я использую прокси, который специально разработан таким образом, чтобы, когда вы делаете запросы SSL, он устанавливает безопасный туннель между вами и прокси, а затем еще один между прокси и пунктом назначения. Это делается для того, чтобы я мог безопасно отслеживать трафик, проходящий через мой прокси, чтобы убедиться, что никто не пытается сделать что-то неприятное и скрыть это. К сожалению, это означает, что сертификат, который возвращается httpie, не является доверенным (потому что он находится в системном корне, но httpie его не использует).

Я могу воспроизвести ту же проблему на NixOS.

4+ года спустя ...

Была ли эта страница полезной?
0 / 5 - 0 рейтинги