RHEL7 上的 RabbitMQ 服务器重置 SSL 连接

RabbitMQ server on RHEL7 resets SSL connection

我一直在尝试连接到 RHEL7 上的 RabbitMQ 服务器,该服务器侦听 5671 端口以进行 SSL 连接。

RabbitMQ server's SSL listener has been configured like this:
[
  {rabbit, [
     {ssl_listeners, [5671]},
     {ssl_options, [{cacertfile,"/etc/pki/tls/certs/samqp.dcu.ie.chain"},
                {certfile,"/etc/pki/tls/certs/samqp.dcu.ie.crt"},
                {keyfile,"/etc/pki/tls/private/samqp.dcu.ie.key"},
                {verify,verify_peer},
                {fail_if_no_peer_cert,false}]}
   ]}
]

在客户端,我收到此异常消息:

客户端机器是 Ubuntu 14.04 LTS。

客户端是使用 'videlalvaro/php-amqplib' 库与服务器通信的 Moodle 自定义插件。

以下是我根据以下文档创建的自签名证书的实际路径和文件名:https://www.rabbitmq.com/ssl.html

$sslOptions = array(
            'cafile' => '/home/duro/testca/cacert.pem',
            'local_cert' => '/home/duro/client/key-cert.pem',
            'peer_name'=>'samqp.dcu.ie',
            'verify_peer_name' => true
            );

PHP 显然需要使用连接到一个文件的证书和密钥,因此 'key-cert.pem'.

这是我从客户端连接的方式,包括实际的 url:

$connection = new AMQPSSLConnection('samqp.dcu.ie.crt', 5671, 'rMQUsername', 'rMQPasswd', '/', $sslOptions)

在客户端,我收到此异常消息:

"stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed" 

在服务器端,查看 /var/log/rabbitmq/rabbit@sphinx.log,我看到这个错误:

=ERROR REPORT==== 3-Mar-2016::14:08:26 ===
SSL: certify: ssl_alert.erl:93:Fatal error: unknown ca

那么,如何使这个连接工作?

... error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed"

您正在连接到名称为 sphinx.dcu.ie:

的服务器
$connection = new AMQPSSLConnection('sphinx.dcu.ie', 5671, ...)

但是,证书中的主机名是 samqp.dcu.ie:

X509v3 Subject Alternative Name: 
    DNS:samqp.dcu.ie

您需要做以下两件事之一。首先,对证书中指定的服务器发出 RabbitMQ 请求。或者其次,获取一个新证书,该证书使用您要使用的 DNS 名称颁发。

您可以在 主题备用名称 (SAN) 中放置任意数量的 DNS 名称。我经常用调试和测试名称填充它们,例如 localhostlocalhost.localdomain127.0.0.1.


编辑:对于这个问题:

... and server's log now says:

=ERROR REPORT==== 3-Mar-2016::09:52:41 ===
SSL: certify: ssl_handshake.erl:1490:Fatal error: unknown ca

您需要返回 Revision 9 左右的问题信息和此信息:

depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert  High Assurance EV Root CA
verify return:1
depth=1 C = NL, ST = Noord-Holland, L = Amsterdam, O = TERENA, CN =   TERENA SSL High Assurance CA 3
verify return:1
depth=0 businessCategory = Government Entity, jurisdictionC = IE,   serialNumber = Government Entity, street = Glasnevin, street = Dublin City   University, postalCode = IE, C = IE, ST = Ireland, L = Dublin, O = Dublin  City University, OU = ISS, CN = samqp.dcu.ie
verify return:1

不需要 ca-cert.pem 文件,其中包含数百个 CA,其中大部分都是错误的。您只需要一个正确的 CA,它曾经被称为 DigiCert High Assurance EV Root CA。您还需要中间的 TERENA SSL High Assurance CA 3

DigiCert 高保证 EV 根 CA 证书

您可以从 DigiCert Trusted Root Authority Certificates 下载 DigiCert High Assurance EV Root CA。它具有以下属性:

  • 序列号:02:AC:5C:26:6A:0B:40:9B:8F:0B:79:F2:AE:46:25:77
  • 指纹:5FB7EE0633E259DBAD0C4C9AE6D38F1A61C7DC25

你下载的时候是DER格式的。您需要将其转换为 PEM 格式:

$ openssl x509 -inform der -in DigiCertHighAssuranceEVRootCA.crt \
    -outform PEM -out DigiCertHighAssuranceEVRootCA.pem

然后:

$ cat DigiCertHighAssuranceEVRootCA.pem 
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
...
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----

TERENA SSL 高保证 CA 3 证书

现在您需要对 TERENA SSL High Assurance CA 3 执行相同的操作。我相信你可以在 TERENA SSL High Assurance CA Root Certificates 找到它。它具有以下属性:

  • 序列号0b:5c:34:35:67:5b:24:67:c0:d7:32:37:f9:0d:5f:94
  • 指纹 SHA1 A7:8A:AB:DE:7F:5B:77:15:40:D3:33:B5:05:87:4C:82:04:AA:D2:06

我的-CACERT.pem

既然您已经拥有路径构建所需的 CA,请执行以下操作:

$ cat DigiCertHighAssuranceEVRootCA.pem > my-cacert.pem
$ cat TERENA_SSL_High_Assurance_CA_3.pem >> my-cacert.pem
$ echo "" >> my-cacert.pem

然后:

$ cat my-cacert.pem 
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
...
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE4DCCA8igAwIBAgIQC1w0NWdbJGfA1zI3+Q1flDANBgkqhkiG9w0BAQsFADBs
...
dnnqz5SeAs6cbSm551qG7Dj8+6f/8e33oqLC5Ldnbt0Ou6PjtZ4O02dN9cnicemR
1B0/YQ==
-----END CERTIFICATE-----

最后使用my-cacert.pem.


您应该能够使用 OpenSSL 的 s_client 进行测试。但我似乎无法与外界联系:

$ openssl s_client -connect sphinx.dcu.ie:5671 -tls1 \
    -servername sphinx.dcu.ie -CAfile my-cacert.pem 

如果你能连接,那么你应该得到一个Verify Ok (0)(如果我没记错的话)。

我在从 PHP 客户端连接到 RabbitMQ 服务器时遇到了同样的问题。错误是

"stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed"

我按照下面的一系列步骤调试了它

确保客户端和服务器正在使用提供的证书文件进行握手。

在一个终端中 运行 下面的命令在 8443 端口上启动服务器。

openssl s_server -accept 8443 -cert /etc/rabbitmq/server/cert.pem -key /etc/rabbitmq/server/key.pem -CAfile  /etc/rabbitmq/testca/cacert.pem

然后,在另一个终端 运行 下面的命令进行连接。

openssl s_client -connect YOUR_SERVER:8443 -key /rabbitmq/client/key.pem -CAfile /rabbitmq/client/key-cert.pem

如果客户端能够连接并且由于超时没有return返回提示,则连接成功。尝试使用您的 certificates/keys 直到您成功建立连接。

Note: It is assumed the key-cert is concatenated file.

# cd /etc/rabbitmq/client
# cat key.pem cert.pem > key-cert.pem

PHP 客户端中的 SSL 选项

我将下面的 PHP 数组作为 $ssl_options 参数传递。

$ssl_options =  [
                        'cafile' => '/rabbitmq/testca/cacert.pem',
                        'local_cert' => '/rabbitmq/client/key-cert.pem',
                        'verify_peer' => false,
                        'verify_peer_name' => false,
            ];

我的 RabbitMQ 配置是根据 docs of VMWare.