Remote MQ Server Authentication - ibm-mq

I am trying to figure out how we would configure / setup the authentication, Queues, and Queue managers for connecting an MQ Client that is on a server / domain completely separate from the MQ Server it will be forwarding messages to.
I would assume that in a normally organizational environment you could just use Active Directory (if hosted on windows servers) for the authentication / AD lookup. However, in this scenario because they are different orgs you couldn't do that?
Can you simply apply SSL certs to both client / server and use that as your authentication? If so is that just applied to the Channel used in the connections?
Not sure how to proceed forward with this.
Any suggestions would be greatly appreciated.
Thanks,
S

Take a look at the Hardening WebSphere MQ presentation for v7.0 and earlier. The thing to remember is that WMQ does not authenticate anything. It authorizes based on OS identities and groups but there is no password checking being done.
For situations where QMgrs and clients live on Windows networks, the connection uses the SID and so it appears that some useful authentication was performed. BUT if a connection from a non-Windows platform is attempted, the Windows QMgr uses the string representation of the ID. So for example, if someone has a Linux VM on their desktop they can easily create a user ID called MUSR_MQADMIN and the Windows QMgr will accept the connection. There is a setting that causes the Windows QMgr to only accept connections with SIDS that it can resolve but even there its just a matter of knowing what the SID values are to spoof them on a connection.
The lesson here is that any QMgr, even one on Windows, must be configured to authenticate remote connections. With WMQ v7.1 and later, the QMgr has functionality to map X.509 certificate DNs to user IDs, or to perform IP filtering. Prior to v7.1 these functions required an exit such as BlockIP2. Capitalware sells MQAUSX which has the functions of BlockIP2, plus will perform ID and password authentication and is supported.
The first recommendation is to use a v7.1 QMgr so that you get the CHLAUTH rules for mapping and filtering. Even if you don't use certificates v7.1 limits administrative connections so it is harder for an attacker to gain full admin rights. Then if you need password validation, use SSL channels (to encrypt the password and prevent simply replay attacks) in combination with an exit that you can write yourself or purchase.
Just be aware that allowing a connection from outside your domain doesn't present any new challenges. The pre-v7.1 Windows QMgr that does not have MCAUSER set in the channel definition or by an exit allows remote administrative access, even from connections originating in the local Windows domain. There was always a need to harden that QMgr, even though honest users will have received authorization errors if the administrator did not set up auths for them.
Summary:
For clients originating outside your administrative domain, I'd recommend mutually authenticated TLS/SSL channels. The same page I linked to above also contains the WMQ Security Lab guide and scripts which show how to script the creation and exchange of WMQ certs and configure WMQ Explorer with them.
Whatever else you do, the MCAUSER on any legitimate channel must be set either in the configuration or by an exit. If the client is allowed to specify the ID, there is nothing to prevent it from specifying an administrative ID. For channels that are NOT being used such as SYSTEM.DEF.* and SYSTEM.AUTO.*, set the MCAUSER to a value that cannot be a local ID such as no!body or on v7.1 and later *NOACCESS.

Related

Does Powershell's -UseDefaultCredentials use Kerberos?

In Azure DevOps services, when you connect an agent to the server, you have different types of ways to authenticate to the server. You can see here for example, about connecting a Linux agent, that you have these 4 types:
Alternate (Basic authentication)
PAT
Negotiate - Connect as a user other than the signed-in user via a scheme such as Kerberos or NTLM.
Integrated - Not supported in Linux
The integrated type is mentioned in the page about connecting a Windows agent as "Windows default credentials"
Bare with me please.
In my organization, we have a Active Directory domain with a Single-Sign-On, I suppose it uses Kerberos as the authentication protocol. Sometimes I use Powershell scripts to access the API of our internal Azure DevOps Server, and I use the -UseDefaultCredentials flag so the user won't have to enter username and password - it will just authenticate based on the logged-in user.
That got me thinking that the -UseDefaultCredentials flag is using Kerberos to authenticate.
But from the above, it seems that Integrated is using "Default credentials", which is something else than "Negotiate" which uses Kerberos.
Can someone help me understand this?
The UseDefaultCredentials flag tells the underlying system to try and use the caller's SSO credentials, which in most cases is the credential used to log into the system interactively or otherwise.
Strictly speaking it does not indicate which protocol to use. What it's actually saying is "dear system internals: please figure it out for me". The way this works is by selecting the negotiate protocol, which as it's name suggests negotiates the use of specific authentication protocols based on the client credentials as well as information from the server. This is called the SPNEGO protocol. It is transparent to the caller.
SPNEGO is fairly simple in nature. The client has a list of known authentication protocols (Kerberos, NTLM, etc.) and will send that list to the server saying 'pick one please'. The server can select any of them and respond telling them what to use, and the client then goes and uses it. Fin.
SPNEGO is also relatively smart because it can reasonably predict what it thinks the server will accept and will attempt to optimistically provide a token up front using the first protocol in the list. So if it thinks it needs Kerberos it'll go and get a Kerberos ticket up front and send it first. The server might think that's fine, or it might fail and return a response saying
"no, I really need NTLM", and so the client tries again with NTLM.

Can a certificate with same CN be used in two remote qmgrs?

Can you use the same certificate for two MQ Qmgrs running in different servers? I know if you have the qmgrs in the same server you can use the same cert, but when you have two servers the CN(common name)of the certificate is the hostname, so it would be different for both and i am not sure if both of them can share the same cert.
The IBM MQ product only checks the DN value of the peer queue manager cert against the SSLPEER configured on the channel. MQ unlike browsers (and other software such as LDAP libraries) does zero validation of the DN (or SAN) against the hostname of the remote host.
There is no technical reason the same cert could not be used on two servers, this is very common when you have HA and DR configurations.
I would consider it best practice to have unique certs for each queue manager since these are used to prove identity.
Security implications for using the same certificate on two separate queue managers:
You have to copy the private key somehow between the two machines.
There are now two places an attacker could gain the single Certificate.
You can't rely on the SSLPEER feature on the client to ensure you connect to one specific QM but you could still ensure you have connected to a QM hosting that cert.
You can't rely on the SSLPEER feature on the connecting queue manager (SDR channel for example) to ensure you connect to one specific QM but you could still ensure you have connected to a QM hosting that cert.
No, client should reject connection as untrusted.
Client connects to particular server and CN in certificate, which server sends back to client, must be the same as is server name.
You can use SAN (Subject alternative name) to put there more FQDN or wildcard (*) in CN.
If client connects to MQserver1:1414, servers certficate must have MQserver1 in CN or in SAN of certificate

How to keep client passwords safe on server machine

Is there any way to keep client third party service password secured from others being able to access server machine?
Password is used to send messages between two system, from A->B. There are 3 actors:
client - owner of the infrastructure and user of system A and B
provider A - author of system A which have ablitity to RDP into client server and administrate it to keep system A working
service B - service providing access to system B, secured with password known to client which provider A shouldn't directly know
Every solution based on encryption and storing password in configuration/database is not an option because provider A will always have access to decrypting algorithm and mangled password.
Best solution right know is based on keeping password in server Windows Credential Manager. Provider A can use it inside message sender process by its code but password itself is not directly visible in server. It always can be retrived by provider A but it is a bit safer.

Connecting from .NET to MQ-Series

There are similar questions to this one, but not quite the same...
I have a C# program that is using amqmdnet.dll (from 9.0.1.0 MQC Redist)
The code to connect is:
Hashtable mqProperties = new Hashtable();
mqProperties.Add(MQC.CHANNEL_PROPERTY, channelName);
mqProperties.Add(MQC.HOST_NAME_PROPERTY, hostname);
mqProperties.Add(MQC.PORT_PROPERTY, port);
queueManager = new MQQueueManager(strQueueManagerName, mqProperties);
It works fine and writes to the queue. I assume it picks up my current login id from Windows.
When I run the same code on IIS, it connects but fails with an auth error 2035 when trying to write to the Queue.I assume this is because IIS is running as a different user-id.
I tried adding:
mqProperties.Add(MQC.USER_ID_PROPERTY, "myuserid");
mqProperties.Add(MQC.PASSWORD_PROPERTY, "mypassword");
and it did not work. Trying "mydomain\myuserid" did not work either. Some other posts mentioned that MQ needs the Windows SID. I tried using that string, but that did not work either.
At this point, I am playing with this, so I'd prefer not to ask the admins to set up a new userid on the MQ server side. With this in mind, is there any way I can login when running under the IIS user, but pass in my userid/password or some other credential to make this work?
If the queue manager is v8.0 or later and is configured to use CONNAUTH and has ADOPTCTX(YES) set you can present an id and password. If it does not have this set then the value presented in the UserId and Password property of a .NET client will be ignored.
A IBM developerWorks MQdev blog post "MQCSP Password Protection in MQ V8 has details on how to do this in various languages."
For .NET you should be able to use what you have with the addition of the MQC.USE_MQCSP_AUTHENTICATION_PROPERTY set to true:
mqProperties.Add(MQC.USER_ID_PROPERTY, "myuserid");
mqProperties.Add(MQC.PASSWORD_PROPERTY, "mypassword");
mqProperties.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
The queue manager will then authenticate this ID. If the queue manager is set with ADOPTCTX(YES) then it will always use the authenticated ID for OAM checks. If it is set to ADOPTCTX(NO) it will still use the ID the process is running under to perform OAM checks. It is highly recommended that this be set to ADOPTCTX(YES).
Update 2017/02/20:
Related to the comment "I can see that it might be turned off by admins so that MQ relies on the larger organizational SSO infrastructure.". Without setting up CONNAUTH and ADOPTCTX(YES) you can assert any id you want to over the channel. If a CHLAUTH rule is not in place to block administrative users then you can obtain full MQ administrative authority without any form of authentication.

Pass current user credentials to remote server

I have an application server (webservice or remoting, not yet decided) on a remote machine and a client on the same domain. I want to authenticate the user as a domain user on the server.
I can ask the user to enter their Windows username/password and send those to the server and get the server to check them against Active Directory but I would rather not. Is there any way I can get the client to send some kind of token which the server can then use to identify which domain user is sending it a request? Obviously I want to protect the server against someone sending a fake user ID and impersonating another user.
Clarification
The client on computer A will communicate with the server on computer B. I think I will probably using .NET remoting for this communication. On the server I merely need to know the ID of the user on computer A; if the app on computer A must send the ID I need to be sure that it hasn't sent the ID of a different user.
I don't need to impersonate the other user, I merely need to know (for certain) who it is.
Are you saying that the client communicates against your server, and you need to use the client's privileges at a third server? That scenario describes The Double-Hop Problem. The blog most describes it in detail, and what can be done to circumvent it (domain modifications).
[...] you can get around the problem and use proper delegation if you set up your network to use Kerberos and set up the web server in question as trusted for delegation.
Added:
I know of no way you can identify the user on computer A. Would it be enough if it was just the user executing your program? You could use windows authentication in a domain scenario, but that would only give you the privileges used by the program to authenticate, which may differ from the actual evil user in front of the keyboard.
Added:
Your comments to this post indicates that windows authentication with impersonation would work for you. Check http://community.bartdesmet.net/blogs/bart/archive/2006/08/26/4277.aspx for code examples.

Resources