Httpie: HTTPie忽略系统证书

创建于 2016-06-09  ·  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,将其传递给请求验证
6)否则将True传递给请求验证

但请注意ssl.get_default_verify_paths仅从python3.4起可用

@luv不仅仅在3.4+和2.7.10+中可用,而且不适用于所有平台。 这就是为什么请求正在处理自己的问题以为人们解决此问题的原因。 请停止对httpie不断发表评论。 这是请求而不是httpie IMO中存在的问题。

@ sigmavirus24 wtf男人? 不知道您不断评论的意思,但是无论如何,我发现您甚至都不是httpie贡献者。 我假设只是一个愚蠢的巨魔:/

快速浏览一下curl源代码,看看有效的实现是什么样的...。

不管所有那些amiga和VMS ifdef以及对许多不同的ssl库的支持,它实际上都是很愚蠢的,并且没有使用openssl X509_ *查找方法(例如,在Python SSL模块的get_default_verify_paths()中使用)。

取而代之的是,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()之类的东西)。 而已。

那么在纯python中实现相同的方法呢? (是的,它看起来像是在地狱般快速又肮脏,但是它可以卷发!)但是增加了对Windows(ssl.enum_certificates?)和OS X的支持(不确定此处,但是python似乎使用了OS X 10.6+上苹果提供的openssl库)这样就可以了!)。

@luv感谢您的举报,但请更尊重其他成员。 @ sigmavirus24是httpie依赖于所有HTTP的请求的核心开发者,而如果没有HTTPie,它甚至将不存在,因此他的观点极为相关。

请注意,直到3.0.0发行版,此请求才会得到解决。由于可能的兼容性问题,甚至不支持SSL_CERT_FILE https://github.com/kennethreitz/requests/pull/2903

顺便说一句我并不是要不尊重我,我真的以为他/他正在拖钓:)我竭尽全力帮助找到问题的解决方案,甚至没有一个曾经为该项目做过贡献的人(我检查了HTTPie的贡献者,因为我真的被这样的敌意所震惊)基本上是告诉我闭嘴:/

@luv我不是在告诉你闭嘴。 有763人订阅了此问题。 其中100%可能会为此收到电子邮件(但可能更像是70%或〜534)。 这意味着您(在问题打开后的两个小时内)产生了约1602封电子邮件(可能或多或少)。 换句话说,您正在通过此类有意识的帖子向用户发送垃圾邮件。 当没人回复您时,记录新信息的最佳方法是编辑原始帖子。

最后,代码贡献并不是对项目的唯一贡献。 如果要查看某个项目的所有贡献,可以使用octohatrack之类的项目。 我已经对@jkbrzt上httpie上的几个与请求相关的错误做出了响应,因为它们没有足够的时间来跟踪请求的开发。 当我在此处看到与请求相关的错误时,我会做出回应,因为99%的时间已经在处理它。 幸运的是, @ jkbrzt之前我被当作很差的人(而且还差了几倍),所以我的皮肤更粗了。

附带说明一下,“他们”与“他/她”一样多,而且更广泛地适用,因为它也可以用于指代一个人。

那么我们能解决这个问题吗?

@jkbrzt我将其称为功能,而不是错误。 故意在Windows,* nixes和BSD上使Requests相同地工作,并且实际上,许多Requests的系统发行版都主动删除了该行为并指向系统证书存储/捆绑。 因此,如果用户需要此行为,则可以将其系统分发者打包的Requests版本与HTTPie(可能还有系统打包的HTTPie)一起使用。

至于“获得此固定”,这取决于您对固定的定义。 _will_将添加到请求的此功能。 此时,HTTPie将免费获得该行为。 如果HTTPie认为此优先级更高( @jkbrzt可能会认为合适),则他们可以重复开发工作来创建一个可以尽快完成此任务的发行版。

似乎您正在使用@luv linux,您可以利用以下事实:您的linux发行版几乎肯定具有使用系统证书存储的Requests版本。 在我检查过的每个Linux发行版中都打包了请求,这些发行版中的几乎每个发行版都使用其系统证书存储。 如果不是这种情况,也许您应该向该发行版的Requests软件包维护者提交错误。

与通过apt(ubuntu 14.04lts)安装的HTTPie相同的问题

@luv令人惊讶,因为我知道14.04和16.04上的请求使用系统证书库。 您是如何安装请求的?

我清除了所有“请求”和“ httpie”版本,以验证是否使用了httpie的ubuntu发行版,您是对的,我仍在使用PyPI中的httpie。 Ubuntu httpie失败,并显示“ ImportError:无法导入名称is_windows”,这是一个已知问题。

我想我忘记运行“ pip3卸载”,而只运行“ pip卸载”,因为我必须首先使用python3来获得可工作的ssl。

我向761个人致歉,并向其发送有关我的httpie设置的描述。

我使用的是通过包管理器在系统范围内安装的Gentoo Linux,httpie-0.9.9和request-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 等级

相关问题

filipesperandio picture filipesperandio  ·  3评论

cunde picture cunde  ·  7评论

ghost picture ghost  ·  5评论

rshurts picture rshurts  ·  5评论

pyvotal-cguers picture pyvotal-cguers  ·  5评论