Search code examples
ibm-mqpymqi

Pymqi - Connecting to IBM mq with SSL


I am able to connect to IBM mq through Pymqi using installed MQ client v9 on my Linux machine. There is requirement of connecting through SSL. How should I create key repository for two way TLS(mTLS)?


Solution

  • I have configured mutual tls between a python application using PyMQI backed with the IBM MQ toolkit for MacOS (9.1.5.0) and a queue manager running on a Raspberry Pi (9.2.0.0).

    I have used self-signed certificates to make it easier to illustrate an end-to-end example of a TLS configuration with MQ. This would not normally be used in a production environment; your MQ administrator will typically provide any certificates that you might need to use which are often issued by a certificate authority. Where this is the case you can skip the certificate creation steps below.

    Here are the steps I took:

    Initial server and Python code setup

    • Setup an IBM MQ server following this tutorial which provides the default developer configuration.

    • Pulled in the the python sample code from this tutorial and put a message to DEV.QUEUE.1 without TLS configured.

    General Config

    • Created some working directories on my Mac client.
      mkdir tlsTest
      cd tlsTest
      mkdir client
      mkdir server
      

    Queue Manager config

    • Create the server keystore.

      cd server
      
      runmqakm -keydb -create -db key.kdb -pw <password> -stash
      
      ls
      

      Check to see key.crl key.kdb key.rdb key.sth.

    • Check that the store is empty.

      runmqakm -cert -list -db key.kdb -stashed
      
      No certificates were found.
      
    • Create the server certificate and put it in the new keystore key.kdb

      runmqakm -cert -create -db key.kdb -stashed -dn "cn=qm,o=ibm,c=uk" -label ibmwebspheremq<QMName_lowerCase> -type cms
      
    • Check the certificate.

      runmqakm -cert -list -db key.kdb -stashed
      
      Certificates found
      * default, - personal, ! trusted, # secret key
      -    ibmwebspheremqqm1
      

      The '-' denotes the client's private key and personal certificate in this keystore.

    • Extract the queue manager's public key.

      runmqakm -cert -extract -label ibmwebspheremq<QMName_lowerCase> -db key.kdb -stashed -file QM.cert
      
    • Check to see the certificate file.

      ls
      
      QM.cert key.crl key.kdb key.rdb key.sth
      
    • Inspect the certificate.

      runmqakm -cert -details -file QM.cert -stashed
      

    Client Config

    • Change to the client directory.
      cd ../client
      
    • Create the client keystore.
      runmqakm -keydb -create -db client.kdb -pw <password> -stash
      
    • Create the client certificate and put it in the new keystore client.kdb.
      runmqakm -cert -create -db client.kdb -stashed -dn "cn=pymqi,o=test,c=uk" -label ibmwebspheremq<userName_lowercase> -type cms
      
    • Extract the client's public key.
      runmqakm -cert -extract -label ibmwebspheremq<userName_lowercase> -db client.kdb -stashed -file Client.cert
      
    • Optionally inspect the certificate by modifying previous runmqakm -cert -list commands from the earlier server steps.

    Exchange public keys

    • Populate the client's keystore with the queue manager's public key.

      runmqakm -cert -add -label ibmwebspheremq<QMName_lowerCase> -db client.kdb -stashed -file ../server/QM.cert
      
    • Check the certificate.

      runmqakm -cert -list -db client.kdb -stashed
      
      Certificates found
      * default, - personal, ! trusted, # secret key
      !    ibmwebspheremqqm1
      -    ibmwebspheremqapp
      

      The '!' shows that the queue manager's public key is trusted.

    • Populate the queue manager's keystore with the client's public key.

      Change to the server directory.

      cd ../server
      
      runmqakm -cert -add -label ibmwebspheremq<userName_lowercase> -db key.kdb -stashed -file ../client/Client.cert
      
    • Check the certificates.

      runmqakm -cert -list -db key.kdb -stashed
      
      Certificates found
      * default, - personal, ! trusted, # secret key
      !    ibmwebspheremqapp
      -    ibmwebspheremqqm1
      

    Configure TLS on the Queue Manager

    • Move the key.kdb and key.sth files from the tlsTest/server directory to /var/mqm/qmgrs/ssl/QM1 directory on the queue manager's file system.

    • Modify the DEV.APP.SVRCONN channel to accept TLS 1.2 cipher suites.

      runmqsc QM1
      
      ALTER CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12)
      
    • Refresh the queue manager's security subsystem.

      REFRESH SECURITY(*) TYPE(SSL)
      

    TLS enabled the MQ PyMQI application

    • Add cipher spec and label into the Python app and include the sco options.

      cd.SSLCipherSpec = b'ANY_TLS12'
      sco = pymqi.SCO()
      #include file name but not file extension
      sco.KeyRepository = b'tlsTest/client/client'
      sco.CertificateLabel =b'ibmwebspheremqapp'
      
    • Change the qmgr.connect line to add sco options.

      qmgr.connect_with_options(queue_manager, user=b'app', password=b'<your_password>', cd=cd, sco=sco)
      
    • Test Python app.

    Alternate configuration to use environment variables to reference label and keystore

    • Change the python app to remove label and keystore.

      #sco = pymqi.SCO()
      #sco.KeyRepository = b'tlsTest/client/client'
      #sco.CertificateLabel =b'ibmwebspheremqapp'
      #qmgr.connect_with_options(queue_manager, user=b'app', password=b'<your_password>', cd=cd, sco=sco)
      qmgr.connect_with_options(queue_manager, user=b'app', password=b'<your_password>', cd=cd)
      
    • Set environment variables.

      export MQSSLKEYR=tlsTest/client/client
      export MQCERTLABL=ibmwebspheremqapp
      
    • Test Python app.