[Podman]

Self-deploying queue managers on Podman

This example runs a prebuilt IBM® MQ Advanced Container image, to deploy a queue manager into Podman. The same example can also be used with Docker.

Before you begin

To validate the TLS configuration at the end of this example:
  • Install the IBM MQ client. You need the amqsputc and amqsgetc commands to test putting and getting messages. These commands can be installed as part of the IBM MQ client.
  • Note there is no prebuilt ARM64 IBM MQ Advanced Container image.

This example uses Podman, but can be used with Docker instead.

About this task

This example runs a prebuilt IBM MQ Advanced Container image, to deploy a queue manager into Podman. It details the additional steps required to configure TLS for messaging, as well as configuring the IBM MQ Console and the REST API. You can choose which of these to configure, by skipping steps that are not required to meet your needs.

When the queue manager is running, this example uses the IBM MQ sample programs running on a machine outside Podman, such as your laptop, to validate using mutual TLS between the sample client and the queue manager to put and get messages. It also validates logging into the IBM MQ Console, and making administrative and messaging REST API calls.

Note: You can instead run a prebuilt IBM MQ Advanced for Developers container image, which has some additional default developer configuration. See IBM MQ Advanced for Developers container image.

Procedure

  • Configure TLS for messaging between a client and the queue manager
    1. Create certificates as described in Creating a self-signed PKI using OpenSSL, following all steps but skipping the kubectl command.
      1. Create a directory, for example called qm-pki containing the key and certificate files generated for the queue manager:
        1. example-qm.key
        2. example-qm.crt
        3. ca.crt
        The user running the container (uid 1001) needs read access to example-qm.key. By default, OpenSSL creates it such that the user that creates the key has access to it.
      2. Create a directory, for example called mq-client, containing files generated for the client:
        1. example-app1.p12
        2. On Mac, you also need example-app1-chain.crt
    2. Create a file containing the MQSC commands, for example example-tls.mqsc, to create a new queue and a SVRCONN channel, and to add a channel authentication record that allows access to the channel.
      DEFINE CHANNEL('MTLS.SVRCONN') CHLTYPE(SVRCONN) SSLCAUTH(REQUIRED) SSLCIPH('ANY_TLS13_OR_HIGHER') REPLACE
      SET CHLAUTH('MTLS.SVRCONN') TYPE(SSLPEERMAP) SSLPEER('CN=*') USERSRC(NOACCESS) ACTION(REPLACE)
      SET CHLAUTH('MTLS.SVRCONN') TYPE(SSLPEERMAP) SSLPEER('CN=example-app1') USERSRC(MAP) MCAUSER('app1') ACTION(REPLACE)
      SET AUTHREC PRINCIPAL('app1') OBJTYPE(QMGR) AUTHADD(CONNECT,INQ)
      DEFINE QLOCAL('EXAMPLE.QUEUE') REPLACE 
      SET AUTHREC PROFILE('EXAMPLE.QUEUE') PRINCIPAL('app1') OBJTYPE(QUEUE) AUTHADD(BROWSE,PUT,GET,INQ)
      The MQSC command defines a channel called MTLS.SVRCONN and a queue called EXAMPLE.QUEUE. The channel is configured to allow access only to clients that present a certificate with a "common name" of example-app1. This is the common name used in one of the certificates created in the previous step. Connections on this channel with this common name are mapped to a user ID of app1, which is authorized to connect to the queue manager and to access the example queue.
    3. Create an INI file, for example example-tls.ini, that enables a security policy such that the app1 user ID does not need to exist in an external user registry - it exists only as a name in this configuration.
      Service:
          Name=AuthorizationService
          EntryPoints=14
          SecurityPolicy=UserExternal
  • Configure the IBM MQ Console and REST API

    In this example, you configure a basic registry within the mqwebuser.xml file. The user names, passwords, and roles in the XML file are used to authenticate and authorize users of the IBM MQ Console and REST API. For more information, see Configuring a basic registry for the IBM MQ Console and REST API.

    You should consider whether using a basic registry is appropriate for your production environments. See IBM MQ Console and REST API security.

    1. Create a file called mqwebuser.xml, to configure the IBM MQ Console.

      In this example a basic registry is created, containing users with the roles web admin and web user.

      You must replace ADMIN_PASSWORD and APP_PASSWORD with your own values. You can change the admin and app usernames too if you wish, though note the app username should match the app username specified in the previous MQSC command. Note that the user names are each used twice in the example.

      <?xml version="1.0" encoding="UTF-8"?>
      <server>
          <featureManager>
          <feature>appSecurity-2.0</feature>
          <feature>basicAuthenticationMQ-1.0</feature>
          </featureManager>
          <enterpriseApplication id="com.ibm.mq.console">
              <application-bnd>
                  <security-role name="MQWebAdmin">
                      <group name="MQWebAdminGroup" realm="defaultRealm"/>
                  </security-role>
              </application-bnd>
          </enterpriseApplication>
          <enterpriseApplication id="com.ibm.mq.rest">
              <application-bnd>
                  <security-role name="MQWebAdmin">
                      <group name="MQWebAdminGroup" realm="defaultRealm"/>
                  </security-role>
                  <security-role name="MQWebUser">
                      <group name="MQWebMessaging" realm="defaultRealm"/>
                  </security-role>
              </application-bnd>
          </enterpriseApplication>
          <basicRegistry id="basic" realm="defaultRealm">
              <user name="admin" password="ADMIN_PASSWORD"/>
              <user name="app1" password="APP_PASSWORD"/>
              <group name="MQWebAdminGroup">
                  <member name="admin"/>
              </group>
              <group name="MQWebMessaging">
                  <member name="app1"/>
              </group>
          </basicRegistry>           
          <sslDefault sslRef="mqDefaultSSLConfig"/>
      </server>
    2. Log into the container registry.

      Get an entitlement key, then use it to log into the container registry. See Preparing to use Podman or Docker by pulling the prebuilt container image.

    3. Run the queue manager in Podman.

      Complete one of the following options:

      • Option 1: Run the queue manager in Podman by mounting the directory containing the queue manager certificates.

        The following command includes the configuration for TLS messaging as well as configuring the IBM MQ Console and REST API. If you skipped any of the previously described configuration, because it wasn’t required for your needs, remove the parameters relevant to the sections you skipped.

        Ensure the command points to the correct location for the files and directory created earlier.

        To run the queue manager in Podman, run the following command:
        podman run --env MQ_ENABLE_EMBEDDED_WEB_SERVER=true  \
        -v "./mqwebuser.xml:/etc/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml" \
        -v "./example-tls.ini:/etc/mqm/example-tls.ini"  \
        -v "./example-tls.mqsc:/etc/mqm/example-tls.mqsc"  \
        -v "./qm-pki:/etc/mqm/pki/keys/qmlabel" --env LICENSE=accept --env MQ_QMGR_NAME=QM1 \
        --publish 1414:1414 --publish 9443:9443 --detach --name QM1 cp.icr.io/cp/ibm-mqadvanced-server:9.4.1.0-r1

        The command pulls the IBM MQ Advanced queue manager image, and starts the container.

      • Option 2: Run the queue manager in Podman using Podman secrets
        You can mount the queue manager certificates using Podman secrets, rather than directly mounting the directories containing them into the container.
        Note: This option does not apply when using Docker, unless you are using Docker Swarm, because Docker secrets can only be used with Docker Swarm. See the docker secret create command in dockerdocs.
        Complete the following steps:
        1. Create Podman secrets for each of the queue manager TLS files. For example, from within the create qm-pki directory:
          podman secret create example-qm.key ./example-qm.key
          podman secret create example-qm.crt ./example-qm.crt
          podman secret create ca.crt ./ca.crt

          The following command includes the configuration for TLS messaging as well as configuring the IBM MQ Console and REST API. If you skipped any of the previously described configuration, because it wasn’t required for your needs, remove the parameters relevant to the sections you skipped.

          Ensure the command points to the correct location for the files and directory created earlier.

          To run the queue manager in Podman, run the following command:
          podman run --env MQ_ENABLE_EMBEDDED_WEB_SERVER=true \
          -v "./mqwebuser.xml:/etc/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml" \
          -v "./example-tls.ini:/etc/mqm/example-tls.ini" \
          -v "./example-tls.mqsc:/etc/mqm/example-tls.mqsc" \
          --secret example-qm.key,target=/etc/mqm/pki/keys/qmlabel/example-qm.key,uid=1001,mode=0440 \
          --secret example-qm.crt,target=/etc/mqm/pki/keys/qmlabel/example-qm.crt,uid=1001 \
          --secret ca.crt,target=/etc/mqm/pki/keys/qmlabel/ca.crt,uid=1001 --env LICENSE=accept --env MQ_QMGR_NAME=QM1 \
          --publish 1414:1414 --publish 9443:9443 --detach --name QM1 cp.icr.io/cp/ibm-mqadvanced-server:9.4.1.0-r1
          Note: If the user that the container is running as is overridden to a different user, change the UID to match.
      A queue manager is running in Podman.
      podman ps

Validation

  • Validate messaging with TLS
    1. Create a client INI file, called mqclient.ini, in the client directory created above, for example mq-client. Specify the PASSWORD used for the p12 keystore in step 1 of Configuring TLS for messaging between a client and the queue manager:
      Channels:
        ChannelDefinitionDirectory=.
        ChannelDefinitionFile=CCDT.json
      SSL:
        OutboundSNI=HOSTNAME
        SSLKeyRepository=example-app1.p12
        SSLKeyRepositoryPassword=PASSWORD
    2. In the same directory, create a CCDT file with a name matching the reference in the previously-defined mqclient.ini file, for example CCDT.json:
      {
          "channel":
          [
              {
                  "name": "MTLS.SVRCONN",
                  "clientConnection":
                  {
                      "connection":
                      [
                          {
                              "host": "localhost",
                              "port": 1414
                          }
                      ],
                      "queueManager": "QM1"
                  },
                  "transmissionSecurity":
                  {
                    "cipherSpecification": "ANY_TLS13",
                    "certificateLabel": "example-app1"
                  },
                  "type": "clientConnection"
              }
         ]
      }
    3. On Mac, run the following command:
      export MQSSLTRUSTSTORE=example-app1-chain.crt
    4. From within the same directory, for example mq-client, use the sample application to put a message:
      amqsputc EXAMPLE.QUEUE QM1 
    5. Use the sample application to get a message:
      amqsgetc EXAMPLE.QUEUE QM1 
  • Validate the IBM MQ Console
    Connect to the console in a browser:
    1. Open: https://localhost:9443/ibmmq/console
    2. Accept the self-signed certificate.
    3. Log in:
      • User: admin
      • Password: The value you previously specified for ADMIN_PASSWORD.
  • Validate the REST API

    In the following examples, specify the values you previously configured for ADMIN_PASSWORD and APP_PASSWORD.

    An example of calling the administrative REST API to get queue manager status:
    curl -k -X GET -u admin:ADMIN_PASSWORD https://localhost:9443/ibmmq/rest/v1/admin/qmgr/QM1

    An example of calling the messaging REST API to put and then get a message from a queue.

    Put a message:
    curl -k -X POST -u app1:APP_PASSWORD \
    -H 'Content-Type: application/json' -H "ibm-mq-rest-csrf-token: value" \
    -d 'msg from REST' https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/EXAMPLE.QUEUE/message
    Browse a message:
    curl -k -X GET -u app1:APP_PASSWORD \
    -H "ibm-mq-rest-csrf-token: value" https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/EXAMPLE.QUEUE/message
    Note: The REST API GET operation is actually an IBM MQ browse operation - the message is left on the queue. To do an IBM MQ GET, use the REST API DELETE verb.

Troubleshooting

  • If the amqputc or amqgetc sample applications fail, view error logs at ~/IBM/MQ/data/errors/AMQERR01.LOG on the client machine, for example your laptop.
  • View queue manager error logs in their usual places, by exec’ing onto the container in Podman.
    For example:
    podman exec -it QM1 /bin/bash