我收到错误:SSL3_GET_RECORD:解密失败或记录错误

我收到错误:SSL3_GET_RECORD:解密失败或记录错误

我有自己的服务器(我在那里运行Apache/2.4.27),今天我意识到从(Brave 和 Google Chrome - 不同的计算机)我从我的网站收到了这个错误;

This site can’t provide a secure connection

mywebsite.com sent an invalid response.
ERR_SSL_PROTOCOL_ERROR

奇怪的是,我每点击五次我的网站就会出现这个错误。

从我的配置文件中:

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mywebsite/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mywebsite/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/mywebsite/chain.pem
SSLCompression off

options-ssl-apache.conf;

SSLProtocol             all -SSLv2 -SSLv3
SSLCipherSuite          EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLHonorCipherOrder     on
SSLCompression          off

我已经检查了网站上的日志文件,但没有任何东西,这里也没有任何东西;/var/log/apache2/error.log

我正在尝试找出导致此错误的原因,有什么想法可以让我在哪里找到更多信息,或者更好的是,如何解决这个问题?

编辑:

如果我尝试openssl s_client -connect mywebsite.com:443,它将返回:

我在用着:OpenSSL 1.1.0f

CONNECTED(00000003)

...

3073276480:error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac:../ssl/record/ssl3_record.c:469:

另一项编辑:

正如@quadruplebucky 建议的那样,我将 options-ssl-apache.conf 更改为:

SSLProtocol             all -SSLv2 -SSLv3
SSLCipherSuite           HIGH:MEDIUM:!aNULL:!MD5:!SSLv3:!SSLv2:!TLSv1
SSLHonorCipherOrder     on
SSLCompression          off

#SSLSessionTickets       off

我也尝试将其添加SSLProtocol all -SSLv2 -SSLv3到我的虚拟主机 conf 文件中,同时我在这里更改了一些东西;/etc/apache2/mods-available/ssl.conf

#SSLCipherSuite HIGH:!aNULL
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SSLv3:!SSLv2:!TLSv1

SSLHonorCipherOrder on

#   The protocols to enable.
#   Available values: all, SSLv3, TLSv1, TLSv1.1, TLSv1.2
#   SSL v2  is no longer supported
SSLProtocol all -SSLv2 -SSLv3

编辑:

将 LogLevel 更改为后,Info将返回:

[Sat Jul 08 13:34:53.374307 2017] [ssl:info] [pid 8710] [client] AH02008: SSL library error 1 in handshake (server mywebsite:443)
[Sat Jul 08 13:34:53.374717 2017] [ssl:info] [pid 8710] SSL Library Error: error:140940F4:SSL routines:ssl3_read_bytes:unexpected message
[Sat Jul 08 13:34:53.374750 2017] [ssl:info] [pid 8710] [client] AH01998: Connection closed to child 1 with abortive shutdown (server mywebsite:443)

编辑:

如果我使用选项 -crlf 运行,如下所示:

openssl s_client -crlf -connect mywebsite:443

我没有收到任何错误?

还有一件事,如果我将 LogLevel 更改为调试,在出现该错误之前我会收到以下信息:

[Tue Jul 11 23:00:38.641568 2017] [core:debug] [pid 26561] protocol.c(1273): [client 188.64.25.162:23165] AH00566: request failed: malformed request line
[Tue Jul 11 23:00:38.641634 2017] [headers:debug] [pid 26561] mod_headers.c(900): AH01503: headers: ap_headers_error_filter()

因此此后仍会发生相同的错误:

SSL Library Error: error:140940F4:SSL routines:ssl3_read_bytes:unexpected message

openssl version
OpenSSL 1.1.0f  25 May 2017

答案1

你无法从该错误中判断你的服务器正在协商 SSLv3 还是 TLSv1(你可能需要查看关于 Unix 和 Linux 的这个问题并确保它被禁用到处在 apache 中...)--- 1.1.0f 源代码在 GitHub 上故意模糊两者......

   if (enc_err < 0) {
    /*
     * A separate 'decryption_failed' alert was introduced with TLS 1.0,
     * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
     * failure is directly visible from the ciphertext anyway, we should
     * not reveal which kind of error occurred -- this might become
     * visible to an attacker (e.g. via a logfile)
     */
    al = SSL_AD_BAD_RECORD_MAC;
    SSLerr(SSL_F_SSL3_GET_RECORD,
           SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
    goto f_err;
}

因此您可能需要重新排序您的密码套件:

SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SSLv3:!SSLv2:!TLSv1

askubuntu 上有关 POODLE 漏洞的这篇文章拥有有关 SSL 检查和管道的优秀资源列表。

Mozilla 配置生成器是一个出色的公共服务。

“每点击五次就会出现此错误”的评论有点奇怪。你的意思是点击,或者日志中每五行就有一个错误请求?尝试启动 apache 单线程(-X 标志),看看是否会出现同样的情况...或者设置SSLSessionTickets off

我的想法是消除线程和会话/缓存一致性/一致性作为麻烦的根源。运行 apache 单线程(使用 -X 标志启动它)是实现此目的的一种方法,另一种方法是设置MaxClients=1(至少使用 MPM 模型)。会话票证在过去一直是 TLSv1.2 的麻烦根源,默认情况下启用它们,这就是背后的原因SSLSessionTickets off(请注意,这是 SSL“Server Hello”消息的一部分,而不是会话 cookie 或类似消息)。“每五次点击”错误仍然困扰着我 - 我不禁注意到大多数浏览器会在一次请求中管道化四个资源请求......)并为第五次请求打开一个新连接(新的 ssl 握手等......)......没有数据包捕获很难说出到底发生了什么。

看起来您已经排除了密码协商作为错误源的可能性(除非我弄错了,否则您可以在更严格的密码规范下复制错误条件)。我很想知道您是否可以通过重新协商 SSL(比如说只是为了好玩)来触发错误: openssl s_client -connect server:443然后输入“R”,看看日志中的内容。
另外,看看会话缓存是否与 s_client 选项配合使用-reconnect
某物SSL 请求的接收上下文必须有所不同,而解决这个问题的最佳方法(缺少对线路上传输的内容的逐字节检查,这可能很难匿名化)似乎是严格限制监听内容的大小(即监听器的数量)。

我会尝试其他调试工具(假设发布数据包捕获是不可能的......)
-ssltap(在libnss3-toolsUbuntu 上)
-密码扫描
-sslscan

更新
通过ssltap看起来很像OpenSSL 错误 #3712 再次出现(基本上是在读/写期间重新协商密钥)。正在寻找一种不会影响性能的合理解决方法。很有趣!

答案2

我以前见过这种情况,事实上以前也遇到过这种情况。

就我的情况而言,答案最终变得极其微妙。

网络适​​配器启用了 TCP 段卸载,由于某种形式的错误,它破坏了(或截断,记不清了)一些消息的最后几个字节——这随后导致 SSL 记录上的 MAC 失败。

它是 VMWare 上的虚拟机。

我将尝试在您的环境中禁用 TSO/GSO/GRO,看看问题是否消失。

ethtool -K eth0 tso off gro off gso off ufo off

答案3

OpenSSL 和多线程有些奇怪。您使用什么 MPM?如果这与多线程有关,则“prefork”应该是安全的,而“worker”和“event”可能会受到影响。

如果您的负载配置文件允许,也许您可​​以尝试切换到 prefork 并查看问题是否仍然存在。

答案4

首先确保 chrome 已更新。旧版本在某些密码方面存在问题。我自己在访问亚马逊等常见网站时也遇到过这种 chrome 问题。

其次,您遵循的禁止“密码列表”中的协议的建议是一个非常糟糕的主意,因为它不会禁止协议,它会禁止大多数密码,包括自 SSLv3 以来工作的密码(但并不意味着如果您允许 SSLv3 密码,您将启用 SSL3),使用 Mozilla SSL 配置生成器提供的更通用的列表以实现兼容性(注意 SSLv2 不再存在或在 httpd 或 openssl 中受支持,因此没有理由再明确禁止它)并且也许您之前的组合太严格,请尝试这个:

SSLProtocol             all -SSLv3
SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS

如果仍然有问题,请启用 SSL 调试并查看 httpd 说什么(仅发送 1 次或两次尝试并禁用此日志记录,因为这样太吵了):

LogLevel ssl:trace3

附注:您也可以继续删除 SSLCertificateChainFile,因为该指令在 2.4 中已弃用。您可以添加 SSLCertificateFile 链,并将所有证书从叶到根排序,甚至可以将 SSLCertificateChainFile 更改为 SSLCACertificateFile(尽管这个主要用于 SSL 身份验证)。

您还应该添加(如果还没有)添加:

SSLRandomSeed startup file:/dev/urandom 2048
SSLRandomSeed connect file:/dev/urandom 2048
SSLSessionCache shmcb:/path/to/log/ssl_gcache_data(512000)

编辑:根据我们的讨论,让我们检查 openssl 安装和/或它是否确实与您的 httpd 使用的版本相同:

发出此命令并看看它说了什么:openssl ciphers -v 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'

另外,为了确保 openssl 版本正确,请运行以下命令:

openssl version

相关内容