Я не совсем понимаю обсуждение проблемы № 480, но я думаю, что основная причина этой проблемы может быть такой же. Мне нужен httpie, чтобы доверять самозаверяющему сертификату. Технически это самозаверяющий промежуточный центр сертификации, но я могу использовать один из реальных сертификатов сервера от этого центра и получить тот же результат. Этот сертификат подходит для всех других приложений на моем Mac (OS 10.12), включая curl. Httpie ему просто не поверит. Пример вывода:
$ http --debug -j --verify=/usr/local/etc/openssl/certs/intermediate-authority.pem https://www.testdomain.com/robots.txt
HTTPie 0.9.9
Requests 2.12.3
Pygments 2.1.3
Python 3.6.1 (default, Mar 24 2017, 17:14:46)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
/usr/local/Cellar/httpie/0.9.9/libexec/bin/python3.6
Darwin 16.5.0
<Environment {
"colors": 256,
"config": {
"__meta__": {
"about": "HTTPie configuration file",
"help": "https://github.com/jkbrzt/httpie#config",
"httpie": "0.9.4"
},
"default_options": "[]"
},
"config_dir": "/Users/username/.httpie",
"is_windows": false,
"stderr": "<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>",
"stderr_isatty": true,
"stdin": "<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>",
"stdin_encoding": "UTF-8",
"stdin_isatty": true,
"stdout": "<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>",
"stdout_encoding": "UTF-8",
"stdout_isatty": true
}>
>>> requests.request(**{
"allow_redirects": false,
"auth": "None",
"cert": "None",
"data": "",
"files": {},
"headers": {
"Accept": "application/json, */*",
"Content-Type": "application/json",
"User-Agent": "HTTPie/0.9.9"
},
"method": "get",
"params": {},
"proxies": {},
"stream": true,
"timeout": 30,
"url": "https://www.testdomain.com/robots.txt",
"verify": "/usr/local/etc/openssl/certs/intermediate-authority.pem"
})
http: error: SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) while doing GET request to URL: https://www.testdomain.com/robots.txt
Traceback (most recent call last):
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 588, in urlopen
self._prepare_proxy(conn)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 801, in _prepare_proxy
conn.connect()
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/packages/urllib3/connection.py", line 323, in connect
ssl_context=context)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/packages/urllib3/util/ssl_.py", line 324, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 401, in wrap_socket
_context=self, _session=session)
File "/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 808, in __init__
self.do_handshake()
File "/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1061, in do_handshake
self._sslobj.do_handshake()
File "/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/adapters.py", line 423, in send
timeout=timeout
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 624, in urlopen
raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/bin/http", line 11, in <module>
load_entry_point('httpie==0.9.9', 'console_scripts', 'http')()
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/httpie/__main__.py", line 11, in main
sys.exit(main())
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/httpie/core.py", line 227, in main
log_error=log_error,
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/httpie/core.py", line 99, in program
final_response = get_response(args, config_dir=env.config.directory)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/httpie/client.py", line 70, in get_response
response = requests_session.request(**kwargs)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/Cellar/httpie/0.9.9/libexec/lib/python3.6/site-packages/requests/adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
Если я использую --verify=no
, соединение принимается. Я попытался преобразовать файл сертификата в формат DER вместо PEM без изменений.
Httpie был установлен через Homebrew, который установил свой собственный Python3 в качестве зависимости.
Никогда не рекомендуется доверять самозаверяющему сертификату. Опасно, если программа принимает его по умолчанию. Хакер может просто ввести самоподписанный, чтобы пользователи чувствовали себя в безопасности, хотя это не так.
Однако я бы посоветовал httpie
ответить на вопрос об использовании самозаверяющего сертификата более четким сообщением, а не просто отказать. Было бы замечательно предложить использовать --verify=no
для отключения проверки в целях тестирования.
@ giskard22
Я не совсем понимаю обсуждение проблемы № 480, но я думаю, что основная причина этой проблемы может быть такой же. Мне нужен httpie, чтобы доверять самозаверяющему сертификату. Технически это самозаверяющий промежуточный центр сертификации, но я могу использовать один из реальных сертификатов сервера от этого центра и получить тот же результат.
Глядя на # 480, это не та же основная причина. HTTPie в этом случае использует предоставленный вами пакет.
Я подозреваю, что на самом деле причина в следующем:
Ваш «тестовый домен» возвращает не всю цепочку сертификатов, а только ее лист (который отлично работает для браузеров, которые могут динамически извлекать остальную часть цепочки), но не для httpie и других клиентов, не являющихся браузерами. В этом случае вы предоставляете часть цепочки через --verify
но не всех посредников. Если вы поместите их все в один комплект и предоставите это вместо этого, я подозреваю, вы обнаружите, что это работает.
Никогда не рекомендуется доверять самозаверяющему сертификату. Опасно, если программа принимает его по умолчанию. Хакер может просто ввести самоподписанный, чтобы пользователи чувствовали себя в безопасности, хотя это не так.
Советы @alvis blanket обычно неверны, и в данном случае они совершенно неверны. Самозаверяющие сертификаты - это решение проблемы. Я не знаю, как использовать здесь самоподписанный сертификат @ giskard22, и вы тоже. В этом случае ваш совет, скорее всего, бесполезен не только для @ giskard22 , но и для остальных людей, получающих уведомления по электронной почте о проблемах в этом репозитории.
Самозаверяющие сертификаты могут быть опасными для доверия без проверки, но в этом случае кажется, что @ giskard22 знает цепочку доверия и доверяет ей, что делает такое использование совершенно безопасным. Да, если вы попали на сайт, использующий HTTPS, на который вам может потребоваться ввести конфиденциальную информацию, не рекомендуется использовать самозаверяющий сертификат, но это совершенно другая ситуация, насколько я понимаю.
Да, здесь используется httpie через корпоративный веб-прокси, который выполняет HTTPS-посредник, чтобы проверять трафик. Он генерирует сертификат для домена на лету. Мля.
Я не понимаю, как отказ прокси-сервера предоставить полную цепочку сертификатов вызывает эту проблему. Возможно, поведение OpenSSL (или это поведение Python?) Отличается от встроенного механизма MacOS.
Цепочка доверия для подключений через прокси выглядит так:
Мне не удалось получить сертификат 3. Однако сертификат 2 доступен через прокси-сервер. Я импортировал в свою Связку ключей и пометил ее как надежную для использования SSL. Этого было достаточно, чтобы удовлетворить все на моем Mac, кроме httpie, включая другие инструменты командной строки, такие как curl. Наблюдаемое поведение заключается в том, что механизм проверки следует по цепочке, пока не найдет доверенный сертификат, а затем останавливается. Отсутствие корневого сертификата не имеет значения.
В выводе отладки httpie, который я опубликовал в своем первоначальном отчете, я сохранил сертификат 2 в intermediate-authority.pem
и указал этот файл с помощью --verify
. Вы хотите сказать, что для httpie этого недостаточно, и я также должен предоставить сертификат 3?
Возможно, поведение OpenSSL (или это поведение Python?) Отличается от встроенного механизма MacOS.
Итак, OpenSSL будет искать в пакете, который вы ему предоставляете, все, что ему не хватает. Если он не может найти его там, он не проходит проверку. Это также транзитивное поведение Python. SecureTransport (встроенный механизм MacOS) работает несколько иначе, но только если сертификаты находятся в связке ключей MacOS. Кроме того, в MacOS Python по умолчанию имеет взломанную (из-за отсутствия лучшего термина) версию OpenSSL, которая использует Keychain и, таким образом, может разрешить их, даже если вы предоставите ему свой собственный пакет сертификатов (то есть, если вы укажете ему только доверять Что находится в файле пакета, он скажет: «LOL, но у меня есть доступ к Keychain, и он доверяет ему, так что YOLO» ... или YOVO? (You Only Verify Once ... Idk)).
Если вся цепочка доверия для этих «на лету» сертификатов - это то, что вы описали, я думаю, вы сможете обойтись без пакета, который включает только звенья 2 и 3 в цепочке.
Кроме того, если вы установили httpie
из homebrew
на MacOS, тогда он был установлен с домашними версиями OpenSSL
, Python
и virtualenv
вот почему он не может воспользоваться взломанным OpenSSL Mac.
Наконец-то я смог идентифицировать и получить самоподписанный корневой сертификат. После помещения как этого сертификата, так и промежуточного сертификата в файл .pem и использования этого файла с --verify
я больше не получал ошибку SSL. Это хорошо! Как и предполагалось, OpenSSL требует всей цепочки сертификатов. В отличие от SecureTransport, он не принимает частичную цепочку, даже если она введена вручную.
Есть мысли о следующем дополнительном усложнении? Прокси-сервер позволяет трафику попадать в определенные домены, не вставляя собственный сертификат. Похоже, вы не можете использовать несколько аргументов --verify
. Побеждает последний. Есть ли способ использовать несколько пакетов сертификатов?
У меня есть обходной путь, который включает объединение предоставленного OpenSSL пакета корневого CA и настраиваемого пакета по запросу, но я надеюсь этого избежать.
Итак, OpenSSL поддерживает предоставление каталога, полного файлов .pem
для проверки. Тем не менее, поддержка этого в Python нечеткая. Честно говоря, я не думаю, что что-либо старше Python 3.5 или 3.6 поддерживает каталоги в стандартной библиотеке, и я не помню, будет ли это поддерживать pyOpenSSL. Суть в том, что я не думаю, что вы сможете достичь своих целей, не имея одного .pem
файла
Старый почтальон спешит на помощь. Вы можете отключить обнаружение самоподписанного сертификата.
SSL - это хорошо, наверное, разработчики это знают. Отключение SSL из-за угловых случаев и языковых ограничений или чего-то еще. Я знаю, что люди просто хотят, чтобы работа была сделана. Мне просто интересно, когда мы скажем, что SSL - это хорошо, и у нас будет такая же внутренняя реакция, когда мы скажем «отключить проверку SSL». Если вы отключите проверку SSL, SSL будет отключен. Но SSL - это хорошо. Мы все это знаем, верно? Это сбивает с толку или общеизвестно, что проверка SSL - это действительно все, что есть в SSL? Если у почтальона есть возможность отключить проверку SSL, это просто причудливый способ сказать что-то потенциально небезопасное? curl имеет ту же опцию, что и флаг под названием --insecure
. Это просто причудливый способ, который точно скрывает, в чем проблема (отключает SSL)? Думаю, в Postman можно потестить. TIL, что у Почтальона есть такая возможность. Я собираюсь снова его включить? Или я просто отключил SSL для всех текущих и будущих проектов? Я отправляю ключи API из кафе? : |
Я надеюсь, что машины https dev, самозаверяющие сертификаты и корпоративные центры сертификации однажды будут вытеснены автоматическими сертификатами letsencrypt с поддержкой сценариев. Жаль, что python делает http менее органичным, доверяя системному хранилищу keychain / ssl. Это замена локонов, за исключением этой области. Думаю, у golang есть обнаружение операционной системы для всего этого. Таким образом, современная замена curl (например, bat), написанная на go, будет иметь хороший вывод, приятный интерфейс командной строки и обрабатывать настраиваемые центры сертификации или завершение SSL (балансировщики нагрузки).
SSL - это хорошо, наверное, разработчики это знают. Отключение SSL из-за угловых случаев и языковых ограничений или чего-то еще. Я знаю, что люди просто хотят, чтобы работа была сделана. Мне просто интересно, когда мы скажем, что SSL - это хорошо, и у нас будет такая же внутренняя реакция, когда мы скажем «отключить проверку SSL». Если вы отключите проверку SSL, SSL будет отключен. Но SSL - это хорошо. Мы все это знаем, верно? Это сбивает с толку или общеизвестно, что проверка SSL - это действительно все, что есть в SSL? Если у почтальона есть возможность отключить проверку SSL, это просто причудливый способ сказать что-то потенциально небезопасное? curl имеет ту же опцию, что и флаг под названием
--insecure
. Это просто причудливый способ, который точно скрывает, в чем проблема (отключает SSL)? Думаю, в Postman можно потестить. TIL, что у Почтальона есть такая возможность. Я собираюсь снова его включить? Или я просто отключил SSL для всех текущих и будущих проектов? Я отправляю ключи API из кафе? : |Я надеюсь, что машины https dev, самозаверяющие сертификаты и корпоративные центры сертификации однажды будут вытеснены автоматическими сертификатами letsencrypt с поддержкой сценариев. Жаль, что python делает http менее органичным, доверяя системному хранилищу keychain / ssl. Это замена локонов, за исключением этой области. Думаю, у golang есть обнаружение операционной системы для всего этого. Таким образом, современная замена curl (например, bat), написанная на go, будет иметь хороший вывод, приятный интерфейс командной строки и обрабатывать настраиваемые центры сертификации или завершение SSL (балансировщики нагрузки).
Нет, не хорошо. Необходимо иметь возможность завивать, даже если сертификат разработчика adhoc.
Самый полезный комментарий
Никогда не рекомендуется доверять самозаверяющему сертификату. Опасно, если программа принимает его по умолчанию. Хакер может просто ввести самоподписанный, чтобы пользователи чувствовали себя в безопасности, хотя это не так.
Однако я бы посоветовал
httpie
ответить на вопрос об использовании самозаверяющего сертификата более четким сообщением, а не просто отказать. Было бы замечательно предложить использовать--verify=no
для отключения проверки в целях тестирования.