ActiveMQ双向SSL认证

3
我正在尝试为ActiveMQ设置双向认证,即客户端需要通过证书才能将消息传递到代理。我在代理上创建了一个密钥库和信任库,并导出了一个证书,该证书被复制到客户端。在客户端上,我也做了同样的事情,虽然我正在使用NMS,因此只使用导出的证书,将其添加到代理的信任库中。我还将证书添加到其他计算机的受信任根证书中。
代理的配置如下:
<transportConnectors>  
  <transportConnector name="ssl" uri="ssl://0.0.0.0:61616"/>  
</transportConnectors>  
<sslContext>  
  <sslContext keyStore="file:${activemq.base}/conf/keystore.jks"  
    keyStorePassword="ksPass"  
    trustStore="file:${activemq.base}/conf/shared.ks"  
    trustStorePassword="ksPass"/>  
</sslContext>  
<plugins>  
 <jaasCertificateAuthenticationPlugin configuration="CertLogin" />  
</plugins>  

AMQ服务wrapper.conf文件中包含以下配置:

wrapper.java.additional.8=-Djava.security.auth.login.config="%ACTIVEMQ_CONF%/login.config"

其中"${activemq.base}/conf/login.config"为登录配置文件路径。

CertLogin {
 org.apache.activemq.jaas.TextFileCertificateLoginModule required
 debug=true
 org.apache.activemq.jaas.textfiledn.user="users.properties"
 org.apache.activemq.jaas.textfiledn.group="groups.properties";
};  

${activemq.base}/conf/users.properties has

user=CN=nms.client.170,\ OU=IT,\ O=MyOrg,\ L=Oslo,\ S=Oslo,\ C=NO  

${activemq.base}/conf/groups.properties 包含以下内容:

admins=system  
users=system,user    

在NMS客户端的appSettings中,我使用以下内容进行连接:
< add key="jms.uri" value="ssl://brokeraddress.in.hosts:61616?needClientAuth=true&amp;wantClientAuth=true&amp;transport.clientCertSubject=nms.client.170&amp;transport.clientCertPassword=ksClientPw&amp;transport.clientCertFilename=C:\TestClient\client170.crt" />    

如果代理中没有jaasCertificateAuthenticationPlugin,我可以通过ssl连接,但是如果有它(这是我想要的),我会得到一个错误,在Apache.NMS.ActiveMQ.Connection失败
// 发送连接并查看是否返回ack/nak。
Response response = transport.Request(this.info, this.RequestTimeout);

会获得ExeptionResponse:“java.lang.SecurityException:无法在没有SSL证书的情况下验证传输。”

跟踪显示:

10:19:16,479 INFO  Client.MyTrace - BrokerUri set = ssl://brokeraddress.in.hosts:61616?transport.clientcertpassword=ksClient&transport.clientcertsubject=nms.client.170&needclientauth=true&wantclientauth=true&transport.clientcertfilename=C:\TestClient\client170.crt  
10:19:16,492 DEBUG Client.MyTrace - SetProperties called with target: ConnectionFactory, and prefix: connection.  
10:19:16,492 DEBUG Client.MyTrace - SetProperties called with target: ConnectionFactory, and prefix: nms.  
10:19:16,495 INFO  Client.MyTrace - Connecting to: ssl://brokeraddress.in.hosts:61616/?transport.clientcertpassword=ksClient&transport.clientcertsubject=nms.client.170&needclientauth=true&wantclientauth=true&transport.clientcertfilename=C:\TestClient\client170.crt  
10:19:16,497 DEBUG Client.MyTrace - Searching Assembly: Apache.NMS.ActiveMQ for factory of the id: ssl  
10:19:16,549 DEBUG Client.MyTrace - Found the Factory of type Apache.NMS.ActiveMQ.Transport.Tcp.SslTransportFactory for id: ssl  
10:19:16,552 DEBUG Client.MyTrace - Opening socket to: brokeraddress.in.hosts on port: 61616  
10:19:16,554 DEBUG Client.MyTrace - Connected to brokeraddress.in.hosts:61616 using InterNetwork protocol.  
10:19:16,562 DEBUG Client.MyTrace - Creating new instance of the SSL Transport.  
10:19:16,564 DEBUG Client.MyTrace - Creating Inactivity Monitor: 1  
10:19:16,677 DEBUG Client.MyTrace - Authorizing as Client for Server: brokeraddress.in.hosts  
10:19:16,679 DEBUG Client.MyTrace - Attempting to load Client Certificate from file := C:\TestClient\client170.crt  
10:19:16,682 DEBUG Client.MyTrace - Loaded Client Certificate := [Subject]  CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO [Issuer]  CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,684 DEBUG Client.MyTrace - Client is selecting a local certificate from 1 possibilities.  
10:19:16,684 DEBUG Client.MyTrace - Client has selected certificate with Subject = CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,969 DEBUG Client.MyTrace - ValidateServerCertificate: Issued By CN=brokeraddress.in.hosts, OU=DataCom, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,969 DEBUG Client.MyTrace - Server is Authenticated = True  
10:19:16,970 DEBUG Client.MyTrace - Server is Encrypted = True  
10:19:16,978 DEBUG Client.MyTrace - InactivityMonitor[1]: Read Check time interval: 30000  
10:19:16,978 DEBUG Client.MyTrace - InactivityMonitor[1]: Initial Delay time interval: 10000  
10:19:16,985 DEBUG Client.MyTrace - InactivityMonitor[1]: Write Check time interval: 10000  
10:19:19,017 DEBUG Client.MyTrace - Exception received in the Inactivity Monitor: Unable to read beyond the end of the stream.  
10:19:19,019 DEBUG Client.MyTrace - InactivityMonitor[1].Runner: Task Runner Shut Down  
10:19:19,019 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  
10:19:19,032 DEBUG Client.MyTrace - Connection[ID:EJPB-56409-635193299565662525-1:0]: Async exception with no exception listener: System.IO.EndOfStreamException: Unable to read beyond the end of the stream.  
 System.IO.BinaryRe.FillBuffer(Int32 numBytes)  
 System.IO.BinaryRe.ReadInt32()  
 Apache.NMS.Util.EnBinaryReader.ReadInt32() in c:\dev\NMS\src\main\csharp\Util\EndianBinaryReader.cs:line 135  
 Apache.NMS.ActiveMenWire.OpenWireFormat.Unmarshal(BinaryReader dis) in c:\dev\NMS.ActiveMQ\src\main\csharp\OpenWire\OpenWireFormat.cs:line 228  
 Apache.NMS.ActiveMansport.Tcp.TcpTransport.ReadLoop() in c:\dev\NMS.ActiveMQ\src\main\csharp\Transport\Tcp\TcpTransport.cs:line 295  
10:19:19,035 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: MutexTransport  
10:19:19,035 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: WireFormatNegotiator  
10:19:19,036 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: InactivityMonitor  
10:19:19,036 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  
10:19:19,037 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: SslTransport  
10:19:19,071 INFO  Client.MyTrace - Connection[ID:SUSSDEV2-56409-635193299565662525-1:0]: Closing Connection Now.  
10:19:19,073 DEBUG Client.MyTrace - Connection[ID:SUSSDEV2-56409-635193299565662525-1:0]: Disposing of the Transport.  
10:19:19,073 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  

在代理中显示:

INFO | jvm 1 | 10:18:20 | WARN | Failed to add Connection ID:EJPB-56409-635193299565662525-1:0, reason: java.lang.SecurityException: Unable to authenticate transport without SSL certificate.  
INFO | jvm 1 | 10:18:22 | INFO | Stopping tcp://192.168.5.170:56408 because Failed with SecurityException: Unable to authenticate transport without SSL certificate.  

好的,我错过了什么?它说“没有SSL证书的传输”,但在客户端连接期间选择它,并且在代理的信任商店和根证书中都存在。

使用NMS 1.6.0和activeMQ 5.8.0。
我还尝试了一个简单的Java客户端,结果相同。

Exception in thread "main" javax.jms.JMSException: Unable to authenticate transport without SSL certificate.  
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:49)  
    at org.apache.activemq.ActiveMQConnection.syncSendPacket  (ActiveMQConnection.java:1295)  
    at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent  (ActiveMQConnection.java:1392)  
    at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:504)  
    at com.atest.jms.Client.main(Client.java:69)  
Caused by: java.lang.SecurityException: Unable to authenticate transport without SSL certificate.  
    at org.apache.activemq.security.JaasCertificateAuthenticationBroker.addConnection(JaasCertificateAuthenticationBroker.java:74)  
    at org.apache.activemq.broker.MutableBrokerFilter.addConnection(MutableBrokerFilter.java:91)  
    at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:766)  
    at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:79)  
    at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)  
    at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:329)  
    at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:184)  
    at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)  
    at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)  
    at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:288)  
    at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)  
    at org.apache.activemq.transport.tcp.SslTransport.doConsume(SslTransport.java:91)  
    at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:214)  
    at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)  
    at java.lang.Thread.run(Unknown Source)    

任何人有任何想法吗?谢谢。

编辑2021年11月12日

好的,我再次尝试。我看到我没有添加到代理的transportConnector ssl:

<transportConnector name="ssl" uri="ssl://0.0.0.0:61616?needClientAuth=true"/>  

我尝试使用Java客户端发送消息,可以成功发送,但是使用NMS客户端(相同配置)仍然出现错误:
15:28:14,044 ERROR Test_DataCom.MyTrace - Exception: A call to SSPI failed, see inner exception.
15:28:14,045 ERROR Test_DataCom.MyTrace - Inner exception: An unknown error occurred while processing the certificate
15:28:14,045 ERROR Test_DataCom.MyTrace - Authentication failed - closing the connection.  

在经纪人处我得到了空的证书链。

INFO | jvm 1 | 15:28:13 | ERROR | Could not accept connection from tcp://192.168.50.170:61978: javax.net.ssl.SSLHandshakeException: null cert chain

我在每个受信任的证书库和本地计算机受信任的根CA中都有证书...还需要什么?如果不是那里,自签名证书的证书链应该从哪里获取?

1个回答

1

好的,我现在似乎明白了。重新阅读了这个comment之后,我将客户端证书和密钥导出到PKCS文件中,并将其导入到Windows的当前用户认证存储中。
C:\> keytool -v -importkeystore -srckeystore client-keystore.jks -srcalias client -destkeystore client.p12 -deststoretype PKCS12

然后我使用了这个url编码的连接:
<add key="jms.uri" value="ssl://brokeraddress.in.hosts:61616?needClientAuth=true&amp;wantClientAuth=true&amp;transport.clientCertSubject=CN%3Dnms.client.170%2C+OU%3DIT%2C+O%3DMyOrg%2C+L%3DOslo%2C+S%3DOslo%2C+C%3DNO" />

我还找到了 ${activemq.base}/conf/users.properties 文件:user=CN=nms.client.170,\ OU=IT,\ O=MyOrg,\ L=Oslo,\ S=Oslo,\ C=NO,尝试去掉空格后,将 S 更正为 ST,就像 keytool 报告的 Owner 行一样。我检查过了,否则会出现错误。

更正后的 ${activemq.base}/conf/users.properties 文件如下:
user=CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, ST=Oslo, C=NO


嗨ejpb,我也遇到了相同的“null cert chain”异常。您能告诉我在哪里添加以下行吗? <add key="jms.uri" value="ssl://brokeraddress.in.hosts:61616?needClientAuth=true&amp;wantClientAuth=true&amp;transport.clientCertSubject=CN%3Dnms.client.170%2C+OU%3DIT%2C+O%3DMyOrg%2C+L%3DOslo%2C+S%3DOslo%2C+C%3DNO" /> - Sudheer Kumar
1
这是NMS项目中使用“jms.uri”键的app.config。我发现文件版本更容易,因为有时在存储中查找证书可能会出现问题。clientCertSubject似乎无法与使用本地系统帐户的默认安装服务一起使用,它根本找不到证书。请以另一个用户身份运行,或改用clientCertFilename。')'是NMS查询处理中的分隔符,因此不要将证书放在“C:\Program Files (x86)/folder”等位置。"C:\My files/client.p12"可以正常工作(包括空格、正斜杠和反斜杠)。 - ejpb

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