【问题标题】:RabbitMQ: handshake error when attempting to use SSL certificatesRabbitMQ:尝试使用 SSL 证书时出现握手错误
【发布时间】:2014-07-07 21:48:16
【问题描述】:

我正在尝试将 SSL 证书与 RabbitMQ 一起使用,但我不断收到与代理的握手错误。

在单独的终端窗口中使用 openssl 's_client' 和 's_server' 命令并使用 SSL 故障排除指南 (http://www.rabbitmq.com/troubleshooting-ssl.html) 中详述的端口 8443 时,我生成的证书可以正常工作。

当我尝试使用相同的 openssl 's_client' 命令连接到 RabbitMQ SSL 端口 5671 时出现问题:

运行这个:

openssl s_client -connect localhost:5671 -cert /etc/rabbitmq/ssl/client/cert.pem -key /etc/rabbitmq/ssl/client/key.pem -CAfile /etc/rabbitmq/ssl/certificate_auth/cacert.pem

产生这个:

CONNECTED(00000003)
depth=1 CN = RMQCA
verify return:1
depth=0 CN = roger.xxxxxx.com, O = server
verify return:1
139997248210760:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1256:SSL alert number 40
139997248210760:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake  failure:s23_lib.c:177:
---

SSL 侦听器启动正常,如 RabbitMQ 日志所示:

=INFO REPORT==== 19-May-2014::15:45:34 ===
 started TCP Listener on [::]:5672

=INFO REPORT==== 19-May-2014::15:45:34 ===
 started SSL Listener on [::]:5671

尝试使用“s_client”连接到端口 5671 时出现错误:

=INFO REPORT==== 19-May-2014::17:20:39 ===
accepting AMQP connection <0.3263.0> ([::1]:58538 -> [::1]:5671)

=ERROR REPORT==== 19-May-2014::17:20:39 ===
SSL: certify: ssl_handshake.erl:1346:Fatal error: handshake failure

=ERROR REPORT==== 19-May-2014::17:20:44 ===
error on AMQP connection <0.3263.0>: {ssl_upgrade_error,
                                      {tls_alert,"handshake failure"}} (unknown POSIX error)

RabbitMQ 配置文件:

[    
    {rabbit, [
      {ssl_listeners, [5671]},
      {ssl_options, [{cacertfile, "/etc/rabbitmq/ssl/certificate_auth/cacert.pem"},
                     {certfile, "/etc/rabbitmq/ssl/server/cert.pem"},
                     {keyfile, "/etc/rabbitmq/ssl/server/key.pem"},
                     {verify, verify_peer},
                     {fail_if_no_peer_cert, false}]}
     ]} 
].

RabbitMQ 信息:

[{pid,10375},
 {running_applications,
     [{rabbitmq_management,"RabbitMQ Management Console","3.2.3"},
      {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.2.3"},
      {webmachine,"webmachine","1.10.3-rmq3.2.3-gite9359c7"},
      {mochiweb,"MochiMedia Web Server","2.7.0-rmq3.2.3-git680dba8"},
      {rabbitmq_management_agent,"RabbitMQ Management Agent","3.2.3"},
      {rabbit,"RabbitMQ","3.2.3"},
      {ssl,"Erlang/OTP SSL application","5.3.3"},
      {public_key,"Public key infrastructure","0.21"},
      {crypto,"CRYPTO version 2","3.2"},
      {asn1,"The Erlang ASN1 compiler version 2.0.4","2.0.4"},
      {os_mon,"CPO  CXC 138 46","2.2.14"},
      {inets,"INETS  CXC 138 49","5.9.8"},
      {mnesia,"MNESIA  CXC 138 12","4.11"},
      {amqp_client,"RabbitMQ AMQP Client","3.2.3"},
      {xmerl,"XML parser","1.3.6"},
      {sasl,"SASL  CXC 138 11","2.3.4"},
      {stdlib,"ERTS  CXC 138 10","1.19.4"},
      {kernel,"ERTS  CXC 138 10","2.16.4"}]},
 {os,{unix,linux}},
 {erlang_version,
     "Erlang R16B03-1 (erts-5.10.4) [source] [64-bit] [smp:2:2] [async-threads:30] [hipe] [kernel-poll:true]\n"},
 {memory,
     [{total,43812088},
      {connection_procs,5616},
      {queue_procs,42528},
      {plugins,451248},
      {other_proc,13805200},
      {mnesia,72752},
      {mgmt_db,10208},
      {msg_index,34560},
      {other_ets,1159472},
      {binary,1030272},
      {code,21819091},
      {atom,793505},
      {other_system,4587636}]},
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,787819724},
 {disk_free_limit,50000000},
 {disk_free,31267266560},
 {file_descriptors,
     [{total_limit,924},{total_used,4},{sockets_limit,829},{sockets_used,2}]},
 {processes,[{limit,1048576},{used,215}]},
 {run_queue,0},
 {uptime,7893}]
...done.

任何帮助将不胜感激

提前致谢。

更新:

尝试连接 rabbitmqadmin 实用程序时出现以下错误。

日志文件:

=INFO REPORT==== 20-May-2014::14:39:12 ===
accepting AMQP connection <0.16589.0> ([::1]:58922 -> [::1]:5671)

=ERROR REPORT==== 20-May-2014::14:39:12 ===
SSL: certify: ssl_handshake.erl:1346:Fatal error: handshake failure

=ERROR REPORT==== 20-May-2014::14:39:17 ===
error on AMQP connection <0.16589.0>: {ssl_upgrade_error,
                                       {tls_alert,"handshake failure"}} (unknown POSIX error)

rabbitmqadmin 命令产生以下内容:

*** Could not connect: [Errno 1] _ssl.c:492: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

【问题讨论】:

  • 您是否仅使用 openssl cli 实用程序遇到此问题?你试过rabbitmqadmin 实用程序吗?
  • 您的问题解决了吗?

标签: ssl rabbitmq


【解决方案1】:

这是对我有用的解决方案:

在 rabbitmq.config 中添加以下密码:

{ciphers, ["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384",
                        "ECDHE-ECDSA-AES256-SHA384","ECDHE-RSA-AES256-SHA384", "ECDHE-ECDSA-DES-CBC3-SHA",
                        "ECDH-ECDSA-AES256-GCM-SHA384","ECDH-RSA-AES256-GCM-SHA384","ECDH-ECDSA-AES256-SHA384",
                        "ECDH-RSA-AES256-SHA384","DHE-DSS-AES256-GCM-SHA384","DHE-DSS-AES256-SHA256",
                        "AES256-GCM-SHA384","AES256-SHA256","ECDHE-ECDSA-AES128-GCM-SHA256",
                        "ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES128-SHA256","ECDHE-RSA-AES128-SHA256",
                        "ECDH-ECDSA-AES128-GCM-SHA256","ECDH-RSA-AES128-GCM-SHA256","ECDH-ECDSA-AES128-SHA256",
                        "ECDH-RSA-AES128-SHA256","DHE-DSS-AES128-GCM-SHA256","DHE-DSS-AES128-SHA256",
                        "AES128-GCM-SHA256","AES128-SHA256","ECDHE-ECDSA-AES256-SHA",
                        "ECDHE-RSA-AES256-SHA","DHE-DSS-AES256-SHA","ECDH-ECDSA-AES256-SHA",
                        "ECDH-RSA-AES256-SHA","AES256-SHA","ECDHE-ECDSA-AES128-SHA",
                        "ECDHE-RSA-AES128-SHA","DHE-DSS-AES128-SHA","ECDH-ECDSA-AES128-SHA",
                        "ECDH-RSA-AES128-SHA","AES128-SHA"]},
                  {fail_if_no_peer_cert,false}]}
    ]}
]

【讨论】:

    【解决方案2】:

    我遇到了与@user3653959 相同的问题,@Sarah Messer 的回答让我找到了解决方案。

    您的客户端证书必须具有TLS Web Client Authentication“X509v3 Extended Key Usage”属性。由于我的客户端生成脚本中的错误,我的只有 TLS Web Server Authentication

    要检查您的客户端证书的功能,您可以使用以下命令:

    openssl x509 -noout -text -in client-certificate.pem
    

    然后查找“X509v3 extensions:”部分和“X509v3 Extended Key Usage:”子部分。

    如果您使用示例openssl.conf 以及官方"RabbitMQ - TLS Support" guide 中提供的客户端和服务器命令生成客户端证书,它应该可以开箱即用。

    这里的关键是@Sarah Messer 指出的openssl.conf 中的extendedKeyUsage = 1.3.6.1.5.5.7.3.2 openssl 配置选项。这是“TLS Web 客户端身份验证”功能。 OpenSSL s_server 不需要此功能,这就是为什么它默认使用它,但不适用于 RabbitMQ。 keyUsage = digitalSignature 作为主要使用选项就足够了。此外,客户端证书的“通用名称”(CN) 并不重要。

    仅供参考

    我的环境:

    • RabbitMQ 3.6.2
    • 二郎18.2
    • Ubuntu 14.04.2 LTS(64 位)
    • 仅启用 TLSv1.2。

    我在 RabbitMQ 日志中看到的错误:

    =ERROR REPORT==== 21-Jun-2016::13:28:21 ===
    SSL: certify: ssl_handshake.erl:1492:Fatal error: handshake failure
    

    我通过openssl s_client看到的错误:

    140735165813584:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1472:SSL alert number 40
    140735165813584:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656:
    

    【讨论】:

    • 我的问题与此非常接近,这帮助我解决了它,而我有正确的extendedKeyUsage 我实际上是在将我的客户端证书作为服务器证书进行签名。请注意您的 openssl 命令正在执行正确的扩展名。 (这是-extensions XXXX 标志)
    【解决方案3】:

    我解决了类似的问题(使用 RabbitMQ 2.7.1 / Erlang R14B04)。这是我发现的:

    RabbitMQ plugins page 和至少 one other site 建议启用插件 rabbitmq_auth_mechanism_ssl。如果rabbitmq-plugins 是您系统上的无效命令,this page 将描述如何在 Ubuntu 上启用它。 (显然 apt-get 软件包在基于 Debian 的系统上没有完全预期的行为。)您的输出(我猜来自 rabbitmqctl report)说您没有启用 rabbitmq_auth_mechanism_ssl

    对于您的 rabbitmq.config,您需要确保“EXTERNAL”被列为 auth_mechanisms 之一。该行的语法是{auth_mechanisms, ['PLAIN', 'AMQPLAIN', 'EXTERNAL']},在配置的默认“兔子”部分中显示为一项。

    您还应该确保您的客户端提供的证书具有为keyUsageextendedKeyUsage 设置的适当值,因为RabbitMQ 对这些比s_server 更严格。出于调试/测试目的,您可能希望对这些非常宽容。您可以在 openssl config 中设置 keyUsage。广泛接受的 openssl 配置可能有这样的行

    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign extendedKeyUsage = 1.3.6.1.5.5.7.3.1, 1.3.6.1.5.5.7.3.2

    (我认为.2 OID,“TLS Web Client Authentication”对于连接RabbitMQ很重要,但我没有做过仔细的测试。)

    这将生成带有此块接近尾声的证书:

    X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication s_client 应该有更多的输出。特别是,我对最后一行感兴趣,它应该类似于“验证返回代码:0(ok)” (#19 非常常见,因为它是not really an error。)

    当我到达这一点时,当我尝试制作一个简单的pika.BlockingConnection 时,握手显然完成得很好,但是 Rabbit 从配置中auth_mechanisms 指定的列表中删除了 EXTERNAL。我确认我启用了 rabbitmq_auth_mechanism_ssl,但这本身还不够。 (我通过子类化pika.credentials.ExternalCredentials 并在ConnectionParameters 中将实例作为“凭据”项传递,在子类的response_for() 方法的顶部添加print start 来发现这一点。)我通过将以下行添加到@ 来解决这个问题配置文件的 987654340@ 部分,与 ssl_listenersssl_cert_login_from 处于同一级别:

    {ssl_apps,[asn1,crypto,public_key,ssl]},

    (我怀疑 RabbitMQ 的较新版本默认开启,但我的特定设置没有。)

    如果您已经完成了所有这些操作,但仍然遇到问题,您还可以尝试在 RabbitMQ 配置中将“verify_peer”替换为“verify_none”。您可能不希望在生产中使用它,因为它向任何拥有自签名证书的人开放,但这是另一个数据点。此外,将 pika 中的相关内容子类化并添加打印语句,以更深入地了解 Rabbit 发送给您的内容以及您的本地客户如何解释它。

    【讨论】:

    • 即使 openssl s_client 成功连接到同一组证书,对于 .net 也会出现相同的错误“SSL: certify: ssl_connection.erl:826:Fatal error: handshake failure”。我的客户端证书在扩展密钥使用部分中有“TLS Web 客户端身份验证”
    猜你喜欢
    • 2015-02-25
    • 1970-01-01
    • 2016-09-28
    • 2018-10-12
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 2018-02-18
    相关资源
    最近更新 更多