ActiveMQ Artemis "needClientAuth=true" 错误输出 "Empty client certificate chain." 消息 (AMQ222208)
ActiveMQ Artemis "needClientAuth=true" errors out "Empty client certificate chain." message (AMQ222208)
我有 ActiveMQ Artemis 集群,带共享存储的主动备份模式,版本 2.17.0。此集群使用 SSL。
我从 Kafka 集群中获取了 keystore/truststore 个文件,这些文件在 2-way TLS 下工作得很好。我在 Artemis 中重新使用这些文件,它也工作得很好。但是,当我在 URL 字符串中启用 needClientAuth=true
时出现问题。
文档是这样说的:
needClientAuth
This property is only for an acceptor
. It tells a client connecting to this acceptor that 2-way SSL is required. Valid values are true
or false
. Default is false
.
所以如果我想实现2-way TLS,我必须使用这个选项。然后 - 服务器和客户端必须有自己的 keystore/truststore 对。在我的例子中,它对于服务器和客户端都是相同的。
当我在接受器 URL 字符串中有 needClientAuth=true
时,我使用 Artemis CLI 连接到 Artemis 集群,这就是我在 CLI 输出中得到的:
Connection failed::Failed to create session factory
这是 Artemis 实例所说的:
WARN [org.apache.activemq.artemis.core.server] AMQ222208: SSL handshake failed for client from /123.123.123.123:36788: javax.net.ssl.SSLHandshakeException: Empty client certificate chain.
正如我所说,keystore/truststore 在 Kafka 上运行良好,没有问题。但是,它不适用于 ActiveMQ Artemis。如果我从 acceptor
URL 字符串中删除 needClientAuth=true
,一切正常。
下面是我如何生成 keystore/truststore:
# Generate private key and CSR
openssl req -new -newkey rsa:2048 -nodes -days 365 -subj '/CN=something.com/OU=XXX/O=Company/L=City/ST=City/C=XX' -keyout private.key -out mycsr.csr
# Upload CSR to magic website, get back CA and signed certificate.
# ...
# Since CA is chain, and you cannot import chain into keystore/truststore, split into multiple files: ca1.cer and ca2.cer.
# ...
# Create truststore.jks
keytool -importcert -noprompt -alias ca1 -file ca1.cer -keystore truststore.jks
keytool -importcert -noprompt -alias ca2 -file ca2.cer -keystore truststore.jks
# Because it's impossible to create JKS keystore out of private key, first generate PKCS12 keystore:
openssl pkcs12 -inkey private.key -in certificate.cer -export -out keystore.p12
# Now convert PKCS12 keystore to JKS keystore:
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks
# Since above command added only a private key, we also need to add an issued certificate:
keytool -importcert -noprompt -alias certificate -file certificate.cer -keystore keystore.jks
# Some client's (in Kafka) does not work if CA is not added to keystore, so add it:
keytool -importcert -noprompt -alias ca1 -file ca1.cer -keystore keystore.jks
keytool -importcert -noprompt -alias ca2 -file ca2.cer -keystore keystore.jks
# End up with the following files:
keystore.jks
truststore.jks
---------
ca.cer
certificate.cer
private.key
受体URL(needClientAuth=true
):
tcp://server.com:1234?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;sslEnabled=true;needClientAuth=true;keyStorePath=/opt/ssl/keystore.jks;keyStorePassword=123;trustStorePath=/opt/ssl/truststore.jks;trustStorePassword=123
当使用 ActiveMQ Artemis CLI 连接时,我通过这个 URL:
tcp://server.com:1234?sslEnabled=true;keyStorePath=/opt/ssl/truststore.jks;keyStorePassword=123;trustStorePath=/opt/ssl/truststore.jks;trustStorePassword=123
我错过了什么?
经纪人和客户都需要他们自己的证书。您似乎只创建了 1 个证书并在代理和客户端上使用它。
例如,代理需要在其呈现给客户端的密钥库中有自己的证书,并且客户端在其信任库中也有该证书。然后,客户端需要在其密钥库中拥有自己的证书,并将其提交给代理,而代理拥有的是其信任库。
据我所知,你没有这样做。查看 ActiveMQ Artemis 附带的 ssl-enabled-dual-authentication
示例。它包含获得 运行 自签名证书所需的所有 keytool
命令。一旦你得到这个和 运行 简单的自签名证书,你就可以继续使用由证书颁发机构签名的证书。
值得注意的是,如果您使用的是由证书颁发机构签署的证书,您可以 import the CA's root certificate into the JVM's truststore 在代理和客户端上,然后您就不需要弄乱任何单独的信任库。客户端和代理将隐式信任由您的 CA 签名的证书。
最后,您在 ActiveMQ Artemis CLI 中使用的 URL 看起来不正确,因为 keyStorePath
引用了信任库 /opt/ssl/truststore.jks
。
我有 ActiveMQ Artemis 集群,带共享存储的主动备份模式,版本 2.17.0。此集群使用 SSL。
我从 Kafka 集群中获取了 keystore/truststore 个文件,这些文件在 2-way TLS 下工作得很好。我在 Artemis 中重新使用这些文件,它也工作得很好。但是,当我在 URL 字符串中启用 needClientAuth=true
时出现问题。
文档是这样说的:
needClientAuth
This property is only for an
acceptor
. It tells a client connecting to this acceptor that 2-way SSL is required. Valid values aretrue
orfalse
. Default isfalse
.
所以如果我想实现2-way TLS,我必须使用这个选项。然后 - 服务器和客户端必须有自己的 keystore/truststore 对。在我的例子中,它对于服务器和客户端都是相同的。
当我在接受器 URL 字符串中有 needClientAuth=true
时,我使用 Artemis CLI 连接到 Artemis 集群,这就是我在 CLI 输出中得到的:
Connection failed::Failed to create session factory
这是 Artemis 实例所说的:
WARN [org.apache.activemq.artemis.core.server] AMQ222208: SSL handshake failed for client from /123.123.123.123:36788: javax.net.ssl.SSLHandshakeException: Empty client certificate chain.
正如我所说,keystore/truststore 在 Kafka 上运行良好,没有问题。但是,它不适用于 ActiveMQ Artemis。如果我从 acceptor
URL 字符串中删除 needClientAuth=true
,一切正常。
下面是我如何生成 keystore/truststore:
# Generate private key and CSR
openssl req -new -newkey rsa:2048 -nodes -days 365 -subj '/CN=something.com/OU=XXX/O=Company/L=City/ST=City/C=XX' -keyout private.key -out mycsr.csr
# Upload CSR to magic website, get back CA and signed certificate.
# ...
# Since CA is chain, and you cannot import chain into keystore/truststore, split into multiple files: ca1.cer and ca2.cer.
# ...
# Create truststore.jks
keytool -importcert -noprompt -alias ca1 -file ca1.cer -keystore truststore.jks
keytool -importcert -noprompt -alias ca2 -file ca2.cer -keystore truststore.jks
# Because it's impossible to create JKS keystore out of private key, first generate PKCS12 keystore:
openssl pkcs12 -inkey private.key -in certificate.cer -export -out keystore.p12
# Now convert PKCS12 keystore to JKS keystore:
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks
# Since above command added only a private key, we also need to add an issued certificate:
keytool -importcert -noprompt -alias certificate -file certificate.cer -keystore keystore.jks
# Some client's (in Kafka) does not work if CA is not added to keystore, so add it:
keytool -importcert -noprompt -alias ca1 -file ca1.cer -keystore keystore.jks
keytool -importcert -noprompt -alias ca2 -file ca2.cer -keystore keystore.jks
# End up with the following files:
keystore.jks
truststore.jks
---------
ca.cer
certificate.cer
private.key
受体URL(needClientAuth=true
):
tcp://server.com:1234?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;sslEnabled=true;needClientAuth=true;keyStorePath=/opt/ssl/keystore.jks;keyStorePassword=123;trustStorePath=/opt/ssl/truststore.jks;trustStorePassword=123
当使用 ActiveMQ Artemis CLI 连接时,我通过这个 URL:
tcp://server.com:1234?sslEnabled=true;keyStorePath=/opt/ssl/truststore.jks;keyStorePassword=123;trustStorePath=/opt/ssl/truststore.jks;trustStorePassword=123
我错过了什么?
经纪人和客户都需要他们自己的证书。您似乎只创建了 1 个证书并在代理和客户端上使用它。
例如,代理需要在其呈现给客户端的密钥库中有自己的证书,并且客户端在其信任库中也有该证书。然后,客户端需要在其密钥库中拥有自己的证书,并将其提交给代理,而代理拥有的是其信任库。
据我所知,你没有这样做。查看 ActiveMQ Artemis 附带的 ssl-enabled-dual-authentication
示例。它包含获得 运行 自签名证书所需的所有 keytool
命令。一旦你得到这个和 运行 简单的自签名证书,你就可以继续使用由证书颁发机构签名的证书。
值得注意的是,如果您使用的是由证书颁发机构签署的证书,您可以 import the CA's root certificate into the JVM's truststore 在代理和客户端上,然后您就不需要弄乱任何单独的信任库。客户端和代理将隐式信任由您的 CA 签名的证书。
最后,您在 ActiveMQ Artemis CLI 中使用的 URL 看起来不正确,因为 keyStorePath
引用了信任库 /opt/ssl/truststore.jks
。