TLS1.2 上的 bad_record_mac 问题

jia*_* li 7 openssl

我们遇到了有关 openldap + openssl 的问题。

当多线程客户端(30 个线程)连接到 OPENLDAP 服务器时,服务器端在 TLS 握手时随机出现“Bad Record MAC”错误。

env
openldap+openssl TLS
RHEL7.5 openssl 1.0.2k
openldap2.4.43

TLS configure
The TLS configures are: TLS1.2 ,  ssf=128 and Cipher_Suite="AES:!NULL:!EXPORT" 

Error connection
Error connection progress are
client->server: Client Hello
server->client:Server Hello, Certificate, Server Hello Done
client->server: Client key Exchange
client->server: change cipher spec
client->server: Encryted Handshake Message
Server->client: Alert(Level: Fatal, Decription: Bad Record MAC)env
openldap+openssl TLS
RHEL7.5 openssl 1.0.2k
openldap2.4.43
Run Code Online (Sandbox Code Playgroud)

当多线程客户端(30个线程)连接OPENLDAP服务器时,服务器端在TLS握手时出现“Bad Record MAC”错误。对于零件连接,此问题是随机发生的。

TLS configure
The TLS configures are: TLS1.2 ,  ssf=128 and    Cipher_Suite="AES:!NULL:!EXPORT" 

Error connection
Error connection progress are
client->server: Client Hello
server->client:Server Hello, Certificate, Server Hello Done
client->server: Client key Exchange
client->server: change cipher spec
client->server: Encryted Handshake Message
Server->client: Alert(Level: Fatal, Decription: Bad Record MAC)
Run Code Online (Sandbox Code Playgroud)

Sha*_*ell 7

“Bad Record MAC”基本上意味着传入的数据由于某种原因是坏的。例如数据包损坏。

自从您提到“多线程”以来,我发现“坏记录 MAC”的第一个原因是在多线程上下文中滥用 OpenSSL 库。OpenSSL 不支持在多线程中同时使用 SSL 句柄“Bad Record MAC”通常是由于使用 OpenSSL SSL 句柄从不同线程更新数据包数据而被损坏的结果。即 OpenSSL 句柄不是线程安全的。

多个 OpenSSL 句柄在彼此使用之间是线程安全的,但单个句柄不是线程安全的。

请参阅有关该主题的这篇 blob文章。

因此,一个常见的错误是允许单个 SSL 句柄有两个线程,一个用于读取,一个用于写入(即,就像套接字句柄所允许的那样),并认为这样就可以了。而 SSL 则不然。您确实需要一个使用所有 SSL 句柄使用的单个线程(或运行上下文,例如 boost asiostrand),以便不会同时发生两个 SSL 句柄 API 调用。