替换urllib.request.urlopen的开启者(url,ca *)

时间:2014-10-03 15:25:11

标签: python ssl ssl-certificate urllib

我正在尝试让Python urllib.request.urlopen(url, ca*)执行证书检查,但忽略主机名不匹配。

(这是必需的,因为可以通过公共IP,私有IP,主机名或FQDN访问主机,并且我不想依赖证书来拥有所有这些有效字段)

根据官方文档,我可以使用自定义开启工具HTTPSHandler来禁用主机名检查(https://docs.python.org/3/library/urllib.request.html

但是,由于Python Issue18543(http://bugs.python.org/issue18543),如果指定了任何ca *参数,urllib.request.urlopen()将忽略已安装的opener。

我的问题是:

解决此问题的最佳方法是什么?我应该尝试覆盖urllib.request.urlopen()方法吗?如果是这样,这是如何以pythonic方式完成的? 还有其他选择吗?我真的不想重写和维护很多基本代码。

到目前为止我的代码(不工作)如下:

import ssl
import urllib.request  # used to be import urllib2 in python 2.x

#create an HTTPS Handler that does not check the hostname
https_handler = urllib.request.HTTPSHandler(debuglevel=0, check_hostname=False)

opener = urllib.request.build_opener(https_handler)
urllib.request.install_opener(opener)

# PROBLEM is that this opener will not be used by urlopen.
# solution: override the urlopen method?

# verify server certificate
try:
    urllib.request.urlopen("https://127.0.0.1:4443", cafile="cert.pem")

except ssl.CertificateError as e:
    print ("Certificate Error:",e)
    return -1
return 0

运行代码会出现有关主机名不匹配的证书错误。

此问题也在这里讨论过: http://www.gossamer-threads.com/lists/python/bugs/1005966?do=post_view_threaded

特别是这篇文章提出了一个解决方法: http://www.gossamer-threads.com/lists/python/bugs/1006048?do=post_view_threaded#1006048

1 个答案:

答案 0 :(得分:0)

这似乎不是一项微不足道的任务,从长远来看大多数解决方案都不可靠。

我想发布我选择解决此问题的解决方案。

首先,我选择使用urllib3库(https://pypi.python.org/pypi/urllib3)。

从文档中,我发现最容易使用PoolManager:

import urllib3

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                           ca_certs="cert.pem",
                           assert_hostname=False)
try:
    r = http.request('GET', 'https://127.0.0.1:4443/')
    print("STATUS:", r.status)
    print("Certificate verification NO HOSTNAME successful")

except urllib3.exceptions.SSLError as e:
    print ("SSL Error:", e)
    return -1

return 0

请注意,在urllib3 verison 1.10中忽略assert_hostname = False: https://github.com/shazow/urllib3/issues/524