我已经使用 SslHandler 创建了服务器 (10.32.240.50)。客户端 (10.32.240.5) 连接到服务器,一切正常。一段时间后,客户无故断开连接。我已经进行了 tcp 转储,并在断开连接之前看到了 ncrypted 警报:
我不知道客户在这个警报中发给我什么 - 它是加密的。什么可能是此警报的原因以及为什么会导致断开连接?有什么办法可以用 netty 追踪这个事件吗?
最佳答案
在这个阶段很难看出你的问题是否真的与编程有关,因此是否与主题相关。
TLS 1.2 警报可以是很多东西,请参阅 https://www.rfc-editor.org/rfc/rfc5246#section-7.2这给了你整个列表:
enum { warning(1), fatal(2), (255) } AlertLevel; enum { close_notify(0), unexpected_message(10), bad_record_mac(20), decryption_failed_RESERVED(21), record_overflow(22), decompression_failure(30), handshake_failure(40), no_certificate_RESERVED(41), bad_certificate(42), unsupported_certificate(43), certificate_revoked(44), certificate_expired(45), certificate_unknown(46), illegal_parameter(47), unknown_ca(48), access_denied(49), decode_error(50), decrypt_error(51), export_restriction_RESERVED(60), protocol_version(70), insufficient_security(71), internal_error(80), user_canceled(90), no_renegotiation(100), unsupported_extension(110), (255) } AlertDescription; struct { AlertLevel level; AlertDescription description; } Alert;
当然它是加密的所以如果你真的想看到它,你需要:
- 更改客户端,使其在执行触发此错误的连接时输出主 key 和客户端随机值
- 用wireshark记录相关连接
- 然后您将能够在 wireshark 中使用第一点中的项目对其进行解密(您可以找到许多关于如何做到这一点的教程)
根据经验,如果警报发生在某些应用程序数据之后,最可能的情况是“close_notify”。这是一个“正常”的情况,它只是意味着服务器决定关闭 TLS 套接字(但不一定是 TCP 套接字)并因此警告(提醒)另一方。
如果是这种情况,则预计对方会发送相同的警报,然后使用 FIN
在 TCP 级别关闭连接。因此,您的观察链是意料之中的。剩下的唯一原因是关于初始警报。
澄清后,由于第一个警报来自 .5
,它是客户端,而不是服务器,这意味着您无法控制的客户端已决定关闭 TLS 流,原因如下只有它知道
(如果我们仍然正确地猜测警报是“close_notify”,这仍然只是一个猜测,只有当您按照上述说明解密交换时才能测试,或者可能增加服务器的冗长程度,就像@dave_thompson_085 在评论中给出的这个想法: “如果您设置 sysprop javax.net.debug=ssl,它将跟踪所有 JSSE (SSL/TLS) 操作,包括收到的警报。”)
除此之外,除了询问客户运营商/开发人员外,我看不出有什么办法可以理解客户为什么决定不再与您交谈。它还取决于交换的底层应用程序数据,也许确实是传输结束并且客户端不再需要 TLS 流?
关于java - 如何在 Netty 中处理 SSL 加密警报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51934666/