How to Connect to Red Hat AMQ using Artemis and SSL
We can protect our AMQ end point using a specific SSL, preventing those who doesnt have the exact certificate to connecting to my AMQ server’s endpoint.
In order to do so, first we need to create a very simple certificate to be use by our AMQ server with a simple keytool command
keytool -genkey -alias artemists -keyalg RSA -sigalg SHA1withRSA -keystore artemis.ts -keysize 2048
It will generate a new file, artemis.ts
And generate a new keystore,
keytool -genkey -v -keystore broker02.ks -alias broker02 -sigalg SHA1withRSA -keyalg RSA -keysize 2048 -validity 10000
Put string “password” if you need to input a password while generating those two items.
And reference those files on our AMQ broker.xml configuration,
<acceptor name="core"> tcp://0.0.0.0:61617?protocols=CORE;sslEnabled=true; keyStorePath=D:/tmp/broker02.ks;keyStorePassword=password; trustStorePath=D:/tmp/artemis.ts;trustStorePassword=password; enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA,SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,RSA;enabledProtocols=TLSv1,TLSv1.1,TLSv1.2; sslProvider=JDK;sniHost=localhost;anycastPrefix=jms.queue.;multicastPrefix=jms.topic;tcpSendBufferSize=1048576; tcpReceiveBufferSize=1048576;useEpoll=true; amqpCredits=1000;amqpMinCredits=300 </acceptor>
Start our server,
artemis run
We can connect using our artemis client with below command,
artemis producer --url tcp://127.0.0.1:61617?sslEnabled=true --message-count 1
The first time connected, it will shows error on your client’s side,
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
And on your server’s side,
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) [java.base:] at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) [java.base:] at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308) [java.base:] at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:285) [java.base:] at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181) [java.base:] at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164) [java.base:] at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:685) [java.base:]
Means you need to use your server’s cert on your client while making request, there are multiple ways of doing that. The simplest is by putting your server’s certificate on your local client’s trust store.
keytool -exportcert -alias artemists -keystore artemis.ts -file artemis.cer keytool -exportcert -alias broker-server -keystore broker02.ks -file broker02.cer keytool -import -alias artemists -file artemis.cer -cacerts keytool -import -alias broker-server -file broker02.cer -cacerts
Use password “changeit” while importing your certificate to client’s cacerts.
When re-run artemis producer again, it should gives a successful message like this
\bin>artemis producer --url tcp://127.0.0.1:61617?sslEnabled=true --message-count 1 Producer ActiveMQQueue[TEST], thread=0 Started to calculate elapsed time ... Producer ActiveMQQueue[TEST], thread=0 Produced: 1 messages Producer ActiveMQQueue[TEST], thread=0 Elapsed time in second : 0 s Producer ActiveMQQueue[TEST], thread=0 Elapsed time in milli second : 27 milli seconds