Part 2 — Enable TLS communications via AMQP

Kok Sing Khong
5 min readMay 1, 2020

--

This is the next installment of the series — to enable TLS communications for the AMQP channel we setup in the previous article. See Part 1 here. In this installment, I am going to show you to scenarios:

  • Server authentication where the AMQP client checks the server certificate from the MQ queue manger
  • Mutual authentication where in addition to server authentication above; there is client authentication where the MQ queue manager checks the client certificate from the AMQP client.

Begin I begin

  1. To simplify this exercise, I have written a script that generate the keys, certificates, keystores and truststores in the format that we need. In order for the script to run, you need to have the following tools:
  • openssl — which is found in most Linux OS
  • ikeycmd — which is packaged in the JRE of the MQ installation
  • keytool — which is packaged in the JRE of the MQ installation.

2. Before you run the script, you should configure the variables.

  • ROOT_CN — the label of the root certificate authority cert.
  • SERVER_CN — the label of the server certificate.
  • CLIENT_CN — the label of the client certificate.
  • C — the name of the country, e.g. AU
  • ST — the name of the state, e.g. VIC (for Victoria)
  • L — the name of the locality or city, e.g. Melbourne
  • O— the name of the organization, e.g. KKS
  • OU — the name of the organization or business unit, e.g. Cloud
  • DNS_1 — the DNS name of the MQ server
  • IP_1 — the IP address of the MQ server
  • PASS — the password for both the server and client keystore (for simplicity)
  • IKEYCMD_PATH — the path of ikeyman, e.g. `/opt/mqm/java/jre64/jre/bin`
  • KEYTOOL_PATH — the path of keytool, e.g. `/opt/mqm/java/jre64/jre/bin`

3. The script generates the following that we are going to use. See scripts here (https://github.com/khongks/amqp-on-mq/blob/master/cert/gen_certs.sh)

  • mqclient.crt — client certificate
  • mqclient.key — client key
  • mqclient.p12 — keystore/truststore that contains the client certificate, client key and the root CA certificate in PKCS12 format; this is used by the AMQP client application.
  • mqserver.crt — server certificate
  • mqserver.key — server key
  • mqserver.p12 — keystore/truststore that contains the server certificate, server key and the root CA certificate in PKCS12 format; this is not used.
  • mqserver.kdb —key database that stores personal certificates, personal certificate requests, and signer certificates.
  • mqserver.rdb — “request” database file that contains certificate requests that are outstanding and have not yet been received from the CA.
  • mqserver.sth — “stash” file that stores an obfuscated version of the key database password; also stores private keys, if there are any.
  • rootca.crt — the root CA signer certificate
  • rootca.key — the root CA key

Step 1: Configure the certificates in the queue manager

  1. Inspect the queue manager to find where we should put the key database files. From here, it shows that the key database files should located in the folder /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl and the file name should be key.kdb.
$ runmqsc AMQP_SAMPLE_QM: DIS QMGRSSLKEYR(/var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key)

2. Login as user of mqm group and copy the following files into the folder; and changing the file names. Change the file ownership if you need to

cp -p mqserver.kdb /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.kdb
cp -p mqserver.rdb /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.rdb
cp -p mqserver.sth /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.sth
chown mqm:mqm /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.kdb
chown mqm:mqm /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.rdb
chown mqm:mqm /var/mqm/qmgrs/AMQP_SAMPLE_QM/ssl/key.sth

Step 2: Server authentication

  1. Instead of using the same channel, we are creating a new AMQP channel for TLS communications. Create the following MQSC file AMQP.CHL.TLS.mqsc.
  • Defines are channel of type AMQP, with the label mqserver that matches the label we used during the creation of the certificate; that listens on port 5671 and specify client authentication SSLCAUTH as OPTIONAL.
  • Reload the SSL configuration into the queue manager memory.
  • Start the channel.
DEF CHL(SAMPLE.AMQP.CHL.TLS) CHLTYPE(AMQP) CERTLABL('mqserver') SSLCAUTH(OPTIONAL) PORT(5671) MCAUSER(nobody) SSLCIPH(TLS_RSA_WITH_AES_256_GCM_SHA384)REFRESH SECURITY TYPE(SSL)
START CHL(SAMPLE.AMQP.CHL.TLS)

2. Run the MQSC file and make sure there is no error.

$ runmqsc AMQP_SAMPLE_QM < SAMPLE.AMQP.CHL.TLS.mqsc

3. Copy the root CA certificate into the ./cert folder.

4. Run the AMQP applications, specifying the following:

  • -s URL, --service=URL: amqps://mqserver:5671
  • -c FILE, --trust-certificate=FILE: rootca.crt

a. Start Receive application.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Receive -s amqps://mqserver:5671 -c ./cert/rootca.crt

b. Start Send application to send 10 messages.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Send -r 10 -s amqps://mqserver:5671 -c ./cert/rootca.crt

Step 3: Mutual authentication

  1. Update the AMQP channel to perform client authentication. Update the previous MQSC file AMQP.CHL.TLS.mqsc.
  • Update the AMQP channel with client authentication — SSLCAUTH as REQUIRED.
  • Reload the SSL configuration into the queue manager memory.
  • Stop and start the channel.
ALTER CHL(SAMPLE.AMQP.CHL.TLS) CHLTYPE(AMQP) SSLCAUTH(REQUIRED) REFRESH SECURITY TYPE(SSL)
STOP CHL(SAMPLE.AMQP.CHL.TLS)
START CHL(SAMPLE.AMQP.CHL.TLS)

2. Run the MQSC file and make sure there is no error.

$ runmqsc AMQP_SAMPLE_QM < SAMPLE.AMQP.CHL.TLS.MUTUAL.mqsc

3. Copy the client keystore/truststore PKCS12 file into the ./cert folder.

4. Run the AMQP applications, specifying the following:

  • -s URL, --service=URL: amqps://mqserver:5671
  • -k FILE, --keystore=FILE: mqclient.p12
  • -p PASSPHRASE, --keystore-passphrase=PASSPHRASE: Passw0rd!

a. Start Receive application.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Receive -s amqps://mqserver:5671 -k ./cert/mqclient.p12 -p Passw0rd!

b. Start Send application to send 10 messages.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Send -r 10 -s amqps://mqserver:5671 -k ./cert/mqclient.p12 -p Passw0rd!

Alternative, instead of the PKCS12 file, you can run the AMQP applications; specify the following:

  • -s URL, --service=URL: amqps://mqserver:5671
  • --client-certificate=FILE: mqclient.crt
  • --client-key=FILE: mqclient.key
  • --client-key-passphrase=PASSPHRASE: Passw0rd!
  • -c FILE, --trust-certificate=FILE: rootca.crt

a. Start Receive application.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Receive -s amqps://mqserver:5671 --client-certificate=./cert/mqclient.crt --client-key=./cert/mqclient.key --client-key-passphrase=Passw0rd! --trust-certificate=./cert/rootca.crt

b. Start Send application to send 10 messages.

java -classpath ./lib/proton-j-0.12.1.jar:./lib/gson-2.2.4.jar:./lib/logback-classic-1.1.2.jar:./lib/logback-core-1.1.2.jar:./lib/netty-all-4.0.21.Final.jar:./lib/slf4j-api-1.7.5.jar:./lib/stateless4j-2.5.0.jar:./mqlight/target/mqlight-api-1.0-SNAPSHOT.jar:./mqlight-samples/target/mqlight-api-samples-1.0-SNAPSHOT.jar com.ibm.mqlight.api.samples.Send -r 10 -s amqps://mqserver:5671 --client-certificate=./cert/mqclient.crt --client-key=./cert/mqclient.key --client-key-passphrase=Passw0rd! --trust-certificate=./cert/rootca.crt

Finally

As with any security type of configuration, it tends to be tedious, hard to debug if you encountered issues. If you have a good understanding of Public Key Infrastructure (PKI) and how TLS/SSL works; you can guess the problems. The most challenging hurdle of this task, for me was really to get the keys, certificates, keystores and truststores generated correctly, and in the right format that is required by the queue manager and the AMQP Java application — trying to figure out how to specify the input paramaters. As you noted, the MQ specific configurations are pretty straight forward. How you find this article useful.

You can find my script here.

https://github.com/khongks/amqp-on-mq/blob/master/cert/gen_certs.sh

--

--

Kok Sing Khong
Kok Sing Khong

No responses yet