I have an ActiveMQ Broker living on AWS. I'm trying to secure connections from clients using SSL. I have set up the broker to use SSL, but I don't quite understand where the clients are supposed to get the certificate from. Do I need to copy the cert from the broker and package it with client code? Or do I remotely retrieve the cert programmatically each time the client is launched?
Relevant SSL Setup in activemq.xml
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/broker.ks"
keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts"
trustStorePassword="password"/>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
</transportConnectors>
The clients connecting will be Java clients using JMS. At this point I'm using the default cert that comes packaged with the ActiveMQ installation.
As the ActiveMQ documentation states:
ActiveMQ includes key and trust stores that reference a dummy self signed cert. When you create a broker certificate and stores for your installation, either overwrite the values in the conf directory or delete the existing dummy key and trust stores so they cannot interfere)
Therefore, you should delete the existing broker.ks and broker.ts and create new ones for your installation. You've got a couple of options here.
I imagine that AWS has some sort of infrastructure to acquire SSL certificates and that those certificates would be signed by a well-known certificate authority which would be trusted implicitly by your JMS clients. A quick search turned up AWS Certificate Manager.
However, you also have the option of using a "self-signed" certificate which is, by definition, not signed by a well-known certificate authority and therefore must be explicitly trusted by your clients.
You can take the self-signed route by using the following commands:
Using keytool (from the JDK), create a certificate for the broker:
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
Export the broker's certificate so it can be shared with clients:
keytool -export -alias broker -keystore broker.ks -file broker_cert
Create a certificate/keystore for the client:
keytool -genkey -alias client -keyalg RSA -keystore client.ks
Create a truststore for the client, and import the broker's certificate. This establishes that the client "trusts" the broker:
keytool -import -alias broker -keystore client.ts -file broker_cert
When starting the client's VM, specify the following system properties:
javax.net.ssl.trustStorePassword=password
javax.net.ssl.trustStore=/path/to/client.ts
If you choose the self-signed route then you only need to generate the client.ts once and then copy that to every client. The clients will use the same truststore every time they connect (assuming the broker's certificate doesn't change).
Related
I have an MQTT broker with ActiveMQ on an Ubuntu server with Windows clients. Now I want to enable SSL. I found the tutorial, but I have a question.
This step 1: I do on Mqtt broker activemq
Step 1 Create a certificate for the broker with keytool:
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
Step 2 export the broker's certificate so it can be shared with clients: This action on MQTT broker Server. Certificat will be installed on Windows cleint.
keytool -export -alias broker -keystore broker.ks -file broker_cert
Step 3 see below Create a certificate/keystore for the client:
Do I need this step? where to perform this step? On client or Mqtt broker server? but there are windows cleint.
keytool -genkey -alias client -keyalg RSA -keystore client.ks
*Step 4. Do I need this step? where to perform this step? On client or MQTT broker server? but there are windows client.
Create a truststore for the client, and import the broker's certificate. This will ensure that the client "trusts" the broker:*
keytool -import -alias broker -keystore client.ts -file broker_cert
What do I have to do now to make the broker and the windows client use the certificate?
The instructions cover both the broker-side and client-side.
The broker hosts the self-signed SSL certificate to hand out on SSL connections, and the client needs the key in a 'truststore' to allow the key from the broker since it is self-signed and not from one of the public SSL key signers that are already provided by most OS and dev stacks.
Keep in mind-- SSL encrypts the traffic, but also maintains 'who to trust'. Just b/c some server hands out a SSL key, doesn't mean the client should simply encrypt and start passing data to that server.
EDIT: Some config samples
At minimum:
<broker ..
..
<sslContext>
<sslContext keyStore="broker1-keystore.ks"
keyStorePassword="password"/>
</sslContext>
..
</broker>
Advanced ref: https://activemq.apache.org/ssl-transport-reference
#Pavlovich
I installed the certificate on client.
I change activeqm.xml like:
transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
I'm trying to test the connection with a certificate using mqtt fx and it doesn't work.
i keep getting mqtt exception
ERROR --- BrokerConnectService : MqttException
Thx
I got a serious problem while making an SSL request to the server with SOAPUI. I am a newbie in SoapUI and maybe I did something wrong while I'm trying to import the certificate into SOAPUI.
My client sends me:
Root CA
Intermediate CA
SSL CA
Private Key
I am using keytore to generate keystore with password by command
keytool -genkey -alias soapui -keyalg RSA -keystore soapui.keystore
And then I tried to export the this keystore with my SSL CA
keytool -export -alias soapui -file SSL.cer -keystore soapui.keystore
And then I import this into Keystores in the SoapUI.
However, I got the error
ERROR:java.security.KeyStoreException: Can't build keystore: [Private key missing (bad password?)]
I have no idea where am I wrong?
Could anyone please indicate what are the steps I should work on to make the SSL request to SoapUI?
Please help
Thank you.
I assume you need to make a Two-Way SSL connection with client cetificate.
Firstly you need to make a keystore (JKS) containing:
your private key
all certificates upwards including the root CA
Maybe using https://keystore-explorer.org/ may help you to understand and verify the content of your keystore.
There are multiple ways to configure the client certificate in SoapUI:
If you use the global configuration (File - Preferences - SSL Settings), there is only one password to be set. Make sure your keystore password and key password are equal.
If you use the setup on the project level, you are allowed to enter two passwords.
I have a xmpp server (openfire 3.9.3) and trying to secure my non-ssl connection to ssl connection.
that's why i have created a self-signed certificate using java keytool as
keytool -genkey -keystore keystore -alias example.com
and i filled the several pieces of information required for the certificate.
the certificate successfully created. and i configured my server to access the keystore file but when restart my xmpp server it says
Unable to access certificate store. The keystore may be corrupt
what should i do for fixing the same issue ?
thanks in advanced
You can :
Delete certs in AdminWEB interface.
Restart openfire
Delete /opt/openfire/resources/security/keystore file
Generate new cert from web interface.
References : http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/ssl-guide.html
Hope this help...:)
Has anyone managed to install a CA certificate into an activemq instance? I've been doing google searches and reading the activemq documentation but I haven't found anything on how to use a pre-existing CA certificate in activemq.
I assume I install it into the activemq keystore. Is that correct? I'll be using it with websockets and mqtt on the client end.
Also, just in case my assumptions are incorrect, here's why I think I need to use my current CA certificate.
1) I have a web application and our users require communication with the server to be secure. All http traffic is secure.
2) All modern web browsers have a same-origin policy for websockets. They also seem to have a no-mixed-content policy. And so because my http traffic is secure I also have to use secure websockets. (I also have to run the activemq server at the same url)
I'd rather not tunnel the websocket traffic over http because then I have to worry about the apache configuration in addition to the activemq configuration - just another place for things to potentially go wrong.
Also, I don't transfer any sensitive information over the websocket so I could potentially leave it unsecured, but first, my users probably wouldn't understand that, but also it looks like browsers have a no-mixed-content policy.
Has anyone gone through what I'm going through? Any tips?
I eventually got this working, but ultimately I decided to tunnel my websockets communication through apache using the ws_tunnel module.
But to answer my question above, basically what you have to do is create a new java keystore based on your webserver keys, and then replace the apachemq java keystore with this new keystore. I was never able to successfully import the keys into the existing keystore.
For example, on my ubuntu server, my keys are:
SSLCertificateFile /etc/apache2/ssl/star_astracorp_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/star_astracorp_com.key
SSLCertificateChainFile /etc/apache2/ssl/astracorp.com.intermediate.sha1.chcrt
I then export the key as pkcs12:
openssl pkcs12 -export -in /etc/apache2/ssl/star_astracorp_com.crt -inkey /etc/apache2/ssl/star_astracorp_com.key -out server.p12 -name emsu1 -CAfile ca.crt -caname root
I then import the pkcs12 into a new java keystore:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/apache2/ssl/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsu1
Then, in my apachemq directory I move the old broker.ks out of the way and rename server.keystore as kroker.ks and restart activemq.
One of my servers had .pem files for its keys. The process was still similar, however I had to go into OS X's keystore utility to get the password of the key.
openssl pkcs12 -export -in /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.cert.pem -inkey /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.key.pem -out server.p12 -name emsdev -CAfile ca.crt -caname root
you will then be asked for the key - copy and paste it from the key util.
Then, the process to create a new keystore is the same:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/certificates/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsdev
I am now trying to access the web service via https and to achieve this i have done the below.
I used the below commands to generate the self signed certificate and placed in /conf dir.
keytool -genkey -alias localhost -keyalg RSA -validity 365 –keystore server.keystore –storetype JKS
keytool -export -alias localhost –keystore server.keystore -rfc -file public.cert
keytool -import -alias localhost -file public.cert –storetype JKS -keystore server.truststore
Below is the server.xml entry
<Connector className="org.apache.catalina.connector.http.HttpConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true"
acceptCount="10" debug="0" scheme="https" secure="true">
<Factory className="org.apache.catalina.net.SSLServerSocketFactory"
keystoreFile="conf/server.keystore"
keystorePass="changeit"
truststoreFile="conf/server.truststore"
truststoreType="JKS" truststorePass="changeit"
clientAuth="false" protocol="TLS"/>
</Connector>
And now i am facing the below error.
{http://xml.apache.org/axis/}stackTrace: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
However the error is not thrown if i add the below code in the class file accessing the webservice.
AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
Could you please guide me in resolving this issue?
TLS is being set up on two sides: server and client. Each side must have its own key pair saved into a key store. Let's call them serverKeystore.jks and clientKeystore.jks
Then additional key store is to be created containing only public key. This one is called trust store and used for key authentication. Let's follow the same scheme and save them into serverTruststore.jks and clientTruststore.jks.
In one way TLS only server key is being authenticated.
Server must have only serverKeystore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
In two way TLS both server and client keys are being authenticated.
Server must have serverKeystore.jks and clientTruststore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
Client registers key stores either by specifying Java environment variable with
-Djavax.net.ssl.keyStore="path\\to\\server.keystore"
in parameters to command starting JVM, or programmatically in the code with
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
Technically it is possible to use the same key pair both on client and server side as you did. But this compromises the private key, as it is not secret any more.
The below entry is added in the class file where the call to https would happen and it works like charm. Yet i am not sure why the xml entry is not considered.
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", "path\\to\\server.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
PS: Both xml entry and the class entry is needed else the same error is thrown. I am yet to get a clear picture on this. Maybe someone might explain. Thanks