Introducing TLS support for remote CCDT access
In MQ 9.4.1, we have introduced support for accessing Client Channel Definition Tables (CCDT) via HTTPS URLs. Previously, CCDT could only be fetched using unsecured protocols like HTTP or FTP. This update enables secure retrieval of CCDT files using TLS (Transport Layer Security), ensuring that sensitive configuration data is transmitted securely across networks.
This blog will explain and demonstrate how to make use of this new functionality.
Setup
To make use of the new functionality, apart from supplying an HTTPS link to the CCDT location, we need to configure our clients to specify some additional information that is required to initialize the HTTPS connection. Specifically, we need to specify an HTTPS keystore, the corresponding stash file, and the strictness levels for certificate validation and revocation. It is assumed that you already have an HTTPS server that is hosting the CCDT.
Client configuration via mqclient.ini
One way to supply the correct client configuration is via the mqclient.ini configuration file. In the SSL stanza, you will need to set three fields – HTTPSKeyStore, HTTPSCertValidation and HTTPSCertRevocation. HTTPSCertValidation and HTTPSCertRevocation fields are optional and have default values (see below).
The HTTPSKeyStore field points to the location of a PKCS12 keystore that is to be used to enable the secure fetch of the CCDT. To correctly initialize the HTTPS API for TLS, a keystore password that is kept in a stash file is also required – this file is stored in the same directory with the same filename as pointed by HTTPSKeyStore, but with a .sth extension. The stash file is retrieved internally automatically, so no setup is needed from the user.
You can create a PKCS12 keystore with a corresponding stash file and a local HTTPS certificate via the following commands:
1. Create a local keystore (with password 'password’) in /tmp using the runmqakm command :
/opt/mqm/bin/runmqakm -keydb -create -db /tmp/auth_serv.p12 -pw password -type pkcs12 -stash
|
2. Create a local HTTPS certificate with label keycloakhttps:
/opt/mqm/bin/runmqakm -cert -create -db /tmp/auth_serv.p12 -stashed -label keycloakhttps -dn "CN=localhost:32030,O=MYORG,L=MYCITY,ST=MYSTATE,C=GB" -size 4096 -expire 365
|
3. You can check if the certificate was successfully created by running:
/opt/mqm/bin/runmqakm -cert -list -db /tmp/auth_serv.p12 -pw password
|
The HTTPSCertValidation field sets the level of certificate peer name validation performed when establishing HTTPS connections. The field can be set to any of the following values:
1. HOSTNAMECN - check that peer's certificate is valid, signed and belongs to the remote host.
2. ANY (default) - check that peer's certificate is valid and signed, but don't fail if it does not belong to the remote host (if CN field does not match remote host's name).
3. NONE - don't validate server's certificate.
4. If the field is set to any other value, we set it to the default value of ANY.
The HTTPSCertRevocation field sets the level of CRL/OCSP extension checks for HTTPS certificates. The field can be set to any of the following values:
1. REQUIRED (default) - check certificate's revocation status and make sure it is resolved.
2. OPTIONAL - check certificate's revocation status but tolerate if it is unknown.
3. DISABLED - don't check certificate's revocation status.
4. If the field is set to any other value, we set it to the default value of REQUIRED.
An example SSL stanza in the mqclient.ini with all of the above set could look like this:
SSL:
HTTPSKeyStore=/home/user/myuser1/httpskeyrepo.p12
HTTPSCertValidation=ANY
HTTPSCertRevocation=REQUIRED
Client configuration via MQSCO
It is also possible to supply client configuration programmatically via the MQSCO structure in your application code. The MQSCO structure was extended to allow the setting of HTTPSKeyStore, HTTPSCertValidation and HTTPSCertRevocation programmatically, and the order of precedence is such that MQSCO is treated as priority over the mqclient.ini config file entries.
The HTTPSKeyStore location can be set via either a pointer or an offset (via HTTPSKeyStorePtr or HTTPSKeyStoreOffset), while the HTTPSCertValidation and HTTPSCertRevocation fields are enums. Regardless of whether the keystore location was set via a pointer or offset, it is important to not forget to set the HTTPSKeyStoreLength as well.
The expected values for the enums can be found below. They map closely to the behaviour described above.
MQSCO new constants
(HTTPSCertValidation / HTTPSCertRevocation)
|
MQ_HTTPSCERTVAL_DEFAULT
|
MQ_HTTPSCERTVAL_ANY
|
MQ_HTTPSCERTVAL_NONE
|
MQ_HTTPSCERTVAL_HOSTNAMECN
|
MQ_HTTPSCERTREV_DEFAULT
|
MQ_HTTPSCERTREV_REQUIRED
|
MQ_HTTPSCERTREV_DISABLED
|
MQ_HTTPSCERTREV_OPTIONAL
|
If a value for HTTPSCertValidation is set to MQ_HTTPSCERTVAL_DEFAULT or HTTPSCertRevocation is set to MQ_HTTPSCERTREV_DEFAULT, it may be overwritten by contents of the mqclient.ini file, if such are present.
Specifying the HTTPS URL
The HTTPS URL for remote CCDT retrieval can be specified via the usual existing options. Currently, the HTTPS link can be supplied via the following methods (in order of precedence):
- CCDTUrlPtr/CCDTUrlOffset in MQCNO,
- MQCCDTURL environment variable,
- MQCHLLIB environment variable,
- or the ChannelDefinitionDirectory attribute in the Channels stanza of the mqclient.ini
If an HTTPS link was set, then the URL will be accepted and fields in the MQSCO/mqclient.ini will be used to initialise the HTTP API to do the secure HTTPS call.
Error handling
Problem diagnosis should hopefully be simple with this feature. The error message in the error logs, specifically AMQ9795 and AMQ5788 should be detailed enough to pinpoint what the problem is. In combination with our documentation (especially for AMQ9795), it should hopefully be trivial to resolve the problem – refer to the following page in IBM Documentation for the error code explanation and suggested actions.