为什么Python的`requests`拒绝我的浏览器可接受的SSL证书

6 投票
1 回答
3628 浏览
提问于 2025-04-18 03:20

我最近为我的网站申请了一个SSL证书:

https://ram.rachum.com/

在浏览器中运行得很好。但是在使用requests时却失败了:

>>> import requests
>>> requests.get('https://ram.rachum.com')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    requests.get('https://ram.rachum.com')
  File "C:\Python27\lib\site-packages\requests\api.py", line 55, in get
    return request('get', url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 354, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 460, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests\adapters.py", line 250, in send
    raise SSLError(e)
SSLError: hostname 'ram.rachum.com' doesn't match either of '*.webfaction.com', 'webfaction.com'

这是为什么呢?为什么requests会查看webfaction的证书,而不是我自己为ram.rachum.com申请的有效证书呢?

1 个回答

9

你正在使用一个请求库,但这个库不支持SNI(服务器名称指示)。而你有多个SSL证书都在同一个IP地址下,这就需要SNI来区分。你可以用openssl s_client来验证这一点。如果没有提供SNI的名称,服务器就会返回这个IP的默认证书,也就是*.webfaction.com:

openssl s_client -connect ram.rachum.com:443
...
 0 ...CN=*.webfaction.com

但是如果你为SNI指定一个主机名,它就会返回你期望的证书:

openssl s_client -connect ram.rachum.com:443 -servername ram.rachum.com
...
 0 ...CN=ram.rachum.com...

也许你需要升级你的请求库和其他模块,具体可以参考这个链接:使用请求库与TLS时不支持SNI

撰写回答