Search code examples
python-3.xibm-mqibm-midrangepymqi

pymqi.connect failing with error 2059 MQRC_Q_MGR_NOT_AVAILABLE on linux


We are setting up client app on linux to connect to remote mq on IBM i (old name- iSeries/AS400).

  • mq client on linux on ppc64le server
  • mq manager, channel & queue on IBM i (old name iSeries)
  • python 3.7.3

First pymqi.connect was failing with error 2393: MQRC_SSL_INITIALIZATION_ERROR.

Here is 2393 error description:

AMQ9641E: Remote CipherSpec error for channel 'SVRCHLSSL256' to host 'remote IBM I host here'
(10.239.53.242)(1414)'.

EXPLANATION:
The remote end of channel 'SVRCHLSSL256' on host 'remote IBM I host here'
(1414)' has indicated a CipherSpec error 'SSLCIPH(' ') ->
SSLCIPH(????)'. The channel did not start.
ACTION:
Check that the CipherSpec values specified on the SVRCHLSSL256 channel
definition on both the local and remote system match. If necessary, review the
queue manager error logs on the remote system to discover more information
about the CipherSpec error. When using the the 'ANY' type CipherSpecs, check
that the Client CipherSpec value would meet the requirements of the
SVRCHLSSL256 channel definition CipherSpec requirements. If the client is set
to use the 'ANY' type CipherSpecs then the TLS handshake may use a higher
protocol than is allowed by the SVRCHLSSL256 channel definition CipherSpec.

We fixed it by adding below to /var/mqm/mqclient.ini file.

SSL:
   AllowedCipherSpecs=ANY_TLS12_OR_HIGHER

But now pymqi.connect is failing with error 2059: MQRC_Q_MGR_NOT_AVAILABLE. MQ manager & channel both are up & running on IBM i. so not sure why I am getting the error? I would appreciate your help to resolve this issue.

Here is my new code snippet:

queue_manager = 'quename here' 
channel = 'channel name here' 
host ='remote host-name here'
port = '1414'
conn_info = '%s(%s)' % (host, port)
user = 'user id here'
password = 'my pwd here'
ssl_cipher_spec = 'TLS_RSA_WITH_AES_256_CBC_SHA256'
key_repo_location = '/var/mqm/qmgrs/QM1/ssl'

cd = pymqi.CD()
cd.ChannelName = channel.encode()
cd.ConnectionName = conn_info.encode()
cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
cd.TransportType = pymqi.CMQC.MQXPT_TCP
cd.SSLCipherSpec = ssl_cipher_spec.encode()

sco = pymqi.SCO()
sco.KeyRepository = key_repo_location

_MQmgr = pymqi.QueueManager(None)
_MQmgr.connect_with_options(queue_manager, cd=cd, sco=sco, user=user, password=password)

Old code

queue_manager = 'quename here' 
channel = 'channel name here' 
host ='remote host-name here'
port = '1414'
conn_info = '%s(%s)' % (host, port)
user = 'user id here'
password = 'my pwd here'
_MQmgr = pymqi.connect(queue_manager, channel, conn_info, user, password)

More details on error message:

Traceback (most recent call last):
  File "/opt/class-python/'host-name here'/app/routing/src/main.py", line 61, in <module>
    qmgr = get_MQmanager()
  File "/opt/class-python/'host-name here'/utility/classMQ.py", line 49, in get_MQmanager
    _MQmgr = pymqi.connect(queue_manager, channel, conn_info, user, password)
  File "/opt/class-python/python-venv/'host-name here'/env3.6/lib64/python3.6/site-packages/pymqi/__init__.py", line 3024, in connect
    qmgr.connect_tcp_client(queue_manager or '', CD(), channel, conn_info, user, password)
  File "/opt/class-python/python-venv/'host-name here'/env3.6/lib64/python3.6/site-packages/pymqi/__init__.py", line 1649, in connect_tcp_client
    self.connect_with_options(name, **kwargs)
  File "/opt/class-python/python-venv/'host-name here'/env3.6/lib64/python3.6/site-packages/pymqi/__init__.py", line 1624, in connect_with_options
    raise MQMIError(rv[1], rv[2])
pymqi.MQMIError: MQI Error. Comp: 2, Reason 2059: FAILED: MQRC_Q_MGR_NOT_AVAILABLE

Here's the 2059 error description:

10/27/2020 01:38:42 PM - Process(16087.1) User(classpy) Program(python)
                    Host('linux host-name here') Installation(Installation1)
                    VRMF(9.2.0.0)
                    Time(2020-10-27T18:38:42.796Z)
                    ArithInsert1(1073766407)
                    CommentInsert1(xcsGetRandomBytes)

AMQ9546E: Error return code received.

EXPLANATION:
The program has ended because return code 1073766407 was returned from function
xcsGetRandomBytes
ACTION:
Correct the cause of the failure and retry the operation.
----- amqrmssa.c : 514 --------------------------------------------------------

Here is the SVRCONN definition

Channel name . . . . . . . . . :   SVRCHLSSL256                      
Message Queue Manager name . . :   APPSVRDEV                                                                                   
Channel type . . . . . . . . . :   *SVRCN                            
Transport type . . . . . . . . :   *TCP                              
Text 'description' . . . . . . :   SSL Server Conn Channel - SHA256  
Maximum message length . . . . :   20480000                          
Heartbeat interval . . . . . . :   300                               
Last alter date  . . . . . . . :   2019-09-28                        
Last alter time  . . . . . . . :   08.33.15                          
SSL CipherSpec . . . . . . . . :   *TLS_RSA_WITH_AES_256_CBC_SHA256  
SSL client authentication  . . :   *OPTIONAL                         

Solution

  • As all the comments suggest, your python code is lacking the TLS settings. You should be using connect_with_options to connect.

    Refer to the pymqi samples - https://dsuch.github.io/pymqi/examples.html#how-to-use-ssl-tls

    Code copied from the above link (which also has explanations)

    import logging
    
    import pymqi
    
    logging.basicConfig(level=logging.INFO)
    
    queue_manager = 'QM1'
    channel = 'SSL.SVRCONN.1'
    host = '127.0.0.1'
    port = '1414'
    queue_name = 'TEST.1'
    conn_info = '%s(%s)' % (host, port)
    ssl_cipher_spec = 'TLS_RSA_WITH_AES_256_CBC_SHA'
    key_repo_location = '/var/mqm/ssl-db/client/KeyringClient'
    message = 'Hello from Python!'
    
    cd = pymqi.CD()
    cd.ChannelName = channel
    cd.ConnectionName = conn_info
    cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
    cd.TransportType = pymqi.CMQC.MQXPT_TCP
    cd.SSLCipherSpec = ssl_cipher_spec
    
    sco = pymqi.SCO()
    sco.KeyRepository = key_repo_location
    
    qmgr = pymqi.QueueManager(None)
    qmgr.connect_with_options(queue_manager, cd, sco)
    
    ...