1

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                         
nads
  • 71
  • 1
  • 7
  • Is the `AMQ9546E` the only error you see in the `AMQERR01.LOG`? I don't see that you are specifying a cipher in your code, have you had a look at the sample pymqi apps that show how to use TLS? Do you have a key store? The setting `AllowedCipherSpecs` in the `mqclient.ini` is only providing which ciphers are allowed overall, you still need to specify a keystore and ciphersuite. There is a sample `amqssslc` that comes with the IBM MQ client that can be used to test the connection to help eliminate pymqi as a problem. Check the queue manager's `AMQERR01.LOG` for errors at the same time. – JoshMc Oct 28 '20 at 14:50
  • After reviewing the [knowledge center](https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.2.0/com.ibm.mq.sec.doc/q134760_.htm) it does not appear that `ANY_TLS12_OR_HIGHER` is a valid value to specify for `AllowedCipherSpecs`, if you do not specify anything it already includes TLS1.2 and TLS1.3 ciphers by default in the allowed list. The result of setting it to an invalid value may be that no ciphers are allowed. I would suggest removing this and go back to troubleshooting the `2393`, what error was in the `AMQERR01.LOG` when you received the `2393`, client and queue manger are helpful. – JoshMc Oct 28 '20 at 14:58
  • @JoshMc I added 2393 error description to original post. You are correct our MQ version is 9.1.0 & it does not support ANY_TLS12_OR_HIGHER option. MQ manager on IBM I expects cipher spec TLS_RSA_WITH_AES_256_CBC_SHA256 but we still get SAME 2393 error with this cipher as well. Not sure what cipher to setup here. – nads Oct 28 '20 at 18:53
  • Please can you show where you are setting the cipher spec in both client application and on the queue manager (SVRCONN definition). Please also show the error from the queue manager AMQERR01.LOG when you get the 2393 error (I think the AMQ9546E error was from the 2059 example?) – Morag Hughson Oct 29 '20 at 03:25
  • Relating my comment: have you had a look at the sample pymqi apps that show how to use TLS? Do you have a key store? – JoshMc Oct 29 '20 at 08:52
  • The `mqclient.ini` `AllowedCipherSpecs` settings is not how to (in general) specify the cipher to use on a client connection. – JoshMc Oct 29 '20 at 08:53
  • Technically you could limit `AllowedCipherSpecs` in the `mqclient.ini` to only `TLS_RSA_WITH_AES_256_CBC_SHA256`, and then in your program specify your cipher as `ANY_TLS12_OR_HIGHER`, but the more common approach would be to directly specify TLS_RSA_WITH_AES_256_CBC_SHA256 in the program. – JoshMc Oct 29 '20 at 10:29
  • @MoragHughson client application cipher is set in mqclient.ini and AMQ9641E error is for 2393 example in post. – nads Oct 29 '20 at 13:09
  • @JoshMc a link would have been helpful, I am going to try those options today. Thanks for your suggestions. – nads Oct 29 '20 at 13:13
  • Check you pymqi github repo for samples. The `mqclient.ini AllowedCipherSpecs` setting is not how to (in general) specify the cipher to use on a client connection. – JoshMc Oct 29 '20 at 14:37
  • @nads - if what you have supplied in the question about `mqclient.ini` is where you think you are setting the cipher, then you are not setting it. This is not how you set the cipher, this is just how you can unrestrict some ciphers to allow them to be used. Can you please also add SVRCONN definition to the question. – Morag Hughson Oct 30 '20 at 03:07
  • @JoshMc.**CipherSpec** matches the server channel but client authentication is **optional**. I could not find example for such settings, How to configure pymqi? Following pymqi github example we created client certificate but we are getting AMQ9665E: SSL connection closed by remote end of channel 'SVRCHLSSL256'. – nads Oct 30 '20 at 14:45
  • @MoragHughson I added SVRCONN definition to question. As you see SSL/TLS client authentication is optional and CipherSpec is matching server channel. Not sure how to configure pymqi for such settings? – nads Oct 30 '20 at 14:51
  • Did you not see the answer that @chughts kindly created yesterday, this shows how to set it. The mqclient.ini only shows what is allowed not what to use for a channel. – JoshMc Oct 30 '20 at 15:32
  • Looks like you have updated the question with the new code that @chughts provided, this and now changed the question. I recommend that you at least indicate this is what you have changed and still show the original or you lose the value provided by showing what the original code looked like that is now fixed. You show you have `/var/mqm/qmgrs/QM1/ssl ` does this ssl.kdb contain the certs to trust the queue manager cert? You also have indicated the cipher as `TLS_RSA_WITH_AES_256_CBC_SHA` but you show the SVRCONN requires `TLS_RSA_WITH_AES_256_CBC_SHA256`, this must match. – JoshMc Oct 30 '20 at 15:36
  • @JoshMc I separated old & new code in question. CipherSpec was typo, I corrected it. Could pymqi be used with cipherSpec=`TLS_RSA_WITH_AES_256_CBC_SHA256` but without client certificate authentication? As today it's optional, IBM I server admins are not comfortable in setting it up. – nads Oct 30 '20 at 16:25
  • If you have a client cert in you kdb file that matches the expected label it will be sent, if they use it is up to them. If you don't have a cert, one will not be sent. You still need to trust the queue manager cert. Normally this would be done by including the root cert of the chain that signed it. – JoshMc Oct 30 '20 at 17:19
  • @JoshMc After removing client cert from kdb and just including root cert to trust queue manager. Now client process hanged on connection (No errors) and Server logs shows "AMQ9271E: Channel 'SVRCHLSSL256' timed out. Client stack trace ```File "classMQ.py", line 62, in get_MQmanager _MQmgr.connect_with_options(queue_manager, cd=cd, sco=sco, user=user, password=password) File ".../pymqi/__init__.py", line 1617, in connect_with_options rv = pymqe.MQCONNX(name, options, cd, user_password, sco.pack()) File "", line 1, in File "", line 5, in ``` – nads Oct 30 '20 at 21:08
  • Do you see any error in the client side AMQERR01.LOG file? This could be a issue with OCSP validation. By default the client will attempt to contact the OCSP server listed on the queue managers cert. you can either fix it so you can get to the ocsp server or you can disable the checking with a setting in the mqclient.ini SSL stanza. – JoshMc Oct 30 '20 at 21:15
  • Thanks for your help @JoshMc. Indeed that was the issue, we could connect now. – nads Nov 02 '20 at 15:28

1 Answers1

2

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)

...

chughts
  • 4,210
  • 2
  • 14
  • 27
  • connect with options is now throwing AMQ9665E: SSL connection closed by remote end of channel 'SVRCHLSSL256'. Also Server channels on the MQ Manager is NOT configured for client authentication. – nads Oct 30 '20 at 14:36
  • I don't understand is the 'Not configured for client authentication' part of the error stack, or are you telling us that ? – chughts Nov 02 '20 at 10:04