Python 2.7 为什么urllib3/idna抱怨X509证书中存在通配符?我怎么修理它?

Python 2.7 为什么urllib3/idna抱怨X509证书中存在通配符?我怎么修理它?,python-2.7,wildcard,x509certificate,urllib3,treasure-data,Python 2.7,Wildcard,X509certificate,Urllib3,Treasure Data,我在虚拟环境下运行,具有以下功能: setuptools==26.1.1 td-client==0.5.0 urllib3[secure]==1.17 如果我不使用urllib3,则由于SNIMissingWarning而使用urllib3: 我还拥有用户指南中列出的所需系统包: dpkg -l | grep build-essential ii build-essential 11.6ubuntu6

我在虚拟环境下运行,具有以下功能:

setuptools==26.1.1
td-client==0.5.0
urllib3[secure]==1.17
如果我不使用urllib3,则由于SNIMissingWarning而使用urllib3:

我还拥有用户指南中列出的所需系统包:

dpkg -l | grep build-essential
ii  build-essential                      11.6ubuntu6                         amd64        Informational list of build-essential packages
dpkg -l | grep libssl-dev
ii  libssl-dev:amd64                     1.0.1f-1ubuntu2.7                   amd64        Secure Sockets Layer toolkit - development files
dpkg -l | grep libffi-dev
ii  libffi-dev:amd64                     3.1~rc1+r3.0.13-12                  amd64        Foreign Function Interface library (development files)
dpkg -l | grep "\spython-dev\s"
ii  python-dev                           2.7.5-5ubuntu3                      amd64        header files and a static library for Python (default)
这是我的密码:

#!./venv/bin/python

from argparse import ArgumentParser
import logging
import tdclient
import urllib3.contrib.pyopenssl
import certifi
import urllib3

def main():
    for key in logging.Logger.manager.loggerDict:
            if key == "tdclient.api": continue
            if key == "tdclient": continue
            logging.getLogger(key).setLevel(logging.DEBUG)
    urllib3.contrib.pyopenssl.inject_into_urllib3()
    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
    key = getKey()
    listTdTables(key)

def listTdTables(key):
    with tdclient.Client(key) as client:
            for db in client.databases():
                    for table in db.tables():
                            print(table.db_name)
                            print(table.table_name)
                            print(table.count)

def getKey():
    parser = ArgumentParser()
    parser.add_argument("-k", "--key", dest="key", help="key", required=True)
    options = parser.parse_args()
    return options.key

if __name__ == "__main__":
    main()
我得到的是:

Traceback (most recent call last):
  File "./akamai_pusher.py", line 35, in <module>
    main()
  File "./akamai_pusher.py", line 18, in main
    listTdTables(key)
  File "./akamai_pusher.py", line 22, in listTdTables
    for db in client.databases():
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/tdclient/client.py", line 81, in databases
    databases = self.api.list_databases()
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/tdclient/database_api.py", line 21, in list_databases
    with self.get("/v3/database/list") as res:
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/tdclient/api.py", line 174, in get
    response = self.send_request("GET", url, fields=params, headers=headers, decode_content=True, preload_content=False)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/tdclient/api.py", line 345, in send_request
    return self.http.request(method, url, fields=fields, **kwargs)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 66, in request
    **urlopen_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 87, in request_encode_url
    return self.urlopen(method, url, **extra_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/poolmanager.py", line 244, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 594, in urlopen
    chunked=chunked)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 350, in _make_request
    self._validate_conn(conn)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 833, in _validate_conn
    conn.connect()
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/connection.py", line 324, in connect
    cert = self.sock.getpeercert()
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 312, in getpeercert
    'subjectAltName': get_subj_alt_name(x509)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 185, in get_subj_alt_name
    for name in ext.get_values_for_type(x509.DNSName)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 141, in _dnsname_to_stdlib
    name = idna.encode(name)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/idna/core.py", line 276, in alabel
    check_label(label)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1473977463594675887/venv/local/lib/python2.7/site-packages/idna/core.py", line 253, in check_label
    raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
idna.core.InvalidCodepoint: Codepoint U+002A at position 1 of u'*' not allowed
然后是代码:

#!./venv/bin/python

import urllib3.contrib.pyopenssl
import certifi
import urllib3
import sys
import traceback

def main():
    urllib3.contrib.pyopenssl.inject_into_urllib3()
    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
    try:
            print("*********** https://www.google.com ***********")
            print(http.request('GET', 'https://www.google.com', timeout=4.0))
            print("********** https://www.facebook.com **********")
            print(http.request('GET', 'https://www.facebook.com', timeout=4.0))
            print("**********************************************")
    except:
            traceback.print_exc(limit=None, file=sys.stderr)
    finally:
            print("**********************************************")

if __name__ == "__main__":
    main()
我得到了以下输出:

*********** https://www.google.com ***********
Traceback (most recent call last):
  File "./akamai_pusher.py", line 14, in main
    print(http.request('GET', 'https://www.google.com', timeout=4.0))
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474000948101039366/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 66, in request
    **urlopen_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474000948101039366/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 87, in request_encode_url
    return self.urlopen(method, url, **extra_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474000948101039366/venv/local/lib/python2.7/site-packages/urllib3/poolmanager.py", line 244, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474000948101039366/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 624, in urlopen
    raise SSLError(e)
SSLError: bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)
**********************************************
有人建议我将certifi的版本降级至2015.4.28:

setuptools==26.1.1
certifi==2015.4.28
urllib3[secure]==1.17
这对谷歌链接起到了作用。但facebook链接的情况并非如此,该链接的最终问题与td客户的问题相同:

*********** https://www.google.com ***********
<urllib3.response.HTTPResponse object at 0x7fc1d8942590>
********** https://www.facebook.com **********
Traceback (most recent call last):
  File "./akamai_pusher.py", line 16, in main
    print(http.request('GET', 'https://www.facebook.com', timeout=4.0))
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 66, in request
    **urlopen_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/request.py", line 87, in request_encode_url
    return self.urlopen(method, url, **extra_kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/poolmanager.py", line 244, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 594, in urlopen
    chunked=chunked)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 350, in _make_request
    self._validate_conn(conn)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/connectionpool.py", line 833, in _validate_conn
    conn.connect()
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/connection.py", line 324, in connect
    cert = self.sock.getpeercert()
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 312, in getpeercert
    'subjectAltName': get_subj_alt_name(x509)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 185, in get_subj_alt_name
    for name in ext.get_values_for_type(x509.DNSName)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 141, in _dnsname_to_stdlib
    name = idna.encode(name)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/idna/core.py", line 276, in alabel
    check_label(label)
  File "/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site-packages/idna/core.py", line 253, in check_label
    raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
InvalidCodepoint: Codepoint U+002A at position 1 of u'*' not allowed
**********************************************
**********https://www.google.com ***********
********** https://www.facebook.com **********
回溯(最近一次呼叫最后一次):
文件“/akamai_pusher.py”,第16行,主视图
打印(http.request('GET','https://www.facebook.com,超时=4.0)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/request.py”,请求中第66行
**urlopen(千瓦)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/request.py”,请求编码url中第87行
返回self.urlopen(方法,url,**额外\u kw)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/poolmanager.py”,第244行,在urlopen中
response=conn.urlopen(方法,u.request\u uri,**kw)
urlopen中的文件“/mnt/home/marc/repos/akamai_pusher/versions/147400158486864131764/venv/local/lib/python2.7/site packages/urllib3/connectionpool.py”,第594行
分块=分块)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/connectionpool.py”,第350行,请求
自我验证连接(连接)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/connectionpool.py”,第833行,位于康涅狄格州
连接
文件“/mnt/home/marc/repos/akamai_pusher/versions/147400158486864131764/venv/local/lib/python2.7/site packages/urllib3/connection.py”,第324行,连接
cert=self.sock.getpeercert()
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/contrib/pyopenssl.py”,第312行,在getpeercert中
“subjectAltName”:获取SubjectAlt名称(x509)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/contrib/pyopenssl.py”,第185行,位于get_subject_alt_name中
对于ext.get_类型(x509.DNSName)中的名称
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/urllib3/contrib/pyopenssl.py”,第141行,在dnsname to stdlib中
name=idna.encode(名称)
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/idna/core.py”,第355行,编码
结果.追加(阿拉贝尔(标签))
文件“/mnt/home/marc/repos/akamai_pusher/versions/1474001584864131764/venv/local/lib/python2.7/site packages/idna/core.py”,第276行,阿拉伯文
检查标签(标签)
文件“/mnt/home/marc/repos/akamai_pusher/versions/147400158486864131764/venv/local/lib/python2.7/site packages/idna/core.py”,第253行,在检查标签中
raise InvalidCodepoint({2}的位置{1}处的代码点{0}不允许)。格式(_unot(cp_值),pos+1,repr(标签)))
InvalidCodepoint:U'*'位置1处的代码点U+002A不允许
**********************************************

所以我发现了问题:urllib3 v1.17(至少在python 2.7下)。我降级到v1.16和viola,代码运行正常。(v1.17在9天前刚刚发布)以下是适用于我的依赖项:

setuptools==26.1.1
certifi==2015.4.28
urllib3[secure]==1.16
td-client==0.5.0
我想可能与此有关:

从用于PyOpenSSL的依赖项中删除了pyasn1和ndg HttpSCClient。我们现在使用加密和idna,它们都已经是PyOpenSSL的依赖项。(PR#930)

工作代码:

#!./venv/bin/python

import urllib3.contrib.pyopenssl
from argparse import ArgumentParser
import tdclient
import certifi
import urllib3

def main():
    urllib3.contrib.pyopenssl.inject_into_urllib3()
    key = getKey()
    listTdTables(key)
    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
    print(http.request('GET', 'https://www.google.com', timeout=4.0))
    print(http.request('GET', 'https://www.facebook.com', timeout=4.0))

def getKey():
    parser = ArgumentParser()
    parser.add_argument("-k", "--key", dest="key", help="key", required=True)
    options = parser.parse_args()
    return options.key

def listTdTables(key):
    with tdclient.Client(key) as client:
            for db in client.databases():
                    for table in db.tables():
                            print(table.db_name)
                            print(table.table_name)
                            print(table.count)

if __name__ == "__main__":
    main()

所以我发现了问题:urllib3 v1.17(至少在python 2.7下)。我降级到v1.16和viola,代码运行正常。(v1.17在9天前刚刚发布)以下是适用于我的依赖项:

setuptools==26.1.1
certifi==2015.4.28
urllib3[secure]==1.16
td-client==0.5.0
我想可能与此有关:

从用于PyOpenSSL的依赖项中删除了pyasn1和ndg HttpSCClient。我们现在使用加密和idna,它们都已经是PyOpenSSL的依赖项。(PR#930)

工作代码:

#!./venv/bin/python

import urllib3.contrib.pyopenssl
from argparse import ArgumentParser
import tdclient
import certifi
import urllib3

def main():
    urllib3.contrib.pyopenssl.inject_into_urllib3()
    key = getKey()
    listTdTables(key)
    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
    print(http.request('GET', 'https://www.google.com', timeout=4.0))
    print(http.request('GET', 'https://www.facebook.com', timeout=4.0))

def getKey():
    parser = ArgumentParser()
    parser.add_argument("-k", "--key", dest="key", help="key", required=True)
    options = parser.parse_args()
    return options.key

def listTdTables(key):
    with tdclient.Client(key) as client:
            for db in client.databases():
                    for table in db.tables():
                            print(table.db_name)
                            print(table.table_name)
                            print(table.count)

if __name__ == "__main__":
    main()

您初始化了一个池管理器,但似乎没有在任何地方使用它。你能用你的池管理器分享代码吗?我添加池管理器的唯一原因是用户指南创建了一个。实际上,我只感兴趣的是通过调用urllib3.contrib.pyopenssl.inject_-into_-urllib3(),让tdclient库使用urllib。PoolManager的实例化应该只显示urllib3库安装正确(我认为)。在任何情况下,我都直接使用池管理器创建了一个测试用例。我把它贴在上面。我现在正在搬家。但我创建了一个问题,以便其他人能够修复此问题或帮助您使用1.17。您初始化了poolmanager,但似乎在任何地方都没有使用它。你能用你的池管理器分享代码吗?我添加池管理器的唯一原因是用户指南创建了一个。实际上,我只感兴趣的是通过调用urllib3.contrib.pyopenssl.inject_-into_-urllib3(),让tdclient库使用urllib。PoolManager的实例化应该只显示urllib3库安装正确(我认为)。在任何情况下,我都直接使用池管理器创建了一个测试用例。我把它贴在上面。我现在正在搬家。但我创建了一个问题,以便其他人能够解决此问题或帮助您使用1.17。