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

3

我一直在尝试连接到运行在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。

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

这里是根据文档创建的自签名证书的实际路径和文件名: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

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

1
请在问题中发布您用于连接服务器的确切URL,并发布openssl s_client -connect <hostname>:<port> -tls1 -servername <hostname> | openssl x509 -text -noout的输出。通过单击“编辑”将其添加到您的问题中(不要将其作为评论发布)。否则,我们无法重现它,也没有足够的信息来帮助排除故障。 - jww
我在$connection实例化代码中提供了实际的URL。我还发布了命令输出,并更新了文件名和路径为真实的文件名和路径。 - Đuro Mandinić
谢谢@Djuro。有了这些信息,诊断变得很容易。我希望每个人都能提供这样的信息。 - jww
2个回答

1

... 错误:14090086:SSL例程:ssl3_get_server_certificate:证书验证失败"

您正在连接到名为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

您需要回到问题的修订版本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的ca-cert.pem文件。您只需要正确的一个CA,那就是DigiCert High Assurance EV Root CA。您还需要中间文件,名为TERENA SSL High Assurance CA 3

DigiCert High Assurance EV Root 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
  • Thumbprint: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 High Assurance CA 3证书

现在您需要用同样的方法处理TERENA SSL High Assurance CA 3。我相信您可以在TERENA SSL High Assurance CA根证书找到它。它具有以下属性:

  • 序列号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

MY-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)的消息(如果我没记错的话)。

再次更新,如果这是你的意思。 - Đuro Mandinić
我通过从$sslOptions中删除'cafile'和'local_cert'来解决了这个问题,我保留了'peer_name'和'verify_peer_name'。消息发送正常,日志记录也很好。你能否像这样修改你的答案或添加一个新的答案,我会接受它。这有意义吗? - Đuro Mandinić
@DjuroMandinic - 我尝试解决您遇到的其他问题。我无法从外部连接到sphinx.dcu.ie:5671,因此我不知道它是否完全正确。 - jww
目前不应该接受外部连接。我可以确认服务器在5671端口上通过SSL侦听器接受连接并接收消息。日志文件显示如下:=INFO REPORT==== 3-Mar-2016::14:48:14 === accepting AMQP connection <0.20455.1> (136.206.4.190:23456 -> 136.206.1.29:5671)=INFO REPORT==== 3-Mar-2016::14:48:14 === closing AMQP connection <0.20455.1> (136.206.4.190:23456 -> 136.206.1.29:5671) - Đuro Mandinić

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

如果客户端能够连接并且由于超时没有返回提示符,那么您的连接就成功了。请尝试使用您的证书/密钥,直到您成功建立连接。
请注意:这里假设密钥证书是拼接文件。
# 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配置是根据VMWare文档进行的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接