In my IBM MQ, I have multiple queue managers which I need to enable SSL.
I've been following this blog and successfully configured SSL to a single queue manager.
If I have more than 1 queue manager, do I need to have a dedicated keystore for each queue manager?
Is there a way to have a global/common keystore and enable SSL for all the queue managers using that keystore?
Have this question since the blog says,
"A word about the certificate label here. Default name for this certificate is in the form of: ‘ibmwebspheremq’ + ‘queue manager name’ (all lower case)
In our case this becomes: ‘ibmwebpsheremqmyqm01’"
Any guidance would be very much helpful.
IBM MQ v 9.1
The answer like many of these questions is it depends.
If you can send the keystore files around to each machine - securely then you could have the same files for all of your queue manages. If you do it insecurely then people could take a copy of your keystores and impersonate you, and see all your traffic.
If you have your private certificate in an external HSM (think Secure USB store), you cannot get the private key to another machine, and so you will have to get a machine unique certificate.
You can use CERTLABL(...) to specify the name of the certificates in the keystore.
Ive just (today) put up some blog posts about TLS on midrange. See https://colinpaice.blog/2021/02/13/which-cipher-spec-and-certificate-type-should-i-use-for-the-mq-server-tls-1-2
When Queue Managers are on the same machine, then you can use the same keystore for all your Queue Managers. You can just specify the same file in the SSL config of the Queue Managers. For example:-
ALTER QMGR SSLKEYR('/central/ssl/key')
The different Queue Managers will find their personal certificate based on the label of the cert. That’s what that quote is about. For example:-
On Queue Manager MQG1
DISPLAY QMGR CERTLABL
QMNAME(MQG1) CERTLABL(ibmwebspheremqmqg1)
On Queue Manager MQG2
DISPLAY QMGR CERTLABL
QMNAME(MQG2) CERTLABL(ibmwebspheremqmqg2)
These are the names that the queue manager will look for in the keystore by default. As you can see they are different for each queue manager and so can happily co-exist in the same keystore. If you want to choose different labels for the certificates, just alter the CERTLABL attribute of each Queue Manager.
Related
I am using SSL self signed certificates to connect MQTT in rabbit MQ broker. Now I need to update them runtime without restarting server. Rabbit MQ trust store gives good solutions for this, but it read only CA certificate from local whitelisted folder or http endpoint. I need to take server certificate and server key from external whitelisted folder or http endpoint. Can I do this using rabbitmq-trust-store plugin or else have any other solution for this.
No need to restart server. Put the new certificate in correct place and wait for a few minutes. Certificates automatically update.
I am trying to connect to a remote QM using SSL from an AIX Machine.
I have setup my QM and Channel to allow SSL connections.
I have created a KeyStore on the Server (Machine containing the above QM + Channel) and have exported its self signed certificate and imported the certificate from the Client.
I have used GSK on the AIX machine to create an Keystore in which both Self Signed and Signer of the Server are present.
Client Code is as below when trying to connect to the QM. This code does work on Windows however does not work on AIX which leads me to believe this is a certificate issue which i have done wrong and not a code issue.
the CipherSpec is - TLS_RSA_WITH_AES_256_CBC_SHA256
and the keystore location is correct.
m_QChannel.setChannelName(m_strChannelName);
m_QChannel.setConnectionName(m_pParent->GetName());
m_QChannel.setTransportType( MQXPT_TCP );
if (!m_strCipherSpec.IsEmpty())
{
m_QChannel.setSslCipherSpecification(m_strCipherSpec);
if (!m_strKeyStore.IsEmpty())
{
m_QMgr.setKeyRepository(m_strKeyStore);
}
else
{
CString strKeyStore = getenv("MQSSLKEYR");
m_QMgr.setKeyRepository(strKeyStore);
}
}
//Set the queue manager options
m_QMgr.setName(m_strName);
m_QMgr.setChannelReference(&m_QChannel);
if (!m_QMgr.connect())
{
m_iLastError =m_QMgr.reasonCode( ) ;
return false;
}
However when i try to run my application to connect i get a MQRC 2393 Error returned, When checking the Error logs it complains about the Certificates.
I have tried Restarting the QM, Restarting the Channel, Refreshing the SSL but all with no luck. What have i missed ?
Any help appreciated.
The current label of the client cert you have is ibmwebspherebldaix02.
For a MQI client app the default cert label that MQ will look for is the string ibmwebspheremq followed by the name of the user that the application is running as all in lowercase.
In this case it does not meet the first part of the default's requirement since it starts out as ibmwebsphere and is missing the mq and is then followed by bldaix02.
You have a few options:
If the user is bldaix02 then you can rename the cert in the keystore to ibmwebspheremqbldaix02. If that is not the username then rename the cert to ibmwebspheremq<username> all in lowercase. This option should work with all version of the IBM MQ product.
If you are using IBM MQ v7.0 - 7.5 (these are all out of support), you could tell MQ to use the Default cert by setting the environment variable AMQ_SSL_ALLOW_DEFAULT_CERT to any value before starting the application or if doing it within the program, do it before calling connect. Note this feature was removed in the initial versions of IBM MQ v8.0 and v9.0 but was later added back at 8.0.0.7 and 9.0.0.1 and later.
If you are using IBM MQ v8.0 or later (you should be since these are the only currently supported versions) you can tell MQ to look for a different label. You can do this in four ways:
If using a CCDT set the CERTLABL attribute of the CLNTCONN channel.
Programmatically set the CertificateLabel attribute in the MQSCO
Set the environment variable MQCERTLABL before starting the application or if doing it within the program, do it before calling connect.
Using the CertificateLabel attribute of the SSL: stanza in the mqclient.ini.Note: there are various ways MQ will find the mqclient.ini and these are detailed in both the IBM MQ Knowledge center and various answers here on StackOverflow.
You can find more information in the following links:
Technote: Specifying the userid in the SSL certificate label for an MQ client
IBM MQ 8.0.0 Knowledge Center > IBM MQ > Security > Security overview > IBM MQ security mechanisms > Security protocols in IBM MQ> The SSL or TLS key repository > Digital certificate labels, understanding the requirements
Let us say, I used a queue manager QMGR1 in host1 to create a CSR and obtain a CA-verified certificate labeled ibmwebspheremqqmgr1. Can I use load the same certificate (and its root and intermediary chains) in another host host2 for the a queue managed named same (i.e. QMGR1) ? In other words, a certreq needs to be present when we 'receive' a certificate using rumqakm or no? Can we just 'add' a cert (like we do the chains)? If the question is not clear, please ask, i can provide more details. In my case host2 is production. host1 is a QA environment where we test connectivity. Thanks.
Update question from comments 26DEC16
Specific to MQ, I believe I would have to load CSR first on host2 and then receive the CER again, right? I wonder how do I 'load' the CSR without creating it. I see an option to recreate it in runmqakm, never used that before and not sure if that will work.
TL;DR: Yes.
When you create a CSR using IBM GSKit (e.g. runmqakm), the result is a certificate that is unsigned and the CSR file itself. The CSR is cryptographically bound to the unsigned certificate that remains in the .rdb file of the keystore. The signed CSR cannot be received into just any keystore at that point.
When you receive the signed CSR, it is combined with the pending unsigned certificate and moved to the .kbd file of the keystore. At this point it is a valid personal certificate with the label name you specified (ibmwebspheremqqmgr1 in this case) and the DN that you specified.
Once completed you have a usable personal certificate. If you wanted to use it on another QMgr you would need to get that certificate to that other QMgr in one of two ways:
Copy the set of files that comprise the keystore.
Export the personal certificate to a file and then import that file into the other QMgr's keystore.
If you copied the entire keystore and the other QMgr is also named QMGR1 then you can use them immediately. If the other QMgr has a different name, then you'd have to rename the certificate to something other than ibmwebspheremqqmgr1, or in a modern QMgr set the QMgr's CERTLABL attribute to ibmwebspheremqqmgr1. Generally, you want the cert label to reflect the name of the QMgr using it so a QMgr named QMGR2 with a CERTLABL of ibmwebspheremqqmgr1 is not recommended.
If you import the certificate then you can set the label during the import command.
Keep in mind, the label and the Distinguished Name are two completely different and unrelated things. The distinguished Name is the value that the CA verified and signed off over and is cryptographically bound tot he keys in the cert. It is the thing that a remote connection partner decides whether to trust or not.
The label is how the local QMgr or client finds its own certificate. Imagine you had created two personal certificates, the QMgr needs to know which one to send. It finds the correct one by matching the label of the certificate to the expected value of ibmwebspheremq[qmgr name in lower case] or against the QMgr's CERTLABL attribute if it is not blank.
This is why the certificate label can be changed easily with a GSKit command but the Distinguished Name is immutable.
With this in mind, note that external, and many internal, CAs will expect the certificate Common Name of the certificate to contain the fully-qualified hostname where the certificate will be used. HTTPS clients check that the certificate CN matches the hostname when they connect. For an MQ connection, this is not the case. You can put anything in the CN that your CA will sign and use it on a QMgr of any arbitrary name. So your certificate can have CN=QMGR1 and that QMgr can live on mqhost.yourcompany.com and MQ likes it just fine. However, clients using the new MQ REST API will not! This is an important distinction for people hoping to use the new MQ REST API.
Finally, please note that best practice is to generate the certificates where they will be used, protect them using filesystem permissions, keep them in local storage, and never copy or move them from that location. Public/Private key crypto was invented to solve the very difficult problem of securely exchanging private keys. If the personal certs are copied around it defeats the purpose of using them in the first place.
The various commercial PKI packages (i.e. IBM Tivoli Key Lifecycle Manager, Venafi, etc.) all solve this problem using FIPS-certified algorithms that don't store keys or crypto primitives on disk, securely wipe memory space before releasing it, and in general take excruciating care to not leave keys unprotected in transit, disk or memory. If you must copy personal certs around, use a real PKI package designed for that purpose if the company has one. Otherwise, export them to a .p12 with a very long and random password and avoid email, FTP, or other non-secure means of copying the file around.
Im trying to use JKS ssl certificate in JMeter to authenticate to a IBM MQ connection factory. I have updated the jmeter system.properties with javax.net.ssl.keyStore and password fields with relevent entries. But it fails to connect stating
"Failed to connect to Queue Manager".
I am not able to debug it either because even though i updated the debugging in jmeter with log_level to "debug" in jmeter.properties its not displaying the necessary logs either.
I tried to use custom jndi.properties file and this is not recognized either (created a jar and stored it in lib and lib/ext folders). I have also tried to use ssl manager option of jmeter.But no luck on that either.
If anyone has configured Jmeter JMS Publisher(Not point to point) to authenticate to IBM MQ queue manager,any help would be really appreciated.
There is a tremendous amount of information missing from this question. You will need to add detail if you want a more precise answer. However, perhaps in working through my reply you will find the error and fix it. If so, please come back and update your question with the details of what you did to fix it.
You mention that you want JMeter to authenticate to MQ. There is no mention of MQ authenticating to JMeter. However there is no option to use TLS with MQ where the QMgr does not require a certificate. Therefore, you need the following:
On the QMgr side
The QMgr must have a personal certificate.
The label of the QMgr's certificate must be in a specific format or (as of v8.0) the QMgr's property needs to point to the right certificate.
If the QMgr's certificate is CA-signed, the CA's signer cert(s) must be available to the QMgr for it's own certificate.
The QMgr must have either the CA signer cert(s) for JMeter's certificate (if CA-signed) or JMeter's public certificate (if self-signed).
The QMgr's channel must specify a CipherSuite.
On the JMeter side
JMeter must have a personal certificate.
If JMeter's certificate is CA-signed, the CA's signer cert(s) must be available in the trust store.
JMeter must have either the CA signer cert(s) for the QMgr's certificate (if
CA-signed) or the QMgr's public certificate (if self-signed).
JMeter's MQ channel must specify the Cipherspec that corresponds to the CipherSuite set at the QMgr.
Of all the information I've listed here, almost none of it is available in the question as written. Someone responding has no reason to believe that the QMgr is even set up for TLS at this point. Nothing in the question indicates that this has been done. Assuming the QMgr is set up for TLS, does it work with IBM's sample programs? Again, we have no way to know from the question as written.
Please be aware though that, like any good security error, nearly all of the information is logged at the QMgr side. For example, if a login fails, the last thing you want to do is to tell the attacker that the User ID is bad or the password is bad. The error message should never provide more information for the attacker.
With this in mind, security errors on the client side tend to produce client-side error logs. Security errors on the QMgr side produce QMgr-side logs and very sparse client messages. If you follow up here, please post sufficient info for us to help diagnose the issue, including the QMgr-side error log entries.
I am trying to write a java application connecting to server connection channel with SSL enabled.
So far, I have been successfully connected to the channel by setting authentication to 'optional'. However, when I set it to be 'required', the connection fails.
Here is what I did:
Create key db for queue manager and keystore for the java client user.
Create key/self-signed certificates for the queue manager and the client user, with names prefixed ibmwebspheremq.
Export, exchange and import certificates for the queue manager and the client. (I did answered 'yes' when being asked whether I trust the queue manager cert).
The location and password to the truststore and keystore are set to point to the same keystore at the client side, where the orgininal created client user key and the imported queue manager key are.
With other settings being the same, if I switch back to 'optional' authentication, the connection works.
I think there is something I understand incorrectly about this ssl authenticaion but cannot figure out what.
Could someone kindly help me?
I beat my head against that wall for a couple of weeks. IBM L2 Support eventually clued me in. My issue here was that keytool will use DSA algorithm unless you specify RSA. This results in keys of length 1022 instead of 1024, which WMQ doesn't like. The fix was to specify -sigalg RSA when generating the certificate and everything works.
I've asked the IBM WMQ team and WMQ FTE team to add this to their Infocenter documentation.