【问题标题】:Secure Websocket (wss) Handshake does not happen using Stunnel使用 Stunnel 不会发生安全 Websocket (wss) 握手
【发布时间】:2015-02-05 18:58:59
【问题描述】:

我们制作了一个使用 websockets 的应用程序。我们用 PHP 构建了自己的 websocket 服务器,并使用 Stunnel 来使用安全的 websocket。我们使用 Amazon EC2 中型服务器

直到上周,Chrome 浏览器突然开始显示失败,一切正常:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET。该连接也已停止在 Firefox 上发生。

但是,有时确实会发生 wss 连接。就像我们刷新页面的 4 或 5 次之后,wss 连接发生了一次。

我们已经分析了这个问题,下面是我们观察到的事情:

在 STUNNEL 中:

创建新的 SSL 会话后,一切正常。以下是日志

2014.12.05 05:56:08 LOG7[13990:140019053639616]: Service [websockets] accepted (FD=14) from 115.111.211.142:60018
2014.12.05 05:56:08 LOG7[13990:140019053496064]: Service [websockets] started
2014.12.05 05:56:08 LOG5[13990:140019053496064]: Service [websockets] accepted connection from 115.111.211.142:60018
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): before/accept initialization
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SNI: no virtual services defined
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 read client hello B
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write server hello A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write certificate A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write key exchange A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write server done A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 flush data
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 read client key exchange A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 read finished A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write session ticket A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write change cipher spec A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write finished A
2014.12.05 05:56:08 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 flush data
2014.12.05 05:56:08 LOG7[13990:140019053496064]:   10 items in the session cache
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 client connects (SSL_connect())
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 client connects that finished
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 client renegotiations requested
2014.12.05 05:56:08 LOG7[13990:140019053496064]: 1138 server connects (SSL_accept())
2014.12.05 05:56:08 LOG7[13990:140019053496064]: 1087 server connects that finished
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 server renegotiations requested
2014.12.05 05:56:08 LOG7[13990:140019053496064]:  558 session cache hits
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 external session cache hits
2014.12.05 05:56:08 LOG7[13990:140019053496064]:    0 session cache misses
2014.12.05 05:56:08 LOG7[13990:140019053496064]:  132 session cache timeouts
2014.12.05 05:56:08 LOG6[13990:140019053496064]: SSL accepted: new session negotiated
2014.12.05 05:56:08 LOG6[13990:140019053496064]: Negotiated TLSv1/SSLv3 ciphersuite: DHE-RSA-AES128-SHA (128-bit encryption)
2014.12.05 05:56:08 LOG6[13990:140019053496064]: Compression: null, expansion: null
2014.12.05 05:56:08 LOG6[13990:140019053496064]: connect_blocking: connecting 127.0.0.1:9000
2014.12.05 05:56:08 LOG7[13990:140019053496064]: connect_blocking: s_poll_wait 127.0.0.1:9000: waiting 10 seconds
2014.12.05 05:56:08 LOG5[13990:140019053496064]: connect_blocking: connected 127.0.0.1:9000
2014.12.05 05:56:08 LOG5[13990:140019053496064]: Service [websockets] connected remote server from 127.0.0.1:18479

但是,当一个会话被重用时,连接会从 PHP websocket 关闭。以下是日志

2014.12.05 05:56:08 LOG7[13990:140019053496064]: Remote socket (FD=15) initialized
2014.12.05 05:56:39 LOG6[13990:140019053496064]: Read socket closed (readsocket)
2014.12.05 05:56:39 LOG7[13990:140019053496064]: Sending close_notify alert
2014.12.05 05:56:39 LOG7[13990:140019053496064]: SSL alert (write): warning: close notify
2014.12.05 05:56:39 LOG6[13990:140019053496064]: SSL_shutdown successfully sent close_notify alert
2014.12.05 05:56:39 LOG3[13990:140019053496064]: transfer: s_poll_wait: TIMEOUTclose exceeded: closing
2014.12.05 05:56:39 LOG5[13990:140019053496064]: Connection closed: 988 byte(s) sent to SSL, 873 byte(s) sent to socket
2014.12.05 05:56:39 LOG7[13990:140019053496064]: Remote socket (FD=15) closed
2014.12.05 05:56:39 LOG7[13990:140019053496064]: Local socket (FD=14) closed
2014.12.05 05:56:39 LOG7[13990:140019053496064]: Service [websockets] finished (3 left)
2014.12.05 05:56:43 LOG7[13990:140019053639616]: Service [websockets] accepted (FD=14) from 115.111.211.142:60045
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Service [websockets] started
2014.12.05 05:56:43 LOG5[13990:140019053496064]: Service [websockets] accepted connection from 115.111.211.142:60045
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): before/accept initialization
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SNI: no virtual services defined
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 read client hello B
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write server hello A
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write change cipher spec A
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 write finished A
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 flush data
2014.12.05 05:56:43 LOG7[13990:140019053496064]: SSL state (accept): SSLv3 read finished A
2014.12.05 05:56:43 LOG7[13990:140019053496064]:   10 items in the session cache
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 client connects (SSL_connect())
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 client connects that finished
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 client renegotiations requested
2014.12.05 05:56:43 LOG7[13990:140019053496064]: 1139 server connects (SSL_accept())
2014.12.05 05:56:43 LOG7[13990:140019053496064]: 1088 server connects that finished
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 server renegotiations requested
2014.12.05 05:56:43 LOG7[13990:140019053496064]:  559 session cache hits
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 external session cache hits
2014.12.05 05:56:43 LOG7[13990:140019053496064]:    0 session cache misses
2014.12.05 05:56:43 LOG7[13990:140019053496064]:  132 session cache timeouts
2014.12.05 05:56:43 LOG6[13990:140019053496064]: SSL accepted: previous session reused
2014.12.05 05:56:43 LOG6[13990:140019053496064]: connect_blocking: connecting 127.0.0.1:9000
2014.12.05 05:56:43 LOG7[13990:140019053496064]: connect_blocking: s_poll_wait 127.0.0.1:9000: waiting 10 seconds
2014.12.05 05:56:43 LOG5[13990:140019053496064]: connect_blocking: connected 127.0.0.1:9000
2014.12.05 05:56:43 LOG5[13990:140019053496064]: Service [websockets] connected remote server from 127.0.0.1:18480
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Remote socket (FD=15) initialized
2014.12.05 05:56:43 LOG6[13990:140019053496064]: Read socket closed (readsocket)
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Sending close_notify alert
2014.12.05 05:56:43 LOG5[13990:140019053496064]: Read socket error: Broken pipe (32)
2014.12.05 05:56:43 LOG5[13990:140019053496064]: Connection reset: 0 byte(s) sent to SSL, 516 byte(s) sent to socket
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Remote socket (FD=15) closed
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Local socket (FD=14) closed
2014.12.05 05:56:43 LOG7[13990:140019053496064]: Service [websockets] finished (3 left)

在我们的 PHP WebSocket 服务器中:

当会话重用发生时,WebSocket 服务器只获取字符串“G”作为数据,没有其他内容,因此握手失败。但是,当在 Stunnel 中创建新会话时,握手工作正常。

如果有人可以帮助我们,那就太好了。

到目前为止,我们做了什么来解决这个问题:

  • 在 Apache 中禁用 SSL 缓存。问题仍然存在
  • 在 stunnel 中使用了会话缓存设置。问题仍然存在。此外,我们对 Session 缓存设置以及如何禁用它也没有清晰的了解。

我们下一步计划做什么

  • 重新编译 STUNNEL 并尝试从代码中禁用 SSL 缓存。

  • 停止使用 STUNNEL 并了解如何在 PHP 中建立 SSL 连接。得到类似 stream_context_create 的东西来创建这些连接。但是我们仍然需要查看 stream_context_create 的详细信息

  • 将所有内容移至新服务器并查看问题所在。

希望我已经把事情说清楚了。等待回复。谢谢!

【问题讨论】:

  • 首先从流中读取 1 个字节,然后进行完整读取(将 1 个字节连接到完整读取)。 “G”很可能是“GET”的第一个字节。我不确定是什么原因造成的,但我最近遇到了这种情况。
  • 哇 :D 这成功了!非常感谢约翰!我很惊讶这么简单的解决方案!
  • 这在 .NET 中也发生在我身上,普通的 SslStream。我认为是因为缓冲区还包含有关 TLS 协商的数据,所以只有实际数据的第一个字节才进入缓冲区。
  • 是的,连我也这么认为的原因……

标签: php session caching ssl websocket


【解决方案1】:

首先从流中读取 1 个字节,然后执行完整读取(将 1 个字节连接到完整读取)。 “G”很可能是“GET”的第一个字节。我不确定是什么原因造成的,但我最近遇到了这种情况。

【讨论】:

    猜你喜欢
    • 2014-10-27
    • 1970-01-01
    • 2016-05-17
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多