Skip to main content
czerasz.com: notes
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

IBM MQ

IBM products version number format: version.release.modification.fixpack

By default IBM MQ configuration is stored under /var/mqm/mqs.ini.

Error logs (by default stored in /var/mqm/errors/):

$ ls -1 /var/mqm/errors/*.LOG
/var/mqm/errors/AMQERR01.LOG
/var/mqm/errors/AMQERR02.LOG
/var/mqm/errors/AMQERR03.LOG
$ ls -1 /var/mqm/log/QM1/active/*.LOG
/var/mqm/log/QM1/active/S0000000.LOG
/var/mqm/log/QM1/active/S0000001.LOG
/var/mqm/log/QM1/active/S0000002.LOG

Queue Manager error logs:

$ ls -1 /var/mqm/qmgrs/QM1/errors/AMQERR*.LOG
/var/mqm/qmgrs/QM1/errors/AMQERR01.LOG
/var/mqm/qmgrs/QM1/errors/AMQERR02.LOG
/var/mqm/qmgrs/QM1/errors/AMQERR03.LOG

Those logs are also available in JSON format:

$ ls -1 /var/mqm/qmgrs/QM1/errors/AMQERR*.json
/var/mqm/qmgrs/QM1/errors/AMQERR01.json
/var/mqm/qmgrs/QM1/errors/AMQERR02.json
/var/mqm/qmgrs/QM1/errors/AMQERR03.json

Getting Started

  1. check Requirements
  2. install IBM MQ
  3. create and start Queue Manager
  4. create channel
  5. create listener for channel and start it

Installing IBM MQ

Follow this guide to learn more.

To update IBM MQ follow this guide.

  • view current installation details

    $ dspmqinst
    InstName:      Installation1
    InstDesc:      IBM MQ V9.4.1.0 (Unzipped)
    Identifier:    126
    InstPath:      /opt/mqm
    Version:       9.4.1.0
    Primary:       N/A
    State:         Available
    LicenseType:   Developer
    Entitlement:   IBM MQ Advanced for Developers (Non-Warranted)
    Fixes:
    
  • get IBM MQ version

    $ dspmqver
    Name:        IBM MQ
    Version:     9.4.1.0
    Level:       p941-L241002
    BuildType:   IKAP - (Production)
    Platform:    IBM MQ for Linux (x86-64 platform)
    Mode:        64-bit
    O/S:         Linux 6.8.0-51-generic
    O/S Details: Red Hat Enterprise Linux 9.5 (Plow)
    InstName:    Installation1
    InstDesc:    IBM MQ V9.4.1.0 (Unzipped)
    Primary:     N/A
    InstPath:    /opt/mqm
    DataPath:    /mnt/mqm/data
    MaxCmdLevel: 941
    LicenseType: Developer
    ReleaseType: Continuous Delivery (CD)
    

Queue Manager

  • create Queue Manager

    crtmqm QM1
    
  • start Queue Manager

    strmqm QM1
    
  • display queue managers and their statuses

    $ dspmq -o all
    QMNAME(QM1)                                               STATUS(Running) DEFAULT(yes) STANDBY(Permitted) INSTNAME(Installation1) INSTPATH(/opt/mqm) INSTVER(9.4.1.0) ROLE(Not configured) INSTANCE() INSYNC() QUORUM()
    

    alternativery

    $ echo "display qmstatus" | runmqsc QM1
    5724-H72 (C) Copyright IBM Corp. 1994, 2024.
    Starting MQSC for queue manager QM1.
    
    
        1 : display qmstatus
    AMQ8705I: Display Queue Manager Status Details.
      QMNAME(QM1)                             TYPE(QMGR)
      STATUS(RUNNING)
    One MQSC command read.
    No commands have a syntax error.
    All valid MQSC commands were processed.
    

    or with more details

    echo "display qmstatus all" | runmqsc QM1
    
  • stop Queue Manager

    endmqm QM1
    
  • View Queue Manager properties

    echo 'DIS QMGR' | runmqsc QM1
    

Channels

Each connection will be associated with a channel.

  • list all connections

    $ echo "display conn(*) all" | runmqsc QM1 | grep -E '^\s*CONN\(' -A14
      CONN(13F2976700090040)
      EXTCONN(414D5143514D31202020202020202020)
      TYPE(CONN)
      PID(1473)                               TID(1)
      APPLDESC(IBM MQ Channel Initiator)      APPLTAG(runmqchi)
      APPLTYPE(CHINIT)                        ASTATE(STARTED)
      CHANNEL( )                              CLIENTID( )
      CONNAME( )
      CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_SHARED_BINDING)
      USERID(mqm)                             UOWLOG( )
      UOWSTDA( )                              UOWSTTI( )
      UOWLOGDA( )                             UOWLOGTI( )
      URTYPE(QMGR)
      EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
      QMURID(0.0)                             UOWSTATE(NONE)
    --
    ...
    

    connections established by applications

    echo "display conn(*) where (APPLTYPE eq USER) all" | runmqsc QM1 | grep -E '^\s*CONN\(' -A14
    

    connections used by remote queues

    echo "display conn(*) where (APPLDESC eq 'IBM MQ Channel') all" | runmqsc QM1 | grep -E '^\s*CONN\(' -A14
    
  • list all channels

    $ echo "display channel(*)" | runmqsc QM1 | grep -E '^\s*CHANNEL\('
      CHANNEL(DEV.ADMIN.SVRCONN)              CHLTYPE(SVRCONN)
      CHANNEL(DEV.APP.SVRCONN)                CHLTYPE(SVRCONN)
      CHANNEL(QM1.TO.QM2)                     CHLTYPE(SDR)
      CHANNEL(SYSTEM.AUTO.RECEIVER)           CHLTYPE(RCVR)
      CHANNEL(SYSTEM.AUTO.SVRCONN)            CHLTYPE(SVRCONN)
      CHANNEL(SYSTEM.DEF.AMQP)                CHLTYPE(AMQP)
      ...
    
  • list specific channels

    $ echo "display channel(SYSTEM*,RECEIVER)" | runmqsc QM1 | grep -E '^\s*CHANNEL\('
      CHANNEL(SYSTEM.AUTO.RECEIVER)           CHLTYPE(RCVR)
      CHANNEL(SYSTEM.AUTO.SVRCONN)            CHLTYPE(SVRCONN)
      CHANNEL(SYSTEM.DEF.AMQP)                CHLTYPE(AMQP)
      CHANNEL(SYSTEM.DEF.CLUSRCVR)            CHLTYPE(CLUSRCVR)
      CHANNEL(SYSTEM.DEF.CLUSSDR)             CHLTYPE(CLUSSDR)
      CHANNEL(SYSTEM.DEF.RECEIVER)            CHLTYPE(RCVR)
      CHANNEL(SYSTEM.DEF.REQUESTER)           CHLTYPE(RQSTR)
      CHANNEL(SYSTEM.DEF.SENDER)              CHLTYPE(SDR)
      CHANNEL(SYSTEM.DEF.SERVER)              CHLTYPE(SVR)
      CHANNEL(SYSTEM.DEF.SVRCONN)             CHLTYPE(SVRCONN)
      CHANNEL(SYSTEM.DEF.CLNTCONN)            CHLTYPE(CLNTCONN)
    
  • get channel details

    $ echo "display channel(QM1.TO.QM2)" | runmqsc QM1
    5724-H72 (C) Copyright IBM Corp. 1994, 2024.
    Starting MQSC for queue manager QM1.
    
    
        1 : display channel(QM1.TO.QM2)
    AMQ8414I: Display Channel details.
      CHANNEL(QM1.TO.QM2)                     CHLTYPE(SDR)
      ALTDATE(2025-01-27)                     ALTTIME(23.52.24)
      BATCHHB(0)                              BATCHINT(0)
      BATCHLIM(5000)                          BATCHSZ(50)
      CERTLABL( )                             COMPHDR(NONE)
      COMPMSG(NONE)                           CONNAME(mq-2(1414))
      CONVERT(NO)                             DESCR(Sender channel to remote QM2)
      DISCINT(6000)                           HBINT(300)
      KAINT(AUTO)                             LOCLADDR( )
      LONGRTY(999999999)                      LONGTMR(1200)
      MAXMSGL(4194304)                        MCANAME( )
      MCATYPE(PROCESS)                        MCAUSER( )
      MODENAME( )                             MONCHL(QMGR)
      MSGDATA( )                              MSGEXIT( )
      NPMSPEED(FAST)                          PASSWORD( )
      PROPCTL(COMPAT)                         RCVDATA( )
      RCVEXIT( )                              RESETSEQ(NO)
      SCYDATA( )                              SCYEXIT( )
      SENDDATA( )                             SENDEXIT( )
      SEQWRAP(999999999)                      SHORTRTY(10)
      SHORTTMR(60)                            SSLCIPH( )
      SSLPEER( )                              STATCHL(QMGR)
      TPNAME( )                               TRPTYPE(TCP)
      USEDLQ(YES)                             USERID( )
      XMITQ(TO.QM2)
    One MQSC command read.
    No commands have a syntax error.
    All valid MQSC commands were processed.
    
  • create channel

    echo "define channel('TEST.01') chltype(SVRCONN)" | runmqsc QM1
    5724-H72 (C) Copyright IBM Corp. 1994, 2024.
    Starting MQSC for queue manager QM1.
    
    
        1 : define channel('TEST.01') chltype(SVRCONN)
    AMQ8014I: IBM MQ channel created.
    One MQSC command read.
    No commands have a syntax error.
    All valid MQSC commands were processed.
    

Listeners

  • define listener

    echo "define listener(LISTENER01) trptype(TCP) control(QMGR) port(1414)" | runmqsc QM1
    
  • start listener

    echo "start listener(LISTENER01)" | runmqsc QM1
    
  • show listener status

    $ echo "display lsstatus(*) all" | runmqsc QM1
    5724-H72 (C) Copyright IBM Corp. 1994, 2024.
    Starting MQSC for queue manager QM1.
    
    
        1 : display lsstatus(*) all
    AMQ8631I: Display listener status details.
      LISTENER(SYSTEM.LISTENER.TCP.1)         STATUS(RUNNING)
      PID(1614)                               STARTDA(2025-01-27)
      STARTTI(20.52.34)                       DESCR( )
      TRPTYPE(TCP)                            CONTROL(QMGR)
      IPADDR(*)                               PORT(1414)
      BACKLOG(100)
    One MQSC command read.
    No commands have a syntax error.
    All valid MQSC commands were processed.
    

Basic Commands

  • execute commands from commands.out file

    runmqsc -f commands.out QM1
    
  • send message to queue on specific queue manager

    amqsput SENDERQ SENDERQM
    
  • read messages from RECEIVERQ queue on specific queue manager (RECEIVERQM)

    amqsget RECEIVERQ RECEIVERQM
    

    This is a destructive operation. The message will be removed from the queue.

Point to Point

Message channels are used to communicate between queue managers. Message Queue Interface (MQI) channels - client connection channels.

Create Remote Queue - Connect two Queue Managers

Requirements:

  • SENDERQM - sender queue manager

  • RECEIVERQM - receiver queue manager

  • create receiver queue

    echo 'define qlocal(RECEIVER.QUEUE)' | runmqsc RECEIVERQM
    
  • create receiver channel

    echo 'define channel(SENDER.TO.RECEIVER) chltype(rcvr) trptype(tcp)' | runmqsc RECEIVERQM
    

    NOTE Channels names are limited to 20 characters.

  • create transmission queue

    echo 'define qlocal(SENDER.TQ) usage(xmitq)' | runmqsc SENDERQM
    
  • create remote queue on sender queue manager

    echo 'define qremote(SENDER.QUEUE) rname(RECEIVER.QUEUE) rqmname(RECEIVERQM) xmitq(SENDER.TQ)' | runmqsc SENDERQM
    
  • create sender channel

    cat <<EOS | runmqsc SENDERQM
    define channel(SENDER.TO.RECEIVER) chltype(sdr) conname('mq-2(1414)') xmitq(SENDER.TQ) trptype(tcp)
    EOS
    
  • allow communication from SENDERQM to RECEIVERQM on SENDER.TO.RECEIVER channel

    cat <<EOS | runmqsc RECEIVERQM
    SET CHLAUTH('SENDER.TO.RECEIVER') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) WARN(NO) ACTION(ADD)
    SET CHLAUTH('SENDER.TO.RECEIVER') TYPE(ADDRESSMAP) ADDRESS('172.23.0.3') USERSRC(MAP) MCAUSER('mqm') ACTION(ADD)
    EOS
    

    The directives above

    • block access to SENDER.TO.RECEIVER channel from all IPs
    • allow access from IP 172.23.0.3 and map queries to user mqm
  • start channel on sender queue manager

    echo 'start channel(SENDER.TO.RECEIVER)' | runmqsc SENDERQM
    

Channel Authentication

  • check if Channel Authentication is enabled

    echo 'DIS QMGR' | runmqsc QM1 | grep -oP 'CHLAUTH[^\)]+\)'
    
  • enable Channel Authentication (by default)

    echo 'ALTER QMGR CHLAUTH(ENABLED)' | runmqsc QM1
    
  • disable Channel Authentication (for local development)

    echo 'ALTER QMGR CHLAUTH(DISABLED)' | runmqsc QM1
    

    Can be also set it to WARN, which would allow access, but still log the result of the rule.

  • disable rule

    SET CHLAUTH(*) TYPE(BLOCKUSER) USERLIST(*MQADMIN) WARN(YES) ACTION(REPLACE)
    
  • remove default channel authentication records:

    cat <<EOS | runmqsc QM1
    SET CHLAUTH(SYSTEM.ADMIN.SVRCONN) TYPE(ADDRESSMAP) ADDRESS(*) ACTION(REMOVE)
    SET CHLAUTH(SYSTEM.*) TYPE(ADDRESSMAP) ADDRESS(*) ACTION (REMOVE)
    SET CHLAUTH(*) TYPE(BLOCKUSER) USERLIST(*MQADMIN) ACTION (REMOVE)
    REFRESH SECURITY
    EOS
    
  • block all connections

    cat <<EOS | runmqsc QM1
    SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('block everything')
    REFRESH SECURITY
    EOS
    
  • allow connections to specific channel (SOME_NAME) from specific IP

    cat <<EOS | runmqsc QM1
    SET CHLAUTH(SOME_NAME) TYPE(ADDRESSMAP) ADDRESS(100.64.0.1) USERSRC(CHANNEL) ACTION(ADD)
    REFRESH SECURITY
    EOS
    
  • map IP 172.23.0.3 to user mqm

    SET CHLAUTH('QM1.TO.QM2') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) WARN(NO) ACTION(ADD)
    SET CHLAUTH('QM1.TO.QM2') TYPE(ADDRESSMAP) ADDRESS('172.23.0.3') USERSRC(MAP) MCAUSER('mqm') ACTION(ADD)
    
  • view/dump all permissions/MQ authorizations

    $ dmpmqaut -m QM1
    ...
    - - - - - - - -
    profile:     QM1.TO.QM2
    object type: channel
    entity:      mqm
    entity type: principal
    authority:   allmqi dlt chg dsp ctrl ctrlx
    - - - - - - - -
    ...
    

    or for specific queue

    dmpmqaut -m QM1 -t queue
    

echo ‘display CHLAUTH(*) all’ | runmqsc QM1

echo ‘display CHLAUTH(*) CHLAUTH TYPE SSLPEER CLNTUSER QMNAME ADDRESS USERSRC MCAUSER USERLIST ADDRLIST WARN CHCKCLNT SSLCERTI DESCR CUSTOM ALTDATE ALTTIME’ | runmqsc QM1

| Channel profile | Type | Peer name | Client user ID | Remote queue manager | Address | User source | MCA user ID | User list | Address list | Warning | Client connections | Peer issuer name | Description | Custom | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | | * | Block User List | | | | | | *MQADMIN | | | | | Default rule to disallow privileged users | | | CFQM.NONSSL.SVRCONN | Map User | | mqm | | * | Map | mqm |

TLS Encryption

MCA - Message Channel Agent

(…)IBM MQ queue managers perform two functions when authenticating a TLS-based connection. The TLS component verifies that the presented certificate is valid; that is, the certificate was signed by a trusted authority, reached its validity date, and has not expire. The channel or a CHLAUTH rule checks the Distinguished Name (DN) of the certificate against expected values, which are found in SSLPEER attributes.(…)

(…)The TLS client end of the TLS connection can be required to present a certificate by defining channels with the SSLCAUTH(REQUIRED) attribute or an SSLPEER parameter value set.(…)

Without TLS, CHLAUTH rules can filter only on the IP address or the queue manager name. Those cannot be considered effective authentication mechanisms (IP can be spoofed, queue manager name can be adopted).

Enable Secure Communication

Requirements:

  • MQSeriesGSKit package must be installed

    Install it with

    $ rpm -ivh MQSeriesGSKit-9.1.0-0.x86_64.rpm
    # make sure the package is successfully installed
    $ rpm -qa | grep -i mq
    ...
    MQSeriesGSKit-9.1.0-0.x86_64
    ...
    # reset MQ installation - not sure this is necessary
    $ setmqinst -x -p /opt/mqm
    $ setmqinst -i -p /opt/mqm
    

Process:

  • on QM1:

    • switch to queue managers ssl directory

      cd /var/mqm/qmgrs/QM1/ssl
      
    • create keystore in cms format

      runmqakm -keydb -create -db key.kdb -pw qm1_password -type cms -stash
      
      $ ls -1
      key.kdb # keystore file
      key.rdb # relational database
      key.sth # stash file - stores password in hexadecimal encoded format
      key.crl # control file - controlls the relation between keystore and stash file
      
    • creating self-signed certificate

      runmqakm -cert -create -label qm1 -db key.kdb -stashed -dn 'CN=QM1,OU=IBM' -expire 365 -size 1024 -format ascii
      

      -dn stands for Distinguished Name (DN), which is a term that describes the identifying information in a certificate and is part of the certificate itself.

      CN - common name OU - organization unit

    • list the certificates in keystore

      runmqakm -cert -list -db key.kdb -stashed
      
    • extract the public certificate

      runmqakm -cert -extract -db key.kdb -stashed -label qm1 -target qm1.pub.arm
      
  • on QM2

    • add the public key from QM1

      runmqakm -cert -add -db key.kdb -stashed -label qm1 -file /tmp/qm1.pub.arm
      
    • repeat commands needed for certificate generation

      cd /var/mqm/qmgrs/QM2/ssl
      runmqakm -keydb -create -db key.kdb -pw qm2_password -type cms -stash
      runmqakm -cert -create -db key.kdb -stashed -label qm2 -dn 'CN=QM2,OU=IBM' -expire 365 -size 1024 -format ascii
      runmqakm -cert -extract -db key.kdb -stashed -label qm2 -target qm2.pub.arm
      
  • on QM1 add the public key from QM2

    runmqakm -cert -add -db key.kdb -stashed -label qm2 -file /tmp/qm2.pub.arm
    
  • enable TLS on QM1

    cat <<EOS | runmqsc QM1
    alter qmgr sslkeyr('/var/mqm/qmgrs/QM1/ssl/key')
    alter channel(SENDER.TO.RECEIVER) chltype(sdr) sslciph(ANY_TLS13_OR_HIGHER)
    REFRESH SECURITY TYPE(SSL)
    EOS
    
  • enable TLS on QM2

    cat <<EOS | runmqsc QM2
    alter qmgr sslkeyr('/var/mqm/qmgrs/QM2/ssl/key')
    alter channel(SENDER.TO.RECEIVER) chltype(rcvr) sslciph(ANY_TLS13_OR_HIGHER)
    REFRESH SECURITY TYPE(SSL)
    EOS
    

Find example script here

Useful TLS Commands

  • remove certificate

    runmqakm -cert -delete \
      -db key.kdb -stashed \
      -label 'CN=mq.czerasz.local,OU=IT,O=czerasz.local Local GmbH,L=Berlin,ST=Berlin-Brandenburg,C=DE'
    

Example - TLS with self-signed certificate

  • add CA certificate on sender and receiver

    runmqakm -cert -add \
      -db key.kdb -stashed \
      -file /var/mqm/qmgrs/QM2/ssl/czerasz.local-ca.pem
    

    then

    $ runmqakm -cert -list -db key.kdb -stashed
    Certificates found
    * default, - personal, ! trusted, # secret key
    !	"CN=czerasz.local,OU=IT,O=czerasz.local Local GmbH,L=Berlin,ST=Berlin-Brandenburg,C=DE"
    

    or

    runmqakm -cert -add \
      -db key.kdb -stashed \
      -label czerasz.local \
      -file /var/mqm/qmgrs/QM2/ssl/czerasz.local-ca.pem
    

    then

    $ runmqakm -cert -list -db key.kdb -stashed
    Certificates found
    * default, - personal, ! trusted, # secret key
    !	czerasz.local
    
  • set key repository location for sender and receiver queue managers

    echo "ALTER QMGR SSLKEYR('/var/mqm/qmgrs/QM1/ssl/key')" | runmqsc QM1
    echo "ALTER QMGR SSLKEYR('/var/mqm/qmgrs/QM2/ssl/key')" | runmqsc QM2
    
  • export certificates in pkcs12 format

    cat mq-2.czerasz.local.crt czerasz.local-ca.pem > mq-2.czerasz.local-full.crt
    openssl pkcs12 -export \
      -in mq-2.czerasz.local.crt \
      -out mq-2.czerasz.local.pfx \
      -inkey mq-2.czerasz.local.key \
      -passout pass:secure-export-password
    
  • import certificate

    runmqakm -cert -import \
      -target key.kdb -target_stashed -target_type cms \
      -type pkcs12 \
      -file /var/mqm/qmgrs/QM2/ssl/mq-2.czerasz.local.pfx \
      -pw secure-export-password
    
  • rename certificate

    $ QM_NAME=QM2
    $ QM_NAME_LOWER=$(echo "${QM_NAME}" | tr '[:upper:]' '[:lower:]')
    $ CERT_LABEL="ibmwebspheremq${QM_NAME_LOWER}"
    $ runmqakm -cert -rename \
      -db key.kdb -stashed \
      -label 'CN=mq.czerasz.local,OU=IT,O=czerasz.local Local GmbH,L=Berlin,ST=Berlin-Brandenburg,C=DE' \
      -new_label "${CERT_LABEL}"
    

    where ibmwebspheremqqm2 is the default label that MQ server uses when communicating over TLS.

    Alternatively use any label name, but then set CERTLABL attribute on Queue Manager or Channel certificate label attribute CERTLABL. Example below demonstrates the

    $ runmqakm -cert -rename \
      -db key.kdb -stashed \
      -label 'CN=mq.czerasz.local,OU=IT,O=czerasz.local Local GmbH,L=Berlin,ST=Berlin-Brandenburg,C=DE' \
      -new_label qm2
    $ echo "ALTER QMGR CERTLABL('qm2')" | runmqsc QM2
    
  • display certificate details

    runmqakm -cert -details \
      -db key.kdb -stashed \
      -type cms \
      -label ibmwebspheremqqm2
    
  • on QM1

    echo 'alter channel(SENDER.TO.RECEIVER) CHLTYPE(SDR) SSLCIPH(ANY_TLS13_OR_HIGHER)' | runmqsc QM1
    # TODO: enable mutual TLS - move to separate section
    # echo "alter channel(SENDER.TO.RECEIVER) CHLTYPE(SDR) SSLCIPH(ANY_TLS13_OR_HIGHER) SSLPEER('UNSTRUCTUREDNAME=mq-1.czerasz.local')" | runmqsc QM1
    echo "alter channel(SENDER.TO.RECEIVER) CHLTYPE(SDR) SSLCIPH(ANY_TLS13_OR_HIGHER) SSLPEER('')" | runmqsc QM1 # reset
    echo 'refresh security type(ssl)' | runmqsc QM1
    
  • on QM2

    echo 'alter channel(SENDER.TO.RECEIVER) CHLTYPE(RCVR) SSLCIPH(ANY_TLS13_OR_HIGHER) SSLCAUTH(OPTIONAL)' | runmqsc QM2
    echo 'refresh security type(ssl)' | runmqsc QM2
    

$ echo "DISPLAY CHSTATUS(CHANNEL.NAME)" | runmqsc QM2
...
     1 : DISPLAY CHSTATUS(SENDER.TO.RECEIVER)
AMQ8417I: Display Channel Status details.
   CHANNEL(SENDER.TO.RECEIVER)             CHLTYPE(RCVR)
   CONNAME(172.24.0.2)                     CURRENT
   RQMNAME(QM1)                            STATUS(RUNNING)
   SUBSTATE(RECEIVE)

Initial Setup

  • setup default dead letter queue

    DEFINE QLOCAL('DEV.DEAD.LETTER.QUEUE') REPLACE
    * Use a different dead letter queue, for undeliverable messages
    ALTER QMGR DEADQ('DEV.DEAD.LETTER.QUEUE')
    
  • create basic channels

    * Developer channels (Application + Admin)
    * Developer channels (Application + Admin)
    DEFINE CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) REPLACE
    DEFINE CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) MCAUSER('app') REPLACE
    
  • setup permissions

    * Developer channel authentication rules
    * Default blocking rule.
    *  Its purpose is to block all incoming connections at the IP address level, unless another rule specifically allows them.
    *  It's a security measure to ensure that, by default, no connections are permitted unless explicitly authorized.
    SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) +
    DESCR('Back-stop rule - Blocks everyone') ACTION(REPLACE)
    
    * ---
    SET CHLAUTH('DEV.APP.SVRCONN') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED) +
    DESCR('Allows connection via APP channel') ACTION(REPLACE)
    
    SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(BLOCKUSER) USERLIST('nobody') +
    DESCR('Allows admins on ADMIN channel') ACTION(REPLACE)
    
    SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(CHANNEL) +
    DESCR('Allows admin user to connect via ADMIN channel') ACTION(REPLACE)
    
    SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(MAP) MCAUSER ('mqm') +
    DESCR ('Allow admin as MQ-admin') ACTION(REPLACE)
    
    * Developer authority records
    SET AUTHREC PRINCIPAL('app') OBJTYPE(QMGR) AUTHADD(CONNECT,INQ)
    SET AUTHREC PROFILE('DEV.**') PRINCIPAL('app') OBJTYPE(QUEUE) AUTHADD(BROWSE,GET,INQ,PUT)
    SET AUTHREC PROFILE('DEV.APP.MODEL.QUEUE') PRINCIPAL('app') OBJTYPE(QUEUE) AUTHADD(BROWSE,DSP,GET,INQ,PUT)
    
  • configure TLS

    * Set the keystore location for the queue manager
    ALTER QMGR SSLKEYR('/var/mqm/qmgrs/QM1/ssl/')
    ALTER QMGR CERTLABL('ibmwebspheremqqm1')
    * ALTER QMGR SSLFIPS(No)
    REFRESH SECURITY(*) TYPE(SSL)
    
  • setup connection authentication

    * Developer connection authentication
    DEFINE AUTHINFO('LOCAL.DEFAULT.AUTHINFO.IDPWOS') +
      AUTHTYPE(IDPWOS) +
      CHCKCLNT(REQUIRED) +
      CHCKLOCL(REQUIRED) +
      ADOPTCTX(YES) REPLACE
    ALTER QMGR CONNAUTH('LOCAL.DEFAULT.AUTHINFO.IDPWOS')
    REFRESH SECURITY(*) TYPE(CONNAUTH)
    
  • create mqadm group

Security

  • show queue manager connection authentication (CONNAUTH) attribute

    ``bash $ echo “DISPLAY QMGR CONNAUTH” | runmqsc QM1 … 1 : DISPLAY QMGR CONNAUTH AMQ8408I: Display Queue Manager details. QMNAME(QM1) CONNAUTH(DEV.AUTHINFO)

  • show specific connection authentication configuration

    ``bash $ echo “DISPLAY AUTHINFO(‘DEV.AUTHINFO’)” | runmqsc QM1 … 1 : DISPLAY AUTHINFO(‘DEV.AUTHINFO’) AMQ8566I: Display authentication information details. AUTHINFO(DEV.AUTHINFO) AUTHTYPE(IDPWOS) ADOPTCTX(YES) DESCR( ) CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL) FAILDLAY(1) AUTHENMD(OS) ALTDATE(2025-02-09) ALTTIME(23.52.52)

    
    Set `CHCKCLNT` to `REQUIRED` so that all clients have to supply a valid user ID and password.
    
    ```bash
    $ echo "DISPLAY AUTHINFO('SYSTEM.DEFAULT.AUTHINFO.IDPWOS') all" | runmqsc QM1
    ...
        1 : DISPLAY AUTHINFO('SYSTEM.DEFAULT.AUTHINFO.IDPWOS') all
    AMQ8566I: Display authentication information details.
      AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
      AUTHTYPE(IDPWOS)                        ADOPTCTX(YES)
      DESCR( )                                CHCKCLNT(REQDADM)
      CHCKLOCL(OPTIONAL)                      FAILDLAY(1)
      AUTHENMD(OS)                            ALTDATE(2025-01-27)
      ALTTIME(20.52.35)
    
  • setup connection authentication

    cat <<EOS | runmqsc QM1
    * Developer connection authentication
    DEFINE AUTHINFO('MYAPP.DEFAULT.AUTHINFO.IDPWOS') +
      AUTHTYPE(IDPWOS) +
      CHCKCLNT(REQUIRED) +
      CHCKLOCL(OPTIONAL) +
      ADOPTCTX(YES) REPLACE
    ALTER QMGR CONNAUTH('MYAPP.DEFAULT.AUTHINFO.IDPWOS')
    REFRESH SECURITY(*) TYPE(CONNAUTH)
    EOS
    

After the client is authenticated, one needs to authorize it access specific queues. This is done using the Object Authority Manager (OAM).

SET AUTHREC OBJTYPE(QUEUE) OBJNAME('APP.QUEUE') PRINCIPAL('myuser') AUTHADD(PUT,GET,BROWSE)

The channel MCAUSER attribute is a fallback user name that the channel process will use if the client doesn’t provide credentials or if authentication fails. Use unprivileged like nobody.


echo "SET CHLAUTH('SENDER.TO.RECEIVER') TYPE(ADDRESSMAP) ADDRESS('172.24.0.2') USERSRC(MAP) MCAUSER('mqm') ACTION(ADD)" | runmqsc QM2
echo "SET CHLAUTH('SENDER.TO.RECEIVER2') TYPE(ADDRESSMAP) ADDRESS('172.24.0.2') USERSRC(MAP) MCAUSER('mqm') ACTION(ADD)" | runmqsc QM2
echo "SET CHLAUTH('QM1.TO.QM2') TYPE(ADDRESSMAP) ADDRESS('172.24.0.2') USERSRC(MAP) MCAUSER('mqm') ACTION(ADD)" | runmqsc QM2
echo 'SET CHLAUTH(QM1.TO.QM2) TYPE(ADDRESSMAP) ADDRESS(172.24.0.2) ACTION(REMOVE)' | runmqsc QM2
echo "SET CHLAUTH(QM1.TO.QM2) TYPE(ADDRESSMAP) ADDRESS(172.24.0.2) USERSRC(MAP) MCAUSER('mqm') ACTION(add)" | runmqsc QM2

echo 'display channel('QM1.TO.QM2') all' | runmqsc QM2
echo 'display CHLAUTH('QM1.TO.QM2')' | runmqsc QM2
echo 'display channel('SENDER.TO.RECEIVER') all' | runmqsc QM2

Backup/Restore

  • export messages from RECEIVER.QUEUE queue (including headers)

    dmpmqmsg -m QM2 -I RECEIVER.QUEUE -f receiver.queue.out -a
    
  • import messages to

    dmpmqmsg -m QM3 -o RECEIVER.QUEUE -f receiver.queue.out
    

IBM MQ on AWS

Read more here

Monitoring

git clone git@github.com:ibm-messaging/mq-metric-samples.git
cd mq-metric-samples
export VER=44a7c88
export MONITORS=mq_otel
export OUTDIR="${PWD}/out"
./scripts/buildMonitors.sh
$ ls -1
mq_otel
mq_otel.mqsc
mq_otel.sh
mq_otel.yaml

Resources