Authenticating to an IBM MQ queue manager is commonly done using either LDAP or local operating system users. This blog entry describes an alternative way to use your TLS certificate to authenticate.
In containers, we recommend against using local operating system users, due to the security risks. In particular, IBM MQ validates your operating system user and password by using privilege escalation to run certain checks as the "root" user. The "no install" version of IBM MQ used in our
container sample, and as part of our official container images with the IBM MQ Operator, does not work at all with local operating system users. This leaves LDAP as a key technology choice, but not everyone has an LDAP server (or wants to use one).
IBM MQ allows you to use mutual TLS (where both ends of a connection supply a certificate) to establish identity. You can map the distinguished name of the certificate to a user name. In order to achieve this, you need to do the following things:
- Set up TLS for your queue manager. You'll need a private key and need to add the certificate of any clients or queue managers you want to allow to connect. The details of this are out of the scope of this blog, but more information can be found in Managing TLS certificates.
- Configure the queue manager INI file, to allow you to use a user name that is not known to the system;
- Configure the channel and queue manager settings;
- Configure authority for each user/certificate pair;
Allowing "unknown" users
Normally, the queue manager will validate that a given user is known to the underlying user directory (either in LDAP or a local operating system user). In this scenario, that's exactly what we're trying to avoid. From IBM MQ 9.2.1 onwards, you can skip this check, by setting the security policy to "UserExternal" in your qm.ini file.
Service:
SecurityPolicy=UserExternal
Note that if you're using
automatic configuration of your INI file at startup (as used by MQ in containers), you will need to specify the whole stanza. For example, you can add the following INI snippet in
using a ConfigMap in the MQ Operator on Red Hat OpenShift Container Platform:
Service:
Name=AuthorizationService
EntryPoints=14
SecurityPolicy=UserExternal
For more information, see
Service stanza of the qm.ini file
Configuring the general queue manager settings
Firstly, create a server connection channel to allow clients to connect. Setting "SSLCAUTH" to "REQUIRED" causes the connection to fail if the client doesn't specify a certificate.
DEFINE CHANNEL('MTLS.SVRCONN') CHLTYPE(SVRCONN) SSLCAUTH(REQUIRED) SSLCIPH('ANY_TLS12_OR_HIGHER') REPLACE
If you are
only going to authenticate users via mutual TLS, then you might want to disable regular connection authentication. This means that any user ID and password credentials will not be validated, and will not be adopted as the connection identity. This should only be done in conjunction with the other steps described here!
ALTER QMGR CONNAUTH(' ')
REFRESH SECURITY
It's recommended to create a back-stop channel authentication rule to disallow all certificates, unless explicitly allowed:
SET CHLAUTH('MTLS.SVRCONN') TYPE(SSLPEERMAP) SSLPEER('CN=*') USERSRC(NOACCESS) ACTION(REPLACE)
Configuring authority for each user/certificate
For each user or application you want to connect, you can add the specific certificate details. For example, the following "SSLPEER" maps a certificate with a common name of "application1" and an organisational unit (OU) of "team1" to user "app1". In addition to the "SSLPEER", you should also specify "SSLCERTI" to be very specific about the issuer of the certificate. The "MCAUSER" is the user name which will be adopted. It does not need to be a real user anywhere, because of the previous "UserExternal" configuration.
SET CHLAUTH('MTLS.SVRCONN') TYPE(SSLPEERMAP) SSLPEER('CN=application1,OU=team1') SSLCERTI('CN=applicationCA,OU=Certificate Authority') USERSRC(MAP) MCAUSER('app1') ACTION(REPLACE)
The channel authentication record maps from the certificate to a user, but you must also remember to create an authority record to authorise the user appropriately, for example to allow "app1" to connect and inquire the queue manager (inquire authority is needed for JMS applications to connect):
SET AUTHREC PRINCIPAL('app1') OBJTYPE(QMGR) AUTHADD(CONNECT,INQ)
In conclusion
This technique allows you securely connect to a queue manager, and of course has the added benefits of encryption for your network traffic. It does introduce the need for certificate management, but you most of us should be doing that anyway, especially in cloud environments. Tools like
cert-manager make certificate management much easier.
Many thanks to
@Rob Parker and
@CALLUM JACKSON for collaborating on this technique.