10.11. HTTPS——服务器的传输层加密¶
到目前为止,所有内容都是端口 80 上的明文 HTTP。任何能在浏览器和摄像头之间抓包的人,都能读取登录表单的密码、由其返回的会话 cookie、Authorization 头中的 JWT,以及每一帧捕获画面的 JPEG 字节。HTTPS 会对线路进行端到端加密。
证书工作流程本身——为开发生成自签名证书、为生产获取由 CA 签发的证书、以正确的格式将文件拷贝到摄像头上——在 使用 TLS 证书 中有专门介绍。本页讲的是 如何把一个已经加载好的证书接入 microdot。
10.11.1. 构建 SSL 上下文¶
ssl.SSLContext 是标准库中用于存放证书、密钥和协议选项的容器。对于服务器,你需要使用 PROTOCOL_TLS_SERVER,并从摄像头的文件系统中加载证书链:
import ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain('/flash/cert.der', '/flash/key.der')
这些 DER 路径来自你在 TLS 章节中所运行的工作流程——开发用自签名证书,生产用 CA 签发的证书。这些文件不必放在 /flash 上;/sdcard 同样可以。
10.11.2. 将上下文传给 start_server¶
与前面的 start_server() 调用相比,唯一的区别就是多了 ssl=ctx 参数以及端口号。端口 443 是 HTTPS 的默认端口,这意味着浏览器无需输入 :443——直接使用 https://yard-cam.local/ 即可:
async def main():
await asyncio.gather(
capture_loop(),
motion_detector(),
app.start_server(host='0.0.0.0', port=443, ssl=ctx),
)
asyncio.run(main())
服务器端的工作就这些了。现有的每一个路由——/status、/snapshot.jpg、/stream.jpg、/config、/events、/control 以及静态仪表盘——现在都通过 TLS 运行,无需任何其他代码改动。
10.11.4. 本页未涵盖的内容¶
HTTP 严格传输安全(HSTS)、证书自动续期、摄像头端用于出站请求的 CA 信任链,以及加密套件的选择,都在 TLS 章节中介绍。这里的接入工作——一个 SSLContext、一个 ssl=ctx——是唯一专属于 microdot 的部分。
仪表盘的地址栏现在从 http:// 变为 https://,WebSocket 从 ws:// 变为 wss://——仪表盘的 JavaScript 已经根据 location.protocol 选择了正确的协议方案,因此无需任何客户端改动。
摄像头通过 HTTPS 提供服务。登录表单、JWT 以及捕获的帧在传输过程中都被加密。