Configuring MQ server SSL communication on Linux

Ivan Slavka
12 min readJul 20, 2023

Table of Contents

Introduction

In this article, I wrote about how to connect your MQ server to LDAP via SSL. Although that article provides a good start into SSL, I still feel like there are some unknowns regarding SSL communication in MQ environment. For this reason, I decided to write one more how-to article about SSL communication. This time, the SSL communication will be between MQ server and MQ client. Although, I could write a simple Java MQ client, for the demonstration purposes I decided to use MQ Explorer as MQ client. In the end, both clients require having keystore and truststore where SSL certificates will be stored.

Certificates Structure

Our SSL certificates will have the following setup. CA Company, is the top certification authority (CA) which is entitled to issue certificates. Consider it as main CA in fictional company. This company has two different departments, accounting and human resources. Each department has its own CA, which is entitled to issue certificates to their own users. In addition, we have a third party company CA, which has no affiliation with our main company CA, nevertheless this CA is entitled to issue certificates inside its own hierarchical system.

For the demonstration purposes, MQ server will belong to Accounting department, and therefore it will have user-accounting certificate. The MQ Explorer will belong to Human Resources department and will have user-human-resources certificate.

A snippet to generate all the necessary certificates. Please note that none of the private keys are secured by password. Only key pairs (*.pfx), are secured by password (passw0rd) since, runmqckm command can’t parse empty password.

# Generate CA Company
openssl genrsa -out ca-company.key 2048
openssl req -x509 -new -nodes -key ca-company.key -sha256 -days 3650 -out ca-company.pem -subj "/CN=ca-company"

# Generate CA Accounting
openssl genrsa -out ca-accounting.key 2048
openssl req -new -key ca-accounting.key -out ca-accounting.csr -subj "/CN=ca-accounting"
openssl x509 -req -in ca-accounting.csr -CA ca-company.pem -CAkey ca-company.key -CAcreateserial -out ca-accounting.crt -days 3650 -sha256

# Generate User Accounting
openssl genrsa -out user-accounting.key 2048
openssl req -new -key user-accounting.key -out user-accounting.csr -subj "/CN=user-accounting"
openssl x509 -req -in user-accounting.csr -CA ca-accounting.crt -CAkey ca-accounting.key -CAcreateserial -out user-accounting.crt -days 3650 -sha256
cat user-accounting.crt ca-accounting.crt ca-company.pem > user-accounting-full.crt
openssl pkcs12 -export -out user-accounting.pfx -inkey user-accounting.key -in user-accounting.crt -passout pass:passw0rd

# Generate CA Human Resources
openssl genrsa -out ca-human-resources.key 2048
openssl req -new -key ca-human-resources.key -out ca-human-resources.csr -subj "/CN=ca-human-resources"
openssl x509 -req -in ca-human-resources.csr -CA ca-company.pem -CAkey ca-company.key -CAcreateserial -out ca-human-resources.crt -days 3650 -sha256

# Generate User Human Resources
openssl genrsa -out user-human-resources.key 2048
openssl req -new -key user-human-resources.key -out user-human-resources.csr -subj "/CN=user-human-resources"
openssl x509 -req -in user-human-resources.csr -CA ca-human-resources.crt -CAkey ca-human-resources.key -CAcreateserial -out user-human-resources.crt -days 3650 -sha256
cat user-human-resources.crt ca-human-resources.crt ca-company.pem > user-human-resources-full.crt
openssl pkcs12 -export -out user-human-resources.pfx -inkey user-human-resources.key -in user-human-resources.crt -passout pass:passw0rd

# Generate CA Third Party Company
openssl genrsa -out ca-third-party-company.key 2048
openssl req -x509 -new -nodes -key ca-third-party-company.key -sha256 -days 3650 -out ca-third-party-company.pem -subj "/CN=ca-third-party-company"

# Generate User Third Party Company
openssl genrsa -out user-third-party-company.key 2048
openssl req -new -key user-third-party-company.key -out user-third-party-company.csr -subj "/CN=user-third-party-company"
openssl x509 -req -in user-third-party-company.csr -CA ca-third-party-company.pem -CAkey ca-third-party-company.key -CAcreateserial -out user-third-party-company.crt -days 3650 -sha256
openssl pkcs12 -export -out user-third-party-company.pfx -inkey user-third-party-company.key -in user-third-party-company.crt -passout pass:passw0rd

Preparing MQ container

Before we enable SSL communication, it’s necessary to prepare MQ server keystore as well as MQ client keystore and truststore. In order to evade potential Java compatibility issues for MQ Explorer, I’ll be using runmqckm command to generate and populate all necessary keystores with certificates.

To do this, I’ll be using MQ docker container. In case you don’t have one, check out my article on how to build one yourself.

Once you have your MQ container up and running, it’s time to prepare keystores.

Generating SSL certificates

First, we’ll need to generate all the necessary certificates. Inside the container prompt, run the following commands to create ssl folder. This folder will hold all the generated certificates.

su - mqm
mkdir "ssl" && cd "$_"

Now, copy, paste and execute the commands for certificate generation. You can find them here.

Once the commands are executed, your folder should look similar to this.

(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$ pwd
/home/mqm/ssl
(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$ ll
total 120
drwxrwxr-x 2 mqm mqm 4096 Jun 24 19:11 ./
drwxr-xr-x 4 mqm mqm 4096 Jun 24 18:59 ../
-rw-rw-r-- 1 mqm mqm 997 Jun 24 19:11 ca-accounting.crt
-rw-rw-r-- 1 mqm mqm 895 Jun 24 19:11 ca-accounting.csr
-rw------- 1 mqm mqm 1675 Jun 24 19:11 ca-accounting.key
-rw-rw-r-- 1 mqm mqm 41 Jun 24 19:11 ca-accounting.srl
-rw------- 1 mqm mqm 1675 Jun 24 19:11 ca-company.key
-rw-rw-r-- 1 mqm mqm 1115 Jun 24 19:11 ca-company.pem
-rw-rw-r-- 1 mqm mqm 41 Jun 24 19:11 ca-company.srl
-rw-rw-r-- 1 mqm mqm 1005 Jun 24 19:11 ca-human-resources.crt
-rw-rw-r-- 1 mqm mqm 903 Jun 24 19:11 ca-human-resources.csr
-rw------- 1 mqm mqm 1679 Jun 24 19:11 ca-human-resources.key
-rw-rw-r-- 1 mqm mqm 41 Jun 24 19:11 ca-human-resources.srl
-rw------- 1 mqm mqm 1679 Jun 24 19:11 ca-third-party-company.key
-rw-rw-r-- 1 mqm mqm 1147 Jun 24 19:11 ca-third-party-company.pem
-rw-rw-r-- 1 mqm mqm 41 Jun 24 19:11 ca-third-party-company.srl
-rw-rw-r-- 1 mqm mqm 3117 Jun 24 19:11 user-accounting-full.crt
-rw-rw-r-- 1 mqm mqm 1005 Jun 24 19:11 user-accounting.crt
-rw-rw-r-- 1 mqm mqm 899 Jun 24 19:11 user-accounting.csr
-rw------- 1 mqm mqm 1679 Jun 24 19:11 user-accounting.key
-rw------- 1 mqm mqm 2301 Jun 24 19:11 user-accounting.pfx
-rw-rw-r-- 1 mqm mqm 3137 Jun 24 19:11 user-human-resources-full.crt
-rw-rw-r-- 1 mqm mqm 1017 Jun 24 19:11 user-human-resources.crt
-rw-rw-r-- 1 mqm mqm 907 Jun 24 19:11 user-human-resources.csr
-rw------- 1 mqm mqm 1675 Jun 24 19:11 user-human-resources.key
-rw------- 1 mqm mqm 2309 Jun 24 19:11 user-human-resources.pfx
-rw-rw-r-- 1 mqm mqm 1029 Jun 24 19:11 user-third-party-company.crt
-rw-rw-r-- 1 mqm mqm 911 Jun 24 19:11 user-third-party-company.csr
-rw------- 1 mqm mqm 1679 Jun 24 19:11 user-third-party-company.key
-rw------- 1 mqm mqm 2317 Jun 24 19:11 user-third-party-company.pfx
(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$

Generate key.kdb

Since our MQ server will belong to the Accounting department, it’s necessary to import its certificate into key.kdb keystore, so that it’s able to authenticate itself to our client. Following commands generate key.kdb keystore and populate it with our user-accounting certificate.

# Generate key.kdb
rm -f /home/mqm/qmgrs/data/QMgr01/ssl/key.*
runmqckm -keydb -create -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -pw passw0rd -type cms -stash
runmqckm -cert -import -file /home/mqm/ssl/user-accounting.pfx -pw passw0rd -type pkcs12 -target /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -target_stashed -target_type cms
runmqckm -cert -list -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -type cms -stashed
runmqckm -cert -rename -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -stashed -label user-accounting -new_label ibmwebspheremqqmgr01
runmqckm -cert -list -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -type cms -stashed
runmqckm -cert -details -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -type cms -stashed -label ibmwebspheremqqmgr01

I understand, and I agree, that there are some commands here, that are redundant. However, as I’m writing a how-to guide, I thought it would be beneficial to show, how each command is used.

The output should look similar to this:

(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$ runmqckm -cert -details -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -type cms -stashed -label ibmwebpsheremqqmgr01
Label: ibmwebpsheremqqmgr01
Key Size: 2048
Version: X509 V1
Serial Number: 78 1F 55 4B 05 FC A7 EF 8F 39 1F 95 29 C9 6C 33
4F 1F 00 AF
Issued by: CN=ca-accounting
Subject: CN=user-accounting
Valid: From: Saturday, June 24, 2023 7:11:47 PM UTC To: Tuesday, June 21, 2033 7:11:47 PM UTC
Fingerprint:
SHA1: 09:56:61:34:23:EC:A1:0F:E5:31:35:57:CD:E8:48:39:2A:19:B4:FF
SHA256: C3:72:59:24:8C:BB:9C:F0:69:A4:2A:48:2D:3F:99:CF:AD:57:AC:27:E3:3B:7F:85:1D:33:A8:FF:85:FF:25:FF
HPKP: eZazhTtFpwvoATnlw7Gn+DruIiA1tVxxhmXpKBPTtwo=


Extensions:
Signature Algorithm: SHA256withRSA (1.2.840.113549.1.1.11)
Trust Status: enabled

What is important to note here, is that we have changed certificate label from user-accounting to ibmwebspheremqqmgr01. This is a default label that MQ server uses when communicating over SSL.

Unfortunately, populating key.kdb with user-accounting certificate is not enough. In order for SSL communication to work, it’s necessary to import a full certificate chain for both departments.

# Populate key.kdb with a full certificate chain
runmqckm -cert -add -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -file /home/mqm/ssl/ca-company.pem -stashed
runmqckm -cert -add -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -file /home/mqm/ssl/ca-accounting.crt -stashed
runmqckm -cert -add -db /home/mqm/qmgrs/data/QMgr01/ssl/key.kdb -file /home/mqm/ssl/ca-human-resources.crt -stashed

In addition, every time there are changes in key.kdb store, don’t forget to refresh MQ SSL security.

runmqsc QMgr01 <<< "refresh security type(ssl)"

Generate keystore.jks

A keystore.jks is a store where our MQ client (MQ Explorer) stores its certificate in order to identify itself. Therefore, let’s import user-human-resources certificate into it.

rm -f /home/mqm/ssl/keystore.jks
runmqckm -keydb -create -db /home/mqm/ssl/keystore.jks -pw passw0rd -type jks
runmqckm -cert -import -file /home/mqm/ssl/user-human-resources.pfx -pw passw0rd -type pkcs12 -target /home/mqm/ssl/keystore.jks -target_pw passw0rd -target_type jks
runmqckm -cert -list -db /home/mqm/ssl/keystore.jks -pw passw0rd
runmqckm -cert -details -db /home/mqm/ssl/keystore.jks -pw passw0rd -label user-human-resources

The output:

(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$ runmqckm -cert -details -db /home/mqm/ssl/keystore.jks -pw passw0rd -label user-human-resources
Label: user-human-resources
Key Size: 2048
Version: X509 V1
Serial Number: 56 FA 5C A1 14 41 E0 09 50 8E 8B 09 EF F9 D4 BB
54 40 F9 51
Issued by: CN=ca-human-resources
Subject: CN=user-human-resources
Valid: From: Saturday, June 24, 2023 7:11:47 PM UTC To: Tuesday, June 21, 2033 7:11:47 PM UTC
Fingerprint:
SHA1: F9:11:2A:64:30:3B:D7:AD:12:37:F3:8D:AB:DA:25:C2:6D:A2:DF:9A
SHA256: 7D:C5:2C:CE:60:17:2E:C0:D2:A2:BF:85:A2:20:34:12:10:DC:56:B9:23:1F:85:35:EF:7F:43:D9:14:AC:74:9D
HPKP: g0kWos3ePal4NkAuE6ARPmaLcQwV0YF5rAb7lk9j98Q=


Extensions:
Signature Algorithm: SHA256withRSA (1.2.840.113549.1.1.11)
Trust Status: enabled

Generate truststore.jks

Truststore.jks is used by MQ client to check and verify whether the MQ server has provided valid identification. Without it, it can’t trust the MQ server and therefore the communication won’t be established. Let’s import our MQ server public key (user-accounting.crt).

rm -f /home/mqm/ssl/truststore.jks
runmqckm -keydb -create -db /home/mqm/ssl/truststore.jks -pw passw0rd -type jks
runmqckm -cert -add -db /home/mqm/ssl/truststore.jks -file /home/mqm/ssl/user-accounting.crt -pw passw0rd
runmqckm -cert -list -db /home/mqm/ssl/truststore.jks -pw passw0rd
runmqckm -cert -details -db /home/mqm/ssl/truststore.jks -pw passw0rd -label cn=user-accounting

The output:

(mq:9.0)mqm@1fa9b9d34b1b:~/ssl$ runmqckm -cert -details -db /home/mqm/ssl/truststore.jks -pw passw0rd -label cn=user-accounting
Label: cn=user-accounting
Key Size: 2048
Version: X509 V1
Serial Number: 78 1F 55 4B 05 FC A7 EF 8F 39 1F 95 29 C9 6C 33
4F 1F 00 AF
Issued by: CN=ca-accounting
Subject: CN=user-accounting

Valid: From: Saturday, June 24, 2023 7:11:47 PM UTC To: Tuesday, June 21, 2033 7:11:47 PM UTC
Fingerprint:
SHA1: 09:56:61:34:23:EC:A1:0F:E5:31:35:57:CD:E8:48:39:2A:19:B4:FF
SHA256: C3:72:59:24:8C:BB:9C:F0:69:A4:2A:48:2D:3F:99:CF:AD:57:AC:27:E3:3B:7F:85:1D:33:A8:FF:85:FF:25:FF
HPKP: eZazhTtFpwvoATnlw7Gn+DruIiA1tVxxhmXpKBPTtwo=


Extensions:
Signature Algorithm: SHA256withRSA (1.2.840.113549.1.1.11)
Trust Status: enabled

Testing the SSL communication

Now that we have all the keystores populated, it’s time to configure MQ Explorer to connect to MQ server via SSL. Before we’re able to do that, we need to copy our keystore.jks and truststore.jks from our docker container to the local machine where the MQ Explorer is installed. Navigate to the folder where you want to copy keystores to, and execute the following commands.

docker cp QMgr01:/home/mqm/ssl/keystore.jks .
docker cp QMgr01:/home/mqm/ssl/truststore.jks .

In my case:

ivansla@BloodRayne:~/Repositories/medium/ibm-mq-ssl/company$ pwd
/home/ivansla/Repositories/medium/ibm-mq-ssl/company
ivansla@BloodRayne:~/Repositories/medium/ibm-mq-ssl/company$ ll
total 16
drwxrwxr-x 2 ivansla ivansla 4096 Jun 24 22:35 ./
drwxrwxr-x 3 ivansla ivansla 4096 Jun 24 20:06 ../
-rw------- 1 root root 2076 Jun 24 21:54 keystore.jks
-rw------- 1 root root 776 Jun 24 22:13 truststore.jks

Don’t forget to change file ownership if necessary.

If you have followed my guide on Running IBM MQ in Docker container, you should be able to connect your MQ Explorer without any issue to MQ server.

In order to enable SSL communication, it’s necessary to modify two things. A channel (SYSTEM.ADMIN.SVRCONN) over which MQ Explorer is connected to MQ server, and connection details that MQ Explorer is using.

Modifying SYSTEM.ADMIN.SVRCONN channel

In your MQ Explorer navigate to channels subfolder and do right-click on channel called SYSTEM.ADMIN.SVRCONN. When the context menu opens, choose Properties…

In the properties dialog window, navigate to SSL menu and choose one of SSL Cipher Specs. I chose TLS_RSA_WITH_AES_128_CBC_SHA256.

Modifying MQ Explorer Connection Details

In the main window, right-click on your Queue Manger instance and open Connection Details Properties.

In the Properties dialog window, navigate to SSL key repositories menu and assigned truststore.jks for Trusted Certificate Store, and keystore.jks for Personal Certificate store. If you have enabled storing of passwords you should be able to enter password as well, if not, you will be prompted for password at connection time. (Quick reminder, password for both stores is passw0rd)

After configuring SSL key repositories, navigate to SSL options menu. Here it’s necessary to configure again SSL Cipher Spec. A quick note, the Cipher Spec here and the one on the channel must be the same or the SSL communication won’t work.

Once you press the OK button, you will be notified that these changes will disconnect you from the Queue Manager. Don’t worry and press yes.

Now simply reconnect to your Queue Manager instance. Right-click on Queue Manager instance and then press Connect.

If you have followed everything to the letter, you should be successfully connected to Queue Manager again, this time, however, over SSL.

Troubleshooting

In case, you accidentally perform incorrect configuration and lose a connection to your Queue Manager. This command will return your channel configuration to prior state, where SSL is disabled.

runmqsc QMgr01 <<< "alter CHANNEL(SYSTEM.ADMIN.SVRCONN) CHLTYPE(SVRCONN) SSLCAUTH(REQUIRED) SSLCIPH('')"

If you execute this command, don’t forget to remove Cipher Spec configuration in your Connection Details as well.

Also, if the error still continues, you may get the error details from error log files on path: /home/mqm/qmgrs/data/QMgr01/errors, or by executing the following command in your docker console.

cat /home/mqm/qmgrs/data/QMgr01/errors/AMQERR01.LOG

Advanced configuration

Securing channel for specific certificate

Current SSL communication will work with any certificate issued by CA Accounting. In case, you want to limit the access to the channel to specific certificate, you can do so by configuring it to accept only certificates with specific DN.

Importing SSL full chain.

While working with key.kdb store, you may have noticed, that after importing user-accounting certificate, it was necessary to import additional certificates, in order to complete the certificate chain.

What I like to do is, create a full certificate chain before I create pfx (merged private and public keys) file. To do this, you can use the following command to chain public certificates into one file. Please note that the order is important.

cat user-accounting.crt ca-accounting.crt ca-company.pem > user-accounting-full.crt

Conclusion

You may have noticed that I haven’t used third party certificates anywhere. Well, that’s because I’m leaving that task to you so you can experiment some more with the behavior of SSL communication. The task is rather simple, make the SSL communication work with a third party certificate as your client (MQ Explorer) certificate. Send me a message or a comment in case you have some difficulty making it work.

This was just one more article regarding configuring SSL communication on MQ server, I hope it helps.

--

--