July 12, 2019
In this post, we will take a look at enabling TLS for IBM MQ inter-cluster communication. Enabling TLS on the MQ cluster is one of the easiest things you can do for the security of your MQ infrastructure.
Prerequisites
First of all, you need to have your key stores setup on all queue managers in the cluster and certificates loaded into them.
Benefits
Second of all: why? Well, after you authenticated the users or applications connecting to the cluster and then checked their authorizations against OAM for various objects in your MQ infrastructure, they will start sending messages and the MQ cluster will start routing them. Those messages will be transmitted across the wire in the clear, and can be easily intercepted and reconstructed. For this very reason, whenever a message is in flight, it’s a good idea to secure both the origin and the destination with TLS v1.2 or above. If a message is intercepted, it will be encrypted and will take a very long time to decrypt.
An MQ cluster consists of one or more full repository queue managers and one or more partial repository queue managers. Securing the communication in the MQ cluster means enabling TLS on the channels that queue managers use to talk to each other. Each member of the cluster has a cluster-receiver channel and 1 or more cluster-sender channels connecting it to full repositories.
Technical Steps
These steps have been tested on MQ v8 and v9.
- Update cluster-receivers first. Pick a TLS v1.2 cipher and make sure it’s the same on all channels. Run this command for every member of the cluster: full repositories as well as partial repositories.
ALTER CHANNEL (<channel name>) CHLTYPE (CLUSRCVR)
SSLCIPH (ECDHE_RSA_AES_256_GCM_SHA384)
- Take 10-15 minute pause to allow MQ to catch up.
- Update cluster-senders second. Make sure you use the same cipher you used on cluster-receiver channels. Run this command for every member of the cluster: full repositories as well as partial repositories. If you have two full repositories serving your cluster, make sure you run this command on both cluster-sender channels on your partial repositories.
ALTER CHANNEL (<channel name>) CHLTYPE (CLUSSDR)
SSLCIPH (ECDHE_RSA_AES_256_GCM_SHA384)
That’s it! Now your cluster traffic is encrypted. Let me know if these instructions worked for you!
EDIT July 19, 2019:
A user pointed out in the comments that they are getting AMQ9288 after performing steps outlined in the post.
It required further investigation and, I believe, I found a solution. Appending it here for those that run into this issue.
In version 8.0.0.4 IBM changed how GCM ciphers behave (including the one I used in the example).
If you send a certain number of TLS records with the same cipher key the channel will end with AMQ9288.
In order to avoid that, you have two choices:
- Change the number of bytes sent across the channel before a session key is renegotiated by MQ. The default value is 0, which means: don’t renegotiate. Change it with this command:
ALTER QMGR SSLRKEYC(10000000)
It will now be renegotiated after every, approximately, 10MB of data is passed on the channel.
You can specify your own number of bytes up to 999,999,999.
You can also change it in MQ Explorer, under queue manager properties, in SSL tab.
Remember to refresh security of type SSL after you make changes to SSL configuration of the queue manager:
REFRESH SECURITY TYPE(SSL)
- Use a different cipher, e.g.: ECDHE_RSA_AES_256_CBC_SHA384.
Here is a table of all supported MQ v9 ciphers you can pick from: Enabling CipherSpecs
But you need to remember that some of them might require different digital signature algorithms when requesting your certificate, e.g. ECDHE_ECDSA_* ciphers.
You can also enable an environment variable to circumvent this restriction (not recommended for production deployments).
Please refer to this article by IBM for the source of this explanation: Change in behavior for channels using GCM based CipherSpecs
Documentation on how to change SSL reset count: Resetting SSL and TLS secret keys
Are there any further configurations I need to make to avoid getting error AMQ9288 please?
We use multiple certificates in our QM which is partial repository member of a Cluster . Try to turn on TLS and set one of our cert for cluster-receiver channel. The CA for that cert is loaded to cluster’s kdb. Unfortunately the channel shows up the default cert instead of the defined one to the cluster so cluster does not handshake. Did you met with this issue? Thnak you Igor