近两年来,Google Chrome 不再支持基于 websocket 的 SSL。 现在我不知道他们真正的问题是什么,除了我听说他们通过 SSL 重写了他们的 WS 协议.. 而且我正在使用 IO::Socket::SSL 我想知道你们是否真的了解它。我的示例站点是一个 irc 机器人,它通过 WSS 上的 javascript 连接从 HTTPS 主机运行。 https://lichtsnel.nl.
它确实工作了很多年,但自从谷歌明显改变了他们的程序以来,Chrome 是唯一一个仍然无法工作的浏览器。我想知道你们是否注意到了这一点。我已经使用 IO::Socket::SSL 编写了一个客户端/服务器库,用于任何与 SSL 相关的内容。它可以在 HTTPS 上完美运行,但 WSS 却发生了一些变化。他们没有解决这个问题。虽然他们可能将新标准强制应用于 HTTPS 层。如果没有有效的 WSS 层,chrome 就会变得毫无用处。我被迫退回到 http/ws。剩下的功能就少了。
不确定这些模块的更新程度如何,我可以最近更新,但仍然很幸运,如果您有任何有关其协议更改的信息。所以我发邮件来看看我们是否可以期待更新让 chrome 再次工作。
致以亲切的问候, 奥尼皮 多梅罗。
这是 perl 中的服务器端代码:
# SSL
my $sslerr=0;
if ($self->{ssl}) {
IO::Socket::SSL->start_SSL($client,
SSL_server => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_cert_file => $self->{sslcert},
SSL_key_file => $self->{sslkey},
SSL_ca_file => $self->{sslca},
Listen => 128
) or $sslerr=1;
if ($sslerr) { print STDOUT prtm(),"Failed to ssl handshake: $SSL_ERROR\n"; close($client) }
}
服务器仅记录以下内容:
ssl 握手失败:SSL 接受尝试失败
虽然您没有提供很多详细信息,并且基本上声称 WSS 通常会被 Chrome 破坏(这不是真的),但我怀疑代码中的以下行导致了问题:
SSL_verify_mode => SSL_VERIFY_PEER,
通过此行,您可以请求客户端证书。请注意,您只请求一个,但实际上并不需要一个,即它只是
SSL_VERIFY_PEER
而不是 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT
。这意味着如果没有发送客户端证书,TLS 握手将继续。
根据此错误报告,如果 WSS 连接请求客户端证书,Chrome 似乎不会提示用户。这意味着连接将失败 - 除非之前已经为同一来源(即域+端口)请求了必要的客户端证书,因此可以使用之前的选择。鉴于您似乎使用特定于 WSS 连接的源(域+端口),情况可能并非如此 - 因此它会失败。
如果您一开始就不需要客户端证书(这很可能是这种情况,因为您将这些证书视为可选),只需删除请求客户端证书的行即可。如果您确实需要客户端证书,请将您的 Websocket 置于与站点其余部分相同的源中,并在那里请求客户端证书。请参阅此处了解如何完成此操作的典型方法。
我刚刚遇到了一个问题,Websocket 在 Firefox 中可以工作,但在 Chrome 中不行。 Chrome 可以正常连接,但随后会立即断开连接并显示 1006 错误代码。
通过更改此行修复:
var chatSocket = new WebSocket(wsproto + window.location.host + '/ws/', null, 5000, 10);
对此:
var chatSocket = new WebSocket(wsproto + window.location.host + '/ws/');
“null”应该用于子协议,我认为 5000,10 是之前使用的不同 websocket 库留下的。