【问题标题】:Can't get SSL to work for a Secure Websocket connection无法让 SSL 用于安全 Websocket 连接
【发布时间】:2018-08-29 01:54:08
【问题描述】:

我是 Python 新手,但必须构建一个 Websocket API 才能工作。 websockets 模块的网站说这段代码应该适用于安全的 websocket 连接 (https://websockets.readthedocs.io/en/stable/intro.html)

但是,我无法让提供的代码工作..

import websockets
import asyncio
import pathlib
import ssl

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.load_verify_locations(pathlib.Path(__file__).with_name('localhost.pem'))

我得到错误:

Traceback(最近一次调用最后一次):

文件“/Applications/Python 3.7/apii.py”,第 7 行,在模块中> ssl_context.load_verify_locations(pathlib.Path(__ file__).with_name('localhost.pem'))

FileNotFoundError: [Errno 2] 没有这样的文件或目录

你能帮帮我吗?

PS。我根本不了解这个 ssl_context 代码。有人能解释一下它背后的逻辑吗?

【问题讨论】:

  • “我根本不明白这个 ssl_context 代码的概念。” - 我认为这个问题太宽泛了。我的猜测是,您首先需要对 SSL/TLS 的工作原理有一个基本的了解——网上有很多资源可以解释这一点。至于 “没有这样的文件或目录” - 如错误消息所述,给定文件可能不存在。
  • 这段代码是由 websockets 库的创建者提供的,所以我猜这个文件应该是默认的。我在我的硬盘驱动器上找不到这样的文件...您能否仅在您能提供帮助的情况下回答。您的回答没有给我任何澄清问题。
  • “所以我猜这个文件应该是默认存在的。” - 猜错了。这段代码只是显示基本用法的示例代码。而且,在此示例代码前面,您会发现“请参阅 ssl 模块的文档以安全地配置上下文”。因此,希望对 ssl 以及它在 Python 中的使用方式有所了解,这并不特定于 websockets。请花点时间先学习documentation of the ssl module,同时学习 SSL/TLS 的基本概念。
  • 明白。谢谢(你的)信息!如果有人能给我一个让 ssl 上下文运行的示例代码(即使它不是“安全”的),我将不胜感激。
  • 我不会为了好玩而使用/禁用 SSL,否则服务器不允许我连接..

标签: python-3.x ssl websocket


【解决方案1】:

我从 docker 容器测试 websocket。我有 NAT ips(不能使用 LetsEncrypt),并且没有 * 域证书。如果我直接在 Firefox 中进行测试,它可以在没有任何证书的情况下正常工作。因此,应允许在防火墙内禁用 SSL 以进行测试。

摘录:

import asyncio
import websockets
import ssl
:    
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

async def logIn(uri, myjson):
    async with websockets.connect(uri) as websocket:
        await websocket.send(myjson)

async def logIn(uri, myjson):
    async with websockets.connect(uri, ssl=ssl_context) as websocket:
        await websocket.send(myjson)
        resp = await websocket.recv()
        print(resp)

myurl = f"wss://{args.server}:{args.port}"
print("connection url:{}".format(myurl))

# logdef is the json string I send in
asyncio.get_event_loop().run_until_complete(
    logIn(myurl, logdef)
)

【讨论】:

    【解决方案2】:

    迟到的答案,但对其他人来说可能仍然很有趣。 这个特定示例的文档 (1) 说:

    此客户端需要上下文,因为服务器使用自签名证书。使用有效证书(即由您的 Python 安装信任的 CA 签名)连接到安全 WebSocket 服务器的客户端可以简单地将 ssl=True 传递给 connect(),而不是构建上下文。

    因此,如果您要访问的服务器的服务器证书具有有效证书,只需执行以下操作:

    uri = "wss://server_you_want_to_connect_to_endpoint"
    async with websockets.connect(uri, ssl=True) as websocket:
        and so on ...
    

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 2014-07-09
      • 2019-08-14
      • 2015-09-03
      • 2014-04-09
      • 2016-08-27
      相关资源
      最近更新 更多