【问题标题】:ActiveMQ: Cant enable SSL over StompActiveMQ:无法通过 Stomp 启用 SSL
【发布时间】:2021-04-23 03:49:07
【问题描述】:

我是一个新的 ActiveMQ 用户,尝试通过 ActiveMQ 启用 SSL over Stomp。以前,我已经为 CMS 启用了 SSL over openwire,我尝试同时使用 CMS 的证书设置和 Stomp 的新证书设置。

这是我的证书设置

创建代理密钥库:

keytool -genkeypair -alias broker -keyalg RSA -keysize 4096 -sigalg SHA256withRSA -validity 4383 -keystore AMQBroker.ks -storepass "password" -keypass "password" -dname "CN=localhost" -ext "SAN=DNS:localhost,DNS:%computername%.%userdomain%,IP:0.0.0.0,IP:127.0.0.1" -ext "BC:critical=ca:true" -ext "KU:critical=keyCertSign"

为 CMS 客户端创建密钥库:

keytool -genkey -alias client -keyalg RSA -keysize 4096 -sigalg SHA256withRSA -validity 4383 -keystore AMQClient.ks -storepass "password" -keypass "password" -dname "CN=localhost" -ext "SAN=DNS:localhost,DNS:%computername%.%userdomain%,IP:0.0.0.0,IP:127.0.0.1"

为代理和客户端创建信任库和导入证书

keytool -export -alias broker -keystore AMQBroker.ks -storepass "password" -file AMQBroker.crt
keytool -export -alias client -keystore AMQClient.ks -storepass "password" -file AMQClient.crt
keytool -import -alias client -keystore AMQBroker.ts -storepass "password" -file AMQClient.crt -noprompt
keytool -import -alias broker -keystore AMQBroker.ts -storepass "password" -file AMQBroker.crt -noprompt (This was for the network connector)

将代理密钥库转换为 p12 格式以导出为 .pem 格式以供 CMS 客户端使用:

keytool -importkeystore -srckeystore AMQBroker.ks -destkeystore AMQBroker.p12 -srcstoretype jks -deststoretype pkcs12 -srcalias broker -deststorepass "password" -destkeypass "password" -srcstorepass "password"
openssl pkcs12 -in AMQBroker.p12 -out AMQClient-ts.pem -password pass:"password" -nokeys

将客户端密钥库转换为 p12 格式以导出为 CMS 客户端的 .pem 格式。我还获取了用于使用 Stomp.py 进行测试的 .key 文件

keytool -importkeystore -srckeystore AMQClient.ks -destkeystore AMQClient.p12 -srcstoretype jks -deststoretype pkcs12 -srcalias client -deststorepass "password" -destkeypass "password" -srcstorepass "password"
openssl pkcs12 -in AMQClient.p12 -passin pass:"password" -out AMQClient.pem -passout pass:"password"
openssl pkcs12 -info -in AMQClient.p12 -passin pass:"password" -out AMQClient.key -nodes -nocerts

这里有一些专门尝试使用 Stomp 生成的证书

openssl genrsa -out AMQStomp.key 4096
openssl req -sha256 -new -key AMQStomp.key -out AMQStomp.pem -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,DNS:%userdomain%,DNS:%computername%.%userdomain%,IP:0.0.0.0,IP:127.0.0.1"
keytool -import -alias stomp -keystore AMQBroker.ts -storepass "password" -file AMQStomp.pem -noprompt
keytool -exportcert -rfc -alias broker -keystore AMQBroker.ks -file AMQStomp-ts.pem -storepass "password"

以下是我与 Stomp.py 建立连接的方式

    brokerPort  = 61612
    stomp_key   = 'C:/path/to/AMQStomp.key'
    stomp_cert  = 'C:/path/to/AMQStomp.pem'
    ca_cert     = 'C:/path/to/AMQStomp-ts.pem'
    
    self.__conn = stomp.Connection(host_and_ports=[(brokerHost, brokerPort)],
            auto_content_length=False,
            use_ssl=True,
            ssl_key_file=stomp_key,
            ssl_cert_file=stomp_cert,
            ssl_ca_certs=ca_cert,
            ssl_version=ssl.PROTOCOL_TLSv1_2)
    self.__conn.set_ssl(
            for_hosts=[(brokerHost, brokerPort)],
            cert_file=stomp_cert,
            key_file=stomp_key,
            ca_certs=ca_cert,
            ssl_version=ssl.PROTOCOL_TLSv1_2)

我也尝试过 CMS 证书。

    stomp_key   = 'C:/path/to/AMQClient.key'
    stomp_cert  = 'C:/path/to/AMQClient.pem'
    ca_cert     = 'C:/path/to/AMQClient-ts.pem'

这是我的activemq.xml当前配置的内容

    <sslContext>
        <sslContext 
        keyStore="C:/path/to/AMQBroker.ks"
        keyStorePassword="password"
        trustStore="C:/path/to/AMQBroker.ts"
        trustStorePassword="password" />
    </sslContext>
    
    <transportConnectors>
            <transportConnector name="openwire+ssl" uri="ssl://0.0.0.0:61617?needClientAuth=true&amp;maximumConnections=1000&amp;transport.enabledProtocols=TLSv1.2&amp;wireformat.maxFrameSize=104857600&amp;wireFormat.maxInactivityDuration=-1"/>
            <transportConnector name="stomp+ssl"  uri="stomp+nio+ssl://0.0.0.0:61612?maximumConnections=1000&amp;transport.enabledProtocols=TLSv1.2&amp;needClientAuth=true"/>
    </transportConnectors>

ACTIVEMQ_SSL_OPTS 设置为:

-Djavax.net.ssl.keyStore=C:\path\to\AMQBroker.ks -Djavax.net.ssl.trustStore=C:\path\to\AMQBroker.ts -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStorePassword=password -Djavax.net.debug=ssl

这是我在尝试与 Stomp 连接时遇到的错误

2021-01-18 19:35:40,184 | ERROR | Could not accept connection from null : {} | org.apache.activemq.broker.TransportConnector | ActiveMQ BrokerService[infrastructure] Task-10
java.io.IOException: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at org.apache.activemq.transport.nio.NIOSSLTransport.initializeStreams(NIOSSLTransport.java:196)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.stomp.StompNIOSSLTransport.initializeStreams(StompNIOSSLTransport.java:57)[activemq-stomp-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.java:543)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.nio.NIOTransport.doStart(NIOTransport.java:174)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.nio.NIOSSLTransport.doStart(NIOSSLTransport.java:470)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:64)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.stomp.StompTransportFilter.start(StompTransportFilter.java:65)[activemq-stomp-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.java:169)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:64)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.broker.TransportConnection.start(TransportConnection.java:1072)[activemq-broker-5.15.9.jar:5.15.9]
    at org.apache.activemq.broker.TransportConnector$1$1.run(TransportConnector.java:218)[activemq-broker-5.15.9.jar:5.15.9]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)[:]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)[:]
    at java.base/java.lang.Thread.run(Unknown Source)[:]
2021-01-18 19:35:40,184 | DEBUG | Reason: java.io.IOException: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? | org.apache.activemq.broker.TransportConnector | ActiveMQ BrokerService[infrastructure] Task-10
java.io.IOException: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at org.apache.activemq.transport.nio.NIOSSLTransport.initializeStreams(NIOSSLTransport.java:196)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.stomp.StompNIOSSLTransport.initializeStreams(StompNIOSSLTransport.java:57)[activemq-stomp-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.java:543)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.nio.NIOTransport.doStart(NIOTransport.java:174)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.nio.NIOSSLTransport.doStart(NIOSSLTransport.java:470)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:64)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.stomp.StompTransportFilter.start(StompTransportFilter.java:65)[activemq-stomp-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.java:169)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:64)[activemq-client-5.15.9.jar:5.15.9]
    at org.apache.activemq.broker.TransportConnection.start(TransportConnection.java:1072)[activemq-broker-5.15.9.jar:5.15.9]
    at org.apache.activemq.broker.TransportConnector$1$1.run(TransportConnector.java:218)[activemq-broker-5.15.9.jar:5.15.9]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)[:]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)[:]
    at java.base/java.lang.Thread.run(Unknown Source)[:]

【问题讨论】:

    标签: ssl activemq stomp stomp.py


    【解决方案1】:

    很难从数据中知道客户端和代理之间通过网络发生的事情,这是您需要查看的地方以了解发生了什么问题。 Broker STOMP 模块有许多使用 SSL 配置运行的测试,您可以看到 here

    一种调试方法是设置 JVM 选项以启用 SSL 调试:

    -Djavax.net.debug=ssl
    

    查看握手信息,看看协商出了什么问题。

    【讨论】:

    • 我曾尝试设置 -Djavax.net.debug=ssl 但收到错误并调试在记录器中返回相同的内容,我发现唯一可行的是将传输连接器设置为 到目前为止它似乎有效。我不知道与“无法识别的 SSL 消息,明文连接”有关的错误是什么?但这可能与 Stomp 作为文本协议有关吗?另外,感谢资源链接。
    【解决方案2】:

    我确实从一个较小的测试文件中运行了这个

    下面的代码sn-p是从https://developers.redhat.com/blog/2018/06/14/stomp-with-activemq-artemis-python/修改的

    stomp_test.py

    import time
    import sys
    import stomp
    import ssl
    
    class MyListener(stomp.ConnectionListener):
        def on_error(self, headers, message):
            print('received an error "%s"' % message)
        def on_message(self, headers, message):
            print('received a message "%s"' % message)
        
    hosts = [('localhost', 61613)]
    stomp_key   = 'D:/FOSS/ActiveMQ/conf/AMQClient.key'
    stomp_cert  = 'D:/FOSS/ActiveMQ/conf/AMQClient.pem'
    stomp_ca    = 'D:/FOSS/ActiveMQ/conf/AMQClient-ts.pem'
    conn = stomp.Connection(host_and_ports=hosts,
        use_ssl=True,
        ssl_key_file=stomp_key,
        ssl_cert_file=stomp_cert,
        ssl_ca_certs=stomp_ca,
        ssl_version=ssl.PROTOCOL_TLSv1_2)
    conn.set_ssl(for_hosts=hosts,
        cert_file=stomp_cert,
        key_file=stomp_key,
        ca_certs=stomp_ca,
        ssl_version=ssl.PROTOCOL_TLSv1_2,
        password='password')
    conn.set_listener('', MyListener())
    conn.connect('admin', 'admin', wait=True,headers = {'client-id': 'clientname'} )
    conn.subscribe(destination='A.B.C.D', id=1, ack='auto',headers = {'subscription-type': 'MULTICAST','durable-subscription-name':'someValue'})
    
    conn.send(body=' '.join(sys.argv[1:]), destination='A.B.C.D')
    
    time.sleep(2)
    conn.disconnect()
    

    我还必须向代理的密钥库添加更多扩展(我有点矫枉过正)

    -ext KeyUsage=digitalSignature,keyEncipherment,keyCertSign -ext ExtendedKeyUsage=serverAuth,clientAuth -ext BasicConstraints=ca:true
    
    keytool -genkeypair -alias broker -keyalg RSA -keysize 4096 -sigalg SHA256withRSA -validity 4383 -keystore AMQBroker.ks -storepass "password" -keypass "password" -dname "CN=localhost" -ext "SAN=DNS:localhost,IP:0.0.0.0,IP:127.0.0.1" -ext KeyUsage=digitalSignature,keyEncipherment,keyCertSign -ext ExtendedKeyUsage=serverAuth,clientAuth -ext BasicConstraints=ca:true
    

    我还在 activemq.xml 中的 stomp transportConnector 中删除了 nio

    <transportConnector name="stomp+ssl"  uri="stomp+ssl://0.0.0.0:61613?maximumConnections=1000&amp;transport.enabledProtocols=TLSv1.2&amp;needClientAuth=true"/>
    

    我希望这对遇到类似问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 2017-02-11
      • 2017-10-05
      • 2016-01-27
      • 2018-03-27
      • 2016-09-06
      • 2016-04-17
      • 2019-01-07
      • 2019-08-04
      相关资源
      最近更新 更多