获取“SSL:Certificate_verify_failed"每当我尝试在 VPS 上使用我的 Discord 机器人登录时 [英] Getting "SSL: Certificate_verify_failed" whenever I try to log in with my Discord bot on VPS
问题描述
我正在将我的机器人从损坏的旧笔记本电脑转移到合适的 VPS.我使用的是 Discord.py (0.16.0) 的较旧异步版本,因为我在重写之前很长时间就开始研究这个东西;而且我对 Linux 没有太多经验,所以迁移到 Windows Server 似乎是谨慎的.我已经安装了所有相同的软件包(据我所知),但我在启动时总是在 bot.run()
行上遇到错误:
I'm moving my bot from my old, broken laptop to a proper VPS. I'm on an older async version of Discord.py (0.16.0), because I started work on this thing a long time before the rewrite was a thing; and I don't have much experience with Linux, so moving to a Windows Server seemed prudent. I've installed all of the same packages (as far as I know), but I'm consistently getting an error on startup, on the bot.run()
line:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:749)
错误发生在握手过程中,据我所知从堆栈跟踪中可以看出,我并不知道这意味着什么.
The error happens during the handshake, so far as I can tell from the stacktrace, not that I'd know what the implications of that are.
此设置已在两台不同的笔记本电脑(尽管运行 Windows 10)上运行多年,没有出现任何问题,并且 discord.py 服务器在 Windows 机器上似乎没有遇到此类问题(它发生在 OS X 上,但是由于 Python 3.6 的一些特性,这也发生在 Python 3.5 中.错误的操作系统也是.)我尝试更改 Python 安装并安装一些自动 Windows 更新,同时运行我在这里和那里找到的一些命令:pip install certifi
和 pip installincremental
.
This setup has worked for several years on two different laptops (albeit running Windows 10) without any issues, and the discord.py server doesn't seem to have encountered such issues on a Windows machine (it happens on OS X, but because of some idiosyncrasy of Python 3.6, and this was also happening in Python 3.5. Wrong OS, too.) I tried changing Python installs and installing some of the automatic Windows updates, along with running some commands I found here and there: pip install certifi
and pip install incremental
.
出于好奇和沮丧,经过几个小时的无所事事后,由于我在一台服务器上有一个测试机器人,我不介意被丢弃,我尝试了在 stackoverflow 讨论中看到的内容
After several hours of nothing out of curiosity: and frustration and owing to the fact that I have a test bot on one server that I don't mind being trashed, I tried from something I saw in a stackoverflow discussion
bot = commands.Bot(
command_prefix='/',
connector=aiohttp.TCPConnector(verify_ssl=False)
)
(添加的行特别是整个 connector
kwarg,以前没有.)
(the added line is specifically the whole connector
kwarg, which was not there before.)
奇怪的是,这改变了堆栈跟踪,但实际上并没有改变错误,如下所示:
The odd thing is, this CHANGED the stacktrace, but didn't actually change the error, as shown below:
在添加 verify_ssl = False 之前,我得到了...
Before adding verify_ssl = False, I was getting...
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 601, in _create_direct_connection
local_addr=self._local_addr)
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 802, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 828, in _create_connection_transport
yield from waiter
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 503, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "C:\Program Files\Python36\lib\ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 304, in connect
yield from self._create_connection(req)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 578, in _create_connection
transport, proto = yield from self._create_direct_connection(req)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 624, in _create_direct_connection
(req.host, req.port, exc.strerror)) from exc
aiohttp.errors.ClientOSError: [Errno 1] Can not connect to discordapp.com:443 [[SSL: CERTIFICATE_VERIFY_FAILED] certific
ate verify failed (_ssl.c:749)]
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "harubotFE98.py", line 43748, in <module> # trust me, I know
bot.run('SNIP')
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 519, in run
self.loop.run_until_complete(self.start(*args, **kwargs))
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete
return future.result()
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 490, in start
yield from self.login(*args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 416, in login
yield from getattr(self, '_login_' + str(n))(*args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 346, in _login_1
data = yield from self.http.static_login(token, bot=is_bot)
File "C:\Program Files\Python36\lib\site-packages\discord\http.py", line 195, in static_login
data = yield from self.get(self.ME)
File "C:\Program Files\Python36\lib\site-packages\discord\http.py", line 105, in request
r = yield from self.session.request(method, url, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 555, in __iter__
resp = yield from self._coro
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 198, in _request
conn = yield from self._connector.connect(req)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 314, in connect
.format(key, exc.strerror)) from exc
aiohttp.errors.ClientOSError: [Errno 1] Cannot connect to host discordapp.com:443 ssl:True [Can not connect to discordap
p.com:443 [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)]]
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x00000224005401D0>
但之后,它被缩短(?)到...
but after, it was shortened(?) to...
Traceback (most recent call last):
File "harubotFE98.py", line 43748, in <module>
bot.run('NOPE')
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 519, in run
self.loop.run_until_complete(self.start(*args, **kwargs))
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete
return future.result()
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 491, in start
yield from self.connect()
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 444, in connect
self.ws = yield from DiscordWebSocket.from_client(self)
File "C:\Program Files\Python36\lib\site-packages\discord\gateway.py", line 175, in from_client
ws = yield from websockets.connect(gateway, loop=client.loop, klass=cls)
File "C:\Program Files\Python36\lib\site-packages\websockets\py35\client.py", line 19, in __await__
return (yield from self.client)
File "C:\Program Files\Python36\lib\site-packages\websockets\client.py", line 150, in connect
factory, wsuri.host, wsuri.port, **kwds)
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 802, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 828, in _create_connection_transport
yield from waiter
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 503, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "C:\Program Files\Python36\lib\ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000021A50E0E358>
我也试过搞乱一个叫做 OpenSSL 的东西,但我能找到的几乎所有关于它的讨论都足够密集,我无法完全理解它.
I've also tried messing with something called OpenSSL, but pretty much any discussion I can find on it is dense enough that I can't quite wrap my head around it.
经过一些混乱,我编写了一些最小脚本来触发错误:
After some messing around, I've written something of a minimum script to get the error to trigger:
import aiohttp
import asyncio
import ssl
async def main():
async with aiohttp.ClientSession() as cs:
async with cs.get("https://www.discordapp.com") as r:
res = await r.text()
print(res)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
返回:
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 924, in _wrap_create_connection
await self._loop.create_connection(*args, **kwargs))
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 802, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 828, in _create_connection_transport
yield from waiter
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 503, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "C:\Program Files\Python36\lib\asyncio\sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "C:\Program Files\Python36\lib\ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test2.py", line 12, in <module>
loop.run_until_complete(main())
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete
return future.result()
File "test2.py", line 7, in main
async with cs.get("https://www.discordapp.com") as r:
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 1005, in __aenter__
self._resp = await self._coro
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 476, in _request
timeout=real_timeout
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 522, in connect
proto = await self._create_connection(req, traces, timeout)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 854, in _create_connection
req, traces, timeout)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 992, in _create_direct_connection
raise last_exc
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 974, in _create_direct_connection
req=req, client_error=client_error)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\connector.py", line 929, in _wrap_create_connection
raise ClientConnectorSSLError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host www.discordapp.com:443 ssl:None [[SSL: CERTIFI
CATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)]
我还尝试了一些其他解决方案,例如使用 Web 客户端访问 discordapp.com:443(有效,但没有解决此问题)并将 python 的 aiohttp 更新到最新版本(没有解决这个问题).
I've also tried a couple of other solutions, such as using a web client to visit discordapp.com:443 (which worked, but did not fix this) and updating python's aiohttp to the most recent build (which did not fix this).
推荐答案
如果您使用的是 Windows Server 2018/2019(我在个人数据中心服务器上尝试过),您可以发出以下命令以允许您的机器人连接.我不得不在管理终端上运行它才能让它工作,但这个命令解决了我的所有问题.
if you are on windows server 2018/2019 (I tried it on a personal Datacenter Server.) you can issue the command below to allow your bot to connect. I had to run it off of an administrative terminal to get it to work but this command fixed all of my problems.
certutil -generateSSTFromWU roots.sst && certutil -addstore -f root roots.sst && del roots.sst
祝你好运!
这篇关于获取“SSL:Certificate_verify_failed"每当我尝试在 VPS 上使用我的 Discord 机器人登录时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!