Socket.io + SSL + 自签名 CA 证书在连接时出错
Posted
技术标签:
【中文标题】Socket.io + SSL + 自签名 CA 证书在连接时出错【英文标题】:Socket.io + SSL + self-signed CA certificate gives error when connecting 【发布时间】:2013-02-28 05:37:25 【问题描述】:我正在使用使用自签名 CA 证书创建的证书运行 https 服务器。
现在我想将 Socket.io 客户端连接到附加到 https 服务器的 Socket.io 服务器。不幸的是,我收到一个错误,告诉我:
Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE
at SecurePair.<anonymous> (tls.js:1271:32)
at SecurePair.EventEmitter.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:883:10)
at CleartextStream.read [as _read] (tls.js:421:15)
at CleartextStream.Readable.read (_stream_readable.js:293:10)
at EncryptedStream.write [as _write] (tls.js:330:25)
at doWrite (_stream_writable.js:211:10)
at writeOrBuffer (_stream_writable.js:201:5)
at EncryptedStream.Writable.write (_stream_writable.js:172:11)
at write (_stream_readable.js:547:24)
at flow (_stream_readable.js:556:7)
基本上,这个错误告诉我证书无法成功验证。这是因为相应的 CA 证书是自签名的。使用 https 请求时,我可以指定我信任的 CA。
在这种情况下如何让 Socket.io 连接?
PS:我正在运行 Node.js 0.10.0 和 Socket.io 0.9.13。
【问题讨论】:
【参考方案1】:四年后,但如果您需要强制客户端套接字不拒绝自签名服务器证书,那么对于任何像我一样发现这篇文章的人,您需要 rejectUnauthorized: false
如在
const socket = require('socket.io-client')('https://192.168.0.31', transports: ['websocket'], rejectUnauthorized: false )
来自https://github.com/socketio/engine.io-client#methods
现在还有一个很好的免费证书来源,所以现在你甚至不必成为“便宜的 d*ck”https://letsencrypt.org/
【讨论】:
我刚刚发现rejectUnauthorized...适用于任何websocket,而不仅仅是socket.io。 Wii 也解决了其他证书的问题(如果您真的不需要对您的 ssl 连接进行高度保护) 这个稍加修改的版本对我有用:const socket = io('https://192.168.0.31:3000', transports: ['websocket'], rejectUnauthorized: false );
【参考方案2】:
对于 socket.io 1.0(不确定 0.9),这里有如何让节点客户端连接到无效证书的详细信息:https://***.com/a/24235426。 (感谢@3rdEden 上面的评论。)我发现自签名 SSL 证书可以方便开发服务器。
【讨论】:
【参考方案3】:查看here,了解如何为Certificate Signing Request
使用自签名证书。您必须指定以下内容以允许使用自签名证书进行连接:
-
key:一个字符串或 Buffer,包含 PEM 格式的客户端私钥。
cert:一个字符串或缓冲区,其中包含 PEM 格式的客户端证书密钥。
ca:受信任证书的字符串或缓冲区数组。如果省略,将使用几个众所周知的“根”CA,例如 VeriSign。这些用于授权连接。
要使用 CSR 创建自签名证书,请执行以下操作:
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
在客户端,套接字应该被用作
var socket = io.connect('https://localhost', secure: true);
【讨论】:
这正是我所做的,但它不起作用。我总是收到 UNABLE_TO_VERIFY_LEAF_SIGNATURE 错误(我试图从 Node.js 中使用 socket.io-client 进行连接,而不是从浏览器中)。我需要的是有可能以编程方式告诉 Socket.io 哪些 CA 证书是好的。看起来,这种可能性是缺失的。 SockJS 的行为方式相同,并且那里也缺少这种可能性:-( 这个答案没有回答如何让有效的自签名证书在 NodeJS 中正常工作的问题。 这不是问题的答案,这是how to create self-signed certificate
【参考方案4】:
不要使用自签名证书。只是不要,有些浏览器在使用 WebSockets 时无法让您接受它们。而且你看起来像一个没有购买适当证书的廉价 d*ck。
来自They see me pollin, they hatin (p. 23)。 Socket.IO 的核心团队成员 Arnout Kazemier (3rdEden) 的演讲。
【讨论】:
那么这如何解决开发/暂存案例?我应该为我的所有登台服务器、Vagrant VM 和生产服务器购买证书吗? Node.js 0.10 已配置为自动拒绝自签名的 SSL 证书。您可以通过添加以下 ENV 变量来“撤消”它以进行开发:NODE_TLS_REJECT_UNAUTHORIZED=0
另外,是的,我对 SSL 的看法很狭窄;)但正如您可能已经经历过的那样,自签名证书会导致很多问题可以通过适当的证书来防止。至于开发/登台,购买通配符 ssl 证书或编辑您的 /etc/hosts
? ;)
@3rdEden 这有点奇怪不是吗? “自动拒绝自签名的 SSL 证书”......我的意思是当有人向options:ca : [self-signed.pem]
添加自签名证书时......不应该通过检查而不是失败吗?从客户端发出的nodejs请求的角度来看,就是。
在某些情况下使用自签名证书可能非常重要。您甚至无法从浏览器访问 socket.io。如果你想进行自动化测试,你不应该使用真正的生产站点密钥,任何人都应该能够运行测试。
@hg — 完全正确!说“只是不要使用自签名证书”似乎非常狭隘。我的用例是 Swift nodejs+socket.io。有人知道在过去两年里这个话题是否发生了变化?以上是关于Socket.io + SSL + 自签名 CA 证书在连接时出错的主要内容,如果未能解决你的问题,请参考以下文章