You have noticed that the IBM MQ product now takes a stance
to have security features turned on by default. many of you will have
undoubtedly tripped over CHLAUTH rules blocking you because you asserted
a privileged user ID over a client connection, or more recently when
playing with V8, you may have also tripped over CONNAUTH rules mandating
you provided a user ID and password because you asserted a privileged
user ID over a client connection.
You'll have no doubt learned that to just turn off CHLAUTH and CONNAUTH completely, you can issue the following commands:-
ALTER QMGR CHLAUTH(DISABLED) CONNAUTH(' ') REFRESH SECURITY TYPE(CONNAUTH)
Plus, adding the user ID that is already defined on the queue manager
system and in the privileged mqm group to your server-connection
channel's MCAUSER field.
ALTER CHANNEL( 'SYS TEM. DEF. SVRC ONN) CHLTYPE(SVRCONN) MCAUSER('morag1')
However, as you do so, you wish that you didn't have to do this and that there was a simple little script you could run to enable your own user to get in without needing to open up the queue manager completely by turning them off. That's what this post hopes to teach you. This could be useful to demonstrate MQ or to play with it and get to know it, but all the while maintaining the security of your system, or even getting to the point where you can demonstrate the security even though you're still just learning how to use it.
Changes to make to keep CHLAUTH and CONNAUTH enabled
There are several steps to this which I'm going to go through one at a time explaining why they are there, and then at the end I'll supply all the commands together (so you can copy them into a script if you want). I'm going to describe two patterns here, one where you want to supply a user ID and password and use a privileged user ID, and the other one where you don't want to supply a user ID and password and will use a non-privileged user ID.
Pattern 1: Password authenticated privileged user ID
In this pattern we will use your existing privileged user ID for the client connections you make into the queue manager, so you need to know what that user ID is and the password for that user ID. In my example, the privileged user ID is 'morag1' and my queue manager is called MORAGQM running on IP address 9.10.11.12 with port number 1515. You'll have to replace those details below with your own user ID and queue manager details. This pattern assumes your queue manager is running with V8 of IBM MQ.
We've chosen to make use of the V8 feature Connection Authentication and supply a user ID and password when we connect to the queue manager. By default CONNAUTH is enabled and is set to REQDADM for client connections which means privileged users are REQUIRED to provide a password but non-privileged users don't have to. So we don't need to change any settings there, as we're going to follow that pattern.
CHLAUTH will catch us out though as we're supplying a privileged user ID. So, as described in CHLA UTH - Al low some pri vile ged admi n s, we're going to create one route into the queue manager where the privileged user ID is allowed in since it is validated by password. To follow good practice, we're going to do this by creating a new server-connection channel rather than using one the pre-existing SYSTEM ones, but you might equally do this with the SYST EM.A DMIN .SVR CONN that MQ Explorer uses by default. I've called this server-connection channel "PASSWORD.SVRCONN" to go with this blog post, but you might equally name it related to your department or application name.
DEFINE CHANNEL( PASS WORD .SVR CONN ) CHLTYPE(SVRCONN)
Having defined it, I am now going to set up a CHLAUTH rule to allow a privileged user to be able to come through on this channel. This rule over-rides the default CHLAUTH rules that blocks all *MQADMIN - i.e. privileged users. It is over-ridden only for my specific channel, so the use of a privileged user ID is blocked over any other channel.
SET CHLAUTH( PASS WORD .SVR CONN ) TYPE(BLOCKUSER) USERLIST('nobody') DESC R('A llow pri vile ged user s on thi s ch anne l')
We also follow the best practice of setting up a backstop rule (as described in CHLA UTH - th e ba ck-s top rul e) so that no connections can be made through this, or any other, channel; and then we allow connections into our channel, but only when a password is supplied.
SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('B ackS top rule ') SET CHLA UTH( PASS WORD .SVR CONN ) TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED)
For the final step, I need to make sure that the client applications I run use the user ID I supplied (which has been password validated). This is not set by default to aid migrations from systems that are relying on the runas user ID which is flowed from the client machine for all their profile checking. If you run your client application under the same user ID as you supply in the user ID and password on your application, these last two commands are redundant.
ALTER AUTHINFO (SYS TEM. DEFA ULT. AUTH INFO .IDP WOS) AUTHTYPE(IDPWOS) ADOPTCTX(YES) REFRESH SECURITY TYPE(CONNAUTH)
To test this out, you can use the runmqsc program in client mode and supply the user ID and password with it. More details in Bite size Blo ggin g: M Q V8 - C lien t MQ SC . Type the following on your client machine:-
set MQSERVER =PAS SWOR D.SV RCON N/TC P/9. 10.1 1.12 (151 5) runmqsc -c -u morag1 MORAGQM
Before allowing you to enter any commands, runmqsc will prompt you for the password.
You can make use of various MQ samples which have been updated for user ID and password supplying, in order to try out putting and getting messages. You can read more about that in Bite size Blo ggin g: M Q V8 - S ampl es c an u se u ser ID a nd p assw ord .
Here's the full script for Pattern 1.
DEFINE CHANNEL( PASS WORD .SVR CONN ) CHLTYPE(SVRCONN) SET CHLA UTH( PASS WORD .SVR CONN ) TYPE(BLOCKUSER) USERLIST('nobody') DESC R('A llow pri vile ged user s on thi s ch anne l') SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESC R('B ackS top rule ') SET CHLA UTH( PASS WORD .SVR CONN ) TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED) ALTER AUTH INFO (SYS TEM. DEFA ULT. AUTH INFO .IDP WOS) AUTHTYPE(IDPWOS) ADOPTCTX(YES) REFRESH SECURITY TYPE(CONNAUTH)
Pattern 2: IP address filtered non privileged user ID
The first thing we notice with the default values of CHLAUTH and CONNAUTH is that they are both determined to keep out privileged user IDs from client connections. As you saw in pattern 1, you can make some changes to allow in a privileged user ID and have that protected by user ID and password validation. Alternatively, you can work with non-privileged user IDs and learn to grant only those accesses the user IDs need. Doing this can become as natural as defining the queue, and can easily be done from the same script.
The first step here is to create a user ID and ensure it not a member of the mqm group. In my example, I created a group called 'nonprivmq' and had these users be a member of that group. The commands to do that differ from platform to platform and you probably know them as well as I do, but here are a few examples:-
Windows:
net localgroup nonprivmq /ADD net user morag2 passw0rd /ADD net localgroup nonprivmq morag2 /ADD
Linux:
groupadd nonprivmq useradd morag2 -g nonprivmq
This user ID that you have created on the queue manager system is not privileged, so it has access to nothing. A connection asserting that user ID would be allowed in by CHLAUTH rules but then would fail because it didn't even have +connect authority to the queue manager. Rather than having to make changes at the client side, or have to define the user ID on the client machine, we are just going to map our connections to this user ID when the server-connection channel runs. This mapping will be done just by filtering by IP address of the client machine - not really authentication, but better than nothing, and will give you a feel for how to use CHLAUTH rules. For decent security you should consider user IDs and passwords (which were shown in Pattern 1) or the use of Digital Certificates and TLS on your channel connections.
As above, we are going to create a new, non SYSTEM server-connection channel for our demonstration. This time I will name it NONPRIV.SVRCONN, although again you will probably want to name it for your department or application.
DEFINE CHANNEL( NONP RIV. SVRC ONN) CHLTYPE(SVRCONN)
Having defined it, we will create our CHLAUTH rules, a backstop rule just as in Pattern 1, and a single IP address rule that allows only your client machine to connect and maps the connection to use your newly created non-privileged user ID.
SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('B ackS top rule ') SET CHLA UTH( NONP RIV. SVRC ONN) TYPE(ADDRESSMAP) ADDR ESS( '9.1 0.20 .30' ) MCAUSER('morag2')
We're not finished yet, but if you were to connect into that server-connection channel now:-
set MQSERVER =NON PRIV .SVR CONN /TCP /9.1 0.11 .12( 1515 )
you'd find that you still didn't have access, not because CHLAUTH blocked you, but because you don't have the necessary privileges required to do anything, like connect for example.
The next step is to rectify that. Since the premise here is that this one user is to be able to do everything, the following set of authority commands are very broad. While this is fine for trying out MQ, in a production system you will of course only grant users access to the resources they need, and not to everything as the following commands do.
SET AUTHREC OBJTYPE(QMGR) GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(QUEUE) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(QUEUE) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(CHANNEL) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(CHANNEL) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT)
These pairs of commands can be repeated for each object type to ensure access to absolutely everything is granted to the 'nonprivmq' group. Alternatively, if you want to start using security in a more granular fashion, as you will do in production, you can change the PROFILE string to only contain the name of the object you want access to, or a prefix that covers all your application's objects, e.g. INVOICE.**. If your queue manager is only being used for client applications and not client administration, you could omit all the AUTHADD(CRT) rules since your applications aren't going to need those.
Here's the full script for Pattern 2.
DEFINE CHANNEL( NONP RIV. SVRC ONN) CHLTYPE(SVRCONN) SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESC R('B ackS top rule ') SET CHLA UTH( NONP RIV. SVRC ONN) TYPE(ADDRESSMAP) ADDR ESS( '9.1 0.20 .30' ) MCAUSER('morag2') SET AUTHREC OBJTYPE(QMGR) GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(QUEUE) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(QUEUE) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(CHANNEL) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(CHANNEL) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(CLNTCONN) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(CLNTCONN) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(AUTHINFO) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(AUTHINFO) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(COMMINFO) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(COMMINFO) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(LISTENER) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(LISTENER) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(NAMELIST) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(NAMELIST) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(PROCESS) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(PROCESS) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(SERVICE) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(SERVICE) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(TOPIC) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL) SET AUTHREC OBJTYPE(TOPIC) PROFILE('**') GROUP('nonprivmq') AUTHADD(CRT) SET AUTHREC OBJTYPE(RQMNAME) PROFILE('**') GROUP('nonprivmq') AUTHADD(ALL)
Summary
Hopefully, this post will encourage you to use your queue managers without turning off security completely, thus preparing you and teaching you how MQ security works before you get to the point of running a production system. Clearly the above patterns are still fairly open in that the user we have allowed in, in both cases, can do anything. However, it is a good starting pattern for your test queue managers, or sandbox queue managers where you want to get a feel for how things work. Then you can try it out with more granular access for your business applications as you develop them.
Comments
Post a Comment