![]()
Further input/tips is appreciated. Feel free to drop us a email.
Foreword
End user agreement
News
Installation
Activation
Configuration
Configuration examples
Enhanced SSL
Single configuration file for multi channels/queue
managers
Specifying patterns
Compilation
Considered changes in the near future
Messages
It have always been a challenge to keep our WebSphere MQ Networks secure. Today in WebSphere MQ is IBM offering us the ability to use SSL to prevent intruders. Anyway SSL requires some administration and creating an infrastructure that supports SSL, CA etc. When I started working with WebSphere MQ (version 1.2) we used it only as an internal tool, and there was no client connections allowed. That was an manageable solution. After the introduction of MQ-clusters and the usage of Client Connections it became a challenge to keep the WebSphere MQ network secure.
This was the trigger to start building a simple WebSphere MQ Security exit that was able to help me keep our networks secure, I had to do a lot studying the intercommunication guide, I did a password verification exit, similar to CSQ4BCX3 (supplied together with MQ 5.3.1 for z/OS). When this exit was finished I began to look on the security, and saw that we also had to do some IP-filtering, and I needed the ability to log connection attempts, and sometime had to do investigation when spammers entered the network, and was trying to connect, using a channel. This lead to development of the LogIP and BlockIP exits.
When the exits was released late 2002, I could see that it was an success, I had some chats on my first visit on the T&M conference in Las Vegas in 2003, and I could feel that there was a need to promote the exit, because it was the same situation all WebSphere MQ administrators was facing: Keep MQ tight.
What started just as an simple exit have now been ported to z/OS, Linux, Windows, OS/400, HP-UX, Sun/Solaris. A lot of specialists round the globe have contributed to BlockIP2 with requirements, coding, testing etc.
The MAXCHL connection control was originally based on the Support pack ME71 written by Tony Madden, MQWare UK. Under z/OS, Windows and UNIX/Linux I've moved into shared memory, to gain high performance without a high CPU consumption. This function is now implemented in WebSphere MQ version 7.0.
You and your company are allowed to use and modify the program code as long that the code is not sold or build/included in a commercial product without a written accept from the author.
The intension of supplying the source code is to make it easier to WebSphere MQ professionals to keep their WebSphere MQ environments secure.
You are allowed to refer and/or put link on you web-site that points to http://www.mrmq.dk/BlockIP2.htm. You are also allowed to include this reference in your written documentation, but we are allowed to move the website and links without any notice.
You are NOT allowed to place the downloaded material on your own internet-webserver/homepage for download. Instead add a link to http://www.mrmq.dk/BlockIP2.htm.
MrMQ.dk have no legal obligation if BlockIP2 causes your system any harm, BlockIP2 is written and is delivered on AS-IS basis, and we're trying to keep it working. When you install it on your own system, it's like a tool written by your self, and therefore on your own risk.
MrMq.dk is allowed to share received ideas and comments with our partners to enhance the WebSphere MQ products. Received traces and dumps are treated as confidential.
Support for WebSphere MQ version 5.3 is withdrawn.
BlockIP2 works fine with WebSphere MQ version 7.0
When you have downloaded the BlockIP2.zip and unpacked the files it's time to install the Exit.
Just copy the BlockIP2.dll and BlockIP2S.exe into the "exits" directory where WebSphere MQ is installed, this makes it very easy to configure the exit. It's VERY important that BlockIP2S.exe is placed in your "exits" directory. This program is used to establish shared memory for BlockIP2.
NOTE: The default log path is changed to follow the Unix implementation, so you will now find it in: WebSphere_MQ_Installpath\exits.
You have to upload blockip2.load.mvs and maybe blockip2.obj.mvs and blockip2.c.mvs (containing BlockIP2.c), blockip2.jcl.txt.
I have added the BlockIP2.c in Xmit format ready to upload, without having to deal with the ASCII to EBCDIC conversion, you just upload it to z/OS using this ftp command:
ftp -s:upload.txt hostname (Just remember to change <userid> and <password> to yours before using it, or use another way to upload the file binary to a PS with a fixed record length of 80).
| <userid> <password> bin |
example upload.txt
When you have uploaded blockip2.LOAD.MVS, blockip2.c.mvs and blockip2.obj.mvs you have to issue a receive to get into a usable dataset:
TSO RECEIVE INDATASET(BLOCKIP2.C.MVS)
TSO RECEIVE INDATASET(BLOCKIP2.LOAD.MVS)
TSO RECEIVE INDATASET(BLOCKIP2.OBJ.MVS)
This will give you three PDS with with different formats.
When you successfully have uploaded the stuff, it's time to decide what to use. The delivered load module, the object or compile it your self.
BLOCKIP2.LOAD.MVS contains a ready to use version of the security exit.
Assemble and compile but before you're able to do that
you have to change the JCL to match your installation.
You can use the supplied
JCL in BLOCKIP2.MVSO BUILDJCL for v5.3 or BUILDJC6 for version 6.0 and just
change the libraries to you installation standard. This means that you don't
need to compile the programs just link them.
If you like to compile the whole stuff: first submit blocki2w in BLOCKIP2.OBJ.MVS, to create the WTO routine. When this is done submit blockip2.jcl (please check the link step, should contain the same includes as in BULDJCx). When this is run ok, you should have a working security exit.
On your xxxxCHIN task add a //SYSPRINT DD card to catch output from BlockIP2, and you can add a DD card to handle the configuration file. The link-edited modules must be placed in the data set specified by the CSQXLIB DD statement of the channel initiator address space procedure; the names of the load modules are specified as the exit names in the channel definition.
The exits are invoked as if by an z/OS LINK, in:
I don't distribute (and don't plan to) a z/OS load module due to the complexity of your different implementations, software levels, requirements etc.
You can however upload BlockIP2.c to z/OS using FTP and handle ASCII to EBCDIC conversion like this (just remember to create a dataset named 'MQ.BLOCKIP.C, the a LRECL=255 and RECFM=VB:
| <userid> <password>
|
myftpparm.txt
ftp -s:myftpparm.txt hostname
The trick is done by quote SITE SBDataconn=(IBM-1047,ISO8859-1) which tells z/OS to do the conversion. The codepages IBM-1047 and ISO8859-1 differs depending on where you are located, so talk to you z/OS Unix Systems Service administrator to obtain the correct values in your situation. This conversion can also be used when you download a coded file from z/OS.
Just untar BLOCKIP2.TAR from Linux_x86 subdir in /var/mqm/exits, and you're allmost ready to go.
You will need to change the owner using root authority:
| chown mqm:mqm /var/mqm/exits/BlockIP2 chmod 550 /var/mqm/exits/BlockIP2 |
Just untar BLOCKIP2.TAR from Linux_x86_64 subdir in /var/mqm/exits64, and you're allmost ready to go.
You will need to change the owner using root authority:
| chown mqm:mqm /var/mqm/exits64/BlockIP2 chmod 550 /var/mqm/exits64/BlockIP2 |
Just untar BLOCKIP2.TAR from AIX_60 subdir in /var/mqm/exits64, and you're allmost ready to go.
You will need to change the owner using root authority:
| chown mqm:mqm /var/mqm/exits64/BlockIP2 chmod 550 /var/mqm/exits64/BlockIP2 |
Just untar BLOCKIP2.TAR from SolarisSPARC subdir in /var/mqm/exits64, and you're allmost ready to go.
You will need to change the owner using root authority:
| chown mqm:mqm /var/mqm/exits64/BlockIP2 chmod 550 /var/mqm/exits64/BlockIP2 |
Just untar BLOCKIP2.TAR from Solarisx86 subdir in /var/mqm/exits64, and you're allmost ready to go.
You will need to change the owner using root authority:
| chown mqm:mqm /var/mqm/exits64/BlockIP2 chmod 550 /var/mqm/exits64/BlockIP2 |
You have to compile the exit your self, because I don't have this platform. See the commands here
You specify that WebSphere MQ have to use the security exit by using the SCYEXIT and SCYDATA keywords when defining/altering channels. This could be like this:
ALTER CHANNEL(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*') +
scyexit('BlockIP2(BlockExit)')
This works on Linux, Windows.
If it was on z/OS it would look like this:
ALTER CHANNEL(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*') +
scyexit('BLOCKIP2')
For further information on the commands refer to the MASC. and Intercommunication guides.
As you saw in the introduction, you control the behavior of BlockIP2 using SCYDATA().
You can specify a simple pattern, or use keywords.
The syntax is:
SCYDATA('[NONE|{pattern[;pattern[;pattern...]]][;userids][;flags]}|FN=filename;[flags;]}')
SCYDATA('172.20.*') to allow anybody from the network 172.20.anything to access the queue manager.
Yet another SCYDATA('172.??.10.21') this one allows only connections from 172.10.10.21 172.11.10.21, it requires two digits in second IP byte.
SCYDATA('NONE') is used together with the default BlockIP2.ini configuration file to allow specification without defaults.
| Flag | Description |
| FN= | Name and path to configuration file. |
| NONE | indicate that no additional patters are added when using default configuration file BlockIP2.ini |
| -d | Debugging activated |
| -d0 | Special for debugging of specification file |
| -d1 | Technical debugging |
| -d8 | Development debugging |
| -i | Ignore default configuration file BlockIP2.ini |
| -l | Switch off recycle of logfiles |
| -z | z/OS only: Translate [] to <> on messages |
| -n | Block system accounts: mqm, musr_mqadmin and "" (unspecified)* |
| +b | Allow blank userids (unspecified) to connect. (added in version 2.21)* |
| -w | Use eventlog on Windows or syslog on UNIX |
| -s | Allow self signed certificates |
| -q | quiet mode |
*) NOTE: -n and +b options is only accepted if FN= mode is note used. Use AllowBlankUserID=Y; and/or BlockMqmUsers=Y; in configuration instead.
To enable the debugging you specify:
SCYDATA('172.20.*;-d;')
Using a specification file (the way of specifying the file differs from platform to platform):
On windows:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=c:\path\Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
On Linux:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
On AIX:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
On HP-UX:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec.txt;') +
scyexit('BLOCKIP2')
On SUN/Solaris x86:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
On z/OS:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=//DD:BLOCKDD;') +
scyexit('BLOCKIP2')
Or if you're using a PDS, you can specify the member name as well:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=//DD:BLOCKDD(MEM);') +
scyexit('BLOCKIP2')
Or using a USS file placed in HFS:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec;') +
scyexit('BLOCKIP2')
Now what can we specify in the configuration file??
Following keywords are implemented:
Please note that all keywords are written on a new line, it's not allowed to specify more keywords on the same line! Only the first one is considered as a command, the rest is accepted as a comment.
| Keywords | Description |
| AllowBlankUserID={Y|N}; | Allow blank userids to connect. To Enable this option can lead to security risks. |
| AllowSelfSignedCertificate={Y|N}; | Allow the use of self-signed certificates. This is by default blocked. |
| ASC={Y|N}; | Allow the use of self-signed certificates. This is by default blocked. Short form of "AllowSelfSignedCertificate=" |
| BlockMqmUsers={Y|N}; | Flag to block for system accounts: mqm, musr_mqadmin and '' |
| BlockUsers=<generic_user_list>; | List of negative userids using generic pattern matching |
| CHANNEL=<generic channelname>; | Working with QMGR= to control a combined configuration file. This is used in BlockIP2.ini |
| CON=<conname>;BLANK_USERID|<userids>[;MCA={*|userid}}|BLOCK}]; | Allow manipulation/selection on specified connectionname/userid. This have higher precedence than userid/pattern filtering. BLANK_USERID is added to support some special WAS situations. |
| LogCount=<nn>; | Number of generations of log file. Default is 3 and max is 99. (Windows, AIX, Linux and Solaris only) |
| LOGCYCLE={N|Y}; | Control for logfile switching , default is on |
| LogDrive=<spec>; | The drive there the log file is placed (Windows only) |
| LogExt=<spec>; | extension of log file, default is 'txt' |
| LogFileName=<spec>; | Name of the log file default is 'BlockIP2' |
| LogFormat=<spec>; | N - For name only or ND - Name and Date or NDC - Name Date Channel format NCD - Name Channel Date format or any variation |
| LogPath=<spec>; | The path where the log file is placed. Default is /var/mqm/exits for UNIX. and <install path>\exits for windows. |
| LogSize=<nnnnnnnn>; | Maximum size of log file before switching to next. default is 200KB, min is 100KB. (Windows, AIX, Linux and Solaris only) |
| MAXCHL=<generic_ChannelName>;<numberOfChannels>; | Limit the number of connection to this channel, the number of connections are checked in the INIT phase. |
| Patterns=<generic_connection_list>; | List of positive network connection names using
generic pattern matching
A pattern starting with a-z are treated as a DNS entry, and pattern entries starting with 0-9 are treated as a IP-addr. |
| QMGR=<generic queue manager>; | Working with CHANNEL= to control a combined configuration file. This is used in BlockIP2.ini |
| SSL=[C=<GN>,][L=<GN>,][O=<GN>,][PC=<GN>,][ST=<GN>,][OU=<GN>,]CN=<GN>;...
[{BLOCK|MCA={*|userid|xx(from,len)};] |
fine selection based on the DN, which also allow override of
MCAUSERID and even to blacklist one or more Certificates. You can use any
of these filters in any combination. The only restriction is: Imbedded
blanks are not allowed. Or have a look in the code for more
information.
MCA=xx(from,len) is MCAUSER extactor from SSL DN, works like substr and start in pos 1. |
| SysLog={FILE|ONLY|BOTH]; | Control where output from BlockIP2 are sent. (UNIX ONLY) |
| SYSLOGFCLTY={LOG_DAEMON|LOG_USER]; | Control which message file BlockIP2 uses for reporting. (UNIX ONLY) |
| SYSLOGPRTY={LOG_INFO|LOG_ERR|LOG_NOTICE|LOG_WARNING]; | Control the "priority" of BlockIP2 messages. (UNIX ONLY) |
| TERM={Y|N}; | controlling print of a termination message, including the connection name. |
| Userids=<generic_user_list>; | List of positive userids using generic pattern matching |
| UseridUpperLowerCase=*; | Swift off case sensitivity, fold any matching to uppercase. |
| WinLog=[FILE|ONLY|BOTH]; | Control where output from BlockIP2 are sent. (Windows ONLY) |
| WTOPFX=<prefix>; | Prefix for WTO messages, default is BLOCKIP-. Max length 20 characters (z/OS only) |
| UseridUpperLowerCase=*; | Swift off case sensitivity, fold any matching to uppercase. |
Patterns=, Users= and BlockUsers= offers concatenation functionality.
This allows file content like:
Patterns=1.2.3.4,1.2.3.5,1.2.3.6; /* hosts 4,5,6 in the 1.2.3 network */
Patterns=1.2.1.4,1.2.1.5,1.2.1.6; /* hosts 4,5,6 in the 1.2.1 network */
and any of the six addresses will be allowed. this can also be specified as:
Patterns=1.2.3.[4-6],1.2.1.[4-6];
Patterns=mrmqdk01.mrmq.dk,mrmqdk02.mrmq.dk,spyder,10.31.*;
Will cause BlockIP2 to look the 3 hostnames up and use the returned IP address
in matching the connection name. You cannot use a generic hostname
like *.mrmq.dk
Specifying pattern rules are described in details here
There is limit on 4096 characters maximum length on Patterns, Users, BlockUsers.
There are room for 256 SSL patterns and 64 CON patterns. This limits can easily elevated, but it require more memory. The memory obtained by BlockIP2 remains allocated until the connection is terminated, therefore have I decided to set some limitation on.
To use multipattern: just seperate the patterns with a semicolon(;) like
this:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.109.*;172.221.*;10.31.*') +
scyexit('BlockIP2(BlockExit)') *
This will allow communication from any computer in the 172.20.109.*,
172.221.* and 10.31.* networks.
You can also use a single position placeholder in the pattern:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('192.168.??.20;10.31.*') +
scyexit('BlockIP2(BlockExit)')
This will allow any IP-addr matching 192.168.10.20, 192.168.11.20..
192.168.99.20 and 10.31.* to pass verification.
How to block bad userids (mqm, musr_mqadmin and ''), this is done using the switch -n in SCYDATA. When the RemoteUserIdentifier of an incoming connection request contains one of the listed users above BlockIP2 sends MQXCC_SUPPRESS_FUNCTION so the communication attempt is abandoned.
BlockIP2 have been updated in SCYDATA like this:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*;10.31.*;-n') +
scyexit('BlockIP2(BlockExit)')
A allow blank userid (unknown) to connect, this is done with the +b option.
alt chl(JMSCHL_SPY) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*;+b') +
scyexit('BlockIP2(BlockExit)')
A quiet mode option have been added, so there will be only one line per
connection attempt in the log. This is done with the -q option.
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*;-q') +
scyexit('BlockIP2(BlockExit)')
A debug option is added, to allow a more comprehensive logging of the
activity inside BlockIP2. This done with the -d option.
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('172.20.10.*;172.221.*;-d') +
scyexit('BlockIP2(BlockExit)')
BlockIP2 is able to obtain the security specification from a file. This
feature was added to circumvent the 32 byte limitation in SCYDATA, and was
requested from complex installations.
The filename is specified in SCYDATA like this on windows:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=c:\path..\Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
or like this on Linux and the rest of Unix impl.:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=/var/mqm/exits/Blockspec.txt;') +
scyexit('BlockIP2(BlockExit)')
or like this on z/OS:
alt chl(MQT2.TCP.MQT1) chltype(SVRCONN) +
SCYDATA('FN=DD:BLOCKDD;') +
scyexit('BLOCKIP2')
NB: The FN=<filename>; requires the ending semicolon(;).
Here is a simple commented specification
| # This is a comment BlockIP2 security specification
Blockspec.txt Patterns=10.1.*,172.20.31.*,127.0.?.1; Userids=xxx,yyy,zzz*,etc,mrmq,root,us???mq; BlockMqmUsers=Y; #----------------------------------------------------------------- # Description of security specification: # This specification will allow: # - connections from 10.1.*, 172.20.31, and 127.0.0.1, 127.0.1.1, ... 127.0.9.1 # Networks. Entries are separated using comma(,) # - allow userids: xxx, yyy, etc, mqm and mrmq. Together with users # starting with zzz<something> and users beginning with us<three chars>mq. # # - BlockMqmUsers=Y; means that following users are blocked: mqm, # MUSR_MQADMIN and musr_mqadmin. # All specs must end with a semicolon ; anything after ; is parsed as a comment # Important: # If you specify Patterns twice they are concatenated, so they are all used # for matching. # # It's very important that all specs are terminated with semicolon(;) otherwise # you will receive connection refused. Because I think it's best only to use # positive error-free identification # The patterns are separated using comma(,) This is also important to remember |
BlockIP2 is able to change MCAUSER depending on the incoming connection credentials.
| # This is a comment BlockIP34.txt Patterns=10.1.*,10.1.11.*,user1.mrmq.dk,127.0.?.1; SSL=CN=ibmwebspheremqclient2;MCA=mrmq; ok userid SSL=CN=ibmwebspheremqQM2;BLOCK; blocked user SSL=CN=ibmwebspheremq*;MCA=*; just do nothing SSL=CN=*;MCA=NoBody; Set all other to NoBody # EOF |
The connection may come from: 10.1.*,10.1.11.*,user1.mrmq.dk,127.0.?.1 (Yes the user1 one is found using the DNS). This means that it supports the use of DHCP....
In the example above will connections with a CN=ibmwebspheremqclient2 get the MCAUSER=mrmq.
Connections from CN=ibmwebspheremqQM2 will be refused all other connections from CN=ibmwebspheremq* will use the normal userid (or MCAUSER if specified on the channel).
Connections made with CN=<anything> will have the MCAUSER=NoBody, which should be no defined. (Could also be SSL=CN=*;BLOCK; have the same function when user NoBody is undefined)
The newest enhancement in BlockIP2 is the enhanced MCAUSER extraction freature that allows BlockIP2 to assign a part of the partners DN to the MCAUSER. This gives you the flexibility to have many users shareing the same SSL= filtering schema, and the assign the authority based on their own certificates. imbedded blanks in the names are removed using truncation, meaning that a name like 'h c andersen' will be 'hcandersen', please note that the current implementation are doing the truncation after the substring. This might get changed in the future. Have a look here: Considered changes in the near future.
Syntax is:
SSL=O=mrmq,MCA=CN(1,8); will extract the first eight characters from CN
and use as MCAUSER. The MCA=xx(from,len) recognizes the used prefixes in the SSL
certificate.
Let's see the result:
| # This example should describe the "substring"
like functionality in the SSL/MCAUSER logic. Patterns=10.1.*; SSL=O=mrmq;MCA=CN(1,8); set mcauser to the Common name pos 1 thru 8. SSL=O=acme;MCA=L(1,4); set MCAUSER to location pos 1 thru 4. SSL=CN=*;BLOCK; Block the rest # EOF |
Here is a couple of DN, and with the rules above it should illustrate the way it work.
DN=CN=jones carin,O=mrmq,C=dk,L=copenhagen gives MCAUSER=jonesca
DN=CN=smith john,O=mrmq,C=dk,L=esbjerg gives MCAUSER=smithjo
DN=CN=bond james,O=acme,L=houston,C=US gives MCAUSER=hous
DN=CN=johnes john,O=acme,L=berlin,C=DE gives MCAUSER=berl
And certificates from anyone else will get refued by the SSL=CN=*;BLOCK;
Here is an commented example using CON= (not from the real world), but still informative:
| # # Simple filter implemented in BlockIP2 version 2.20 # # 1. stop all connection attempts from mqm (NoBody is an undefined or blocked userid). CON=*;mqm;MCA=NoBody; # # 2. Stop users starting with dk14 from 10.31.* Might be a foreign network CON=10.31.*;dk14*;MCA=NoBody; # # 3. Allow master03 when coming from 172.20.10.31 CON=172.20.10.31;master03; # # 4. Allow spider when coming from 10.*, and set MCAUSER to master04 CON=10.*;spider;MCA=master04; # # 5. Block all other attempts. CON=*;*;MCA=NoBody; # # Control the number of connections: # # Establish a default max connection count of 5 MAXCHL=*;5; # # Specific channel limitations MAXCHL=SYSTEM.DEF.SVRCONN;25; MAXCHL=SYSTEM.ADMIN.SVRCONN;25; MAXCHL=SYSTEM.AUTO.SVRCONN;25; |
The list is searched from top to bottom, and when BlockIP2 detects a match on connection-id and userid, this means that it's important to specify the rules in the right order.
Caution: Using both SSL and CON keywords in the same specification file, should be done with great caution, because the SSL have precedence over CON. You might see that a MCA change caused by CON, can affect a SSL setting without MCA settings.
Making use of hostnames:
BlockIP2 support DNS lookup of hostnames, this makes it easier to control patterns and also support filtering of users using dynamic ip addresses.
|
# #Allow connection from theBoss, 10.3.* and anything from 11.* ending on ".12" Patterns=theBoss,10.3.*,11.*.12; # # Grant userid mrmq connecting from theBoss the MCA user mqm: # CON=theBoss;mrmq;MCA=mqm; # # Grant anybody else access using MCA=user: # CON=*;*;MCA=user; # # |
Here is an commented example using MAXCHL= (not from the real world), but still informative:
|
# # Control the number of connections: # # Establish a default max connection count of 5 MAXCHL=*;5; # # Specific channel limitations MAXCHL=SYSTEM.DEF.SVRCONN;25; Allow 25 connections here MAXCHL=SYSTEM.ADMIN.SVRCONN;25; Allow 25 connections here MAXCHL=SYSTEM.AUTO.SVRCONN;25; Allow 25 connections here |
This feature implemented using shared memory on UNIX, Linux and z/OS. On windows it's implemented using "Display Channel Status" and a local queue: SYSTEM.ADMIN.BIP2.QUEUE.
You create the control queue like this:
DEFINE QL('SYSTEM.ADMIN.BIP2.QUEUE') defperst(NO) maxqdepth(500) replace +
DESCR('Blockip2 control queue')
The MAXCHL= table is processed sequential, and all matches are processed, this means that the last match have higher priority than the first one. Therefore should you place the default value as the first entry, and place specific entries after it.
BlockIP2 rely on /var/mqm/qmgrs/QMGR/shmem/BlockIP2.1 and /var/mqm/qmgrs/QMGR/shmem/BlockIP2.2 for pointing out the shared memory segment in the UNIX implementation. The determination follows mqs.ini/qm.ini.
You are able to use a single configuration file to control any combination of queue managers and channels. The only limitations are simplicity. My recommendation is: Keep it simple because this makes you have control over the configuration and makes it easy to maintain.
An example: This file is default loaded from the queue managers exit path (BlockIP2 will not choose exits64). The file is named BlockIP2.ini and is case sensetive for some implementations.
|
# Simple filter implemented in BlockIP2 version 2.60 # Copyright (c) 2007 M-Invent, All rights reserved. # # # First some global settings: QMGR=*; CHANNEL=*; # BlockMqmUsers=Y; # # Specific channel limitations MAXCHL=SYSTEM.DEF.SVRCONN;25; MAXCHL=SYSTEM.ADMIN.SVRCONN;25; MAXCHL=SYSTEM.AUTO.SVRCONN;25; # # 1. stop all connection attempts from mqm (NoBody is an undefined or blocked userid). CON=*;mqm;MCA=NoBody; Could also be: CON=*;mqm;BLOCK; # # Now we will play with the SATURN queue manager and the system channels QMGR=SATURN; CHANNEL=SYSTEM.*; # 2. We don't like peter and we have frank as administrator from 10.31.* BlockUsers=peter; CON=10.31.*;frank;MCA=mqm; # # we are still playing with the SATURN queue manager but now it's SATURN.INPUT* channels CHANNEL=SATURN.INPUT*; # 3. Allow communication from 10.31.14.11 and 10.32.14.11 with user dku12345 CON=10.3[1-2].14.11;dku12345; # # Now we will play with the MARS queue manager and the system channels QMGR=MARS; CHANNEL=SYSTEM.*; # 4. We don't like deu98765 and we have "frank" as administrator from 10.31.* BlockUsers=deu98765; CON=10.31.*;frank;MCA=mqm; # # Now we will play with the VENUS queue manager and the system channels QMGR=VENUS; CHANNEL=SYSTEM.*; # 5. We have "donna" as administrator from 172.20.14.11 CON=172.20.14.11;donna;MCA=donnaadmin; # # Close the last hole in case a channel is unprotected. This is the last check... QMGR=*; CHANNEL=*; # 6. Block any non accepted connection attempts. CON=*;*;BLOCK; # # Please remember that the configuration file is processed from the top and down. # The CON/SSL check is stopped on first match, this means that placing the stage 6. on top # would block any connect attempt.. And by placing it last it last it will block connect attempts # on non-protected channels. # # |
The default locations are:
UNIX/Linux/Solaris/HP-UX:
/var/mqm/exits/BlockIP2.ini
Windows:
c:\program files\IBM\Websphere MQ\Exits\BlockIP2.ini
The file location is found based on mqs.ini/qm.ini or registry settings, to allow more default configuration files on server hosting more queue managers.
| Special character | Rule description |
| * | Any number of characters towards end of spec |
| ? | Any character in this position |
| # | Any numeric (0-9) character in this position |
| $ | Any alphabetic character a-z and A-Z |
| (0-4) (c-j) (A-z) | Any alphanumeric character in the specified range (Added for European z/os systems) |
| [0-4] [c-j] [A-z] | Any alphanumeric character in the specified range |
Remark: The range selection is based on the character value, this means that there are a huge difference between z/OS, AS/400 and the other platforms because z/OS and AS/400 are using EBCDIC and the rest are using ASCII, this means that [0-z] will allow any character on Linux, but is a bad specification on z/OS. There are currently (v.2.21) added a z/OS limitation that are blocking for mixing numbers and letters in a range spec.
Here are some examples of how to specify various patterns :
| # # Simple filter implemented in BlockIP2 version 2.21 # # 1. using range in connection name # This statement allow connections from connection names that are starting with 10.1 having 2-5 in pos 5, having 0-9 in 7'th # position and anything in the last group (0-255). This also means that you can't get in from 10.12.10.11 ... # Net we're going to look on the userid, it must start with the 'us' and 6 digits, like us0234237, and you'll not be able to # connect if you user id us02345 (one digit too short. CON=10.1[2-5].#.*;us######;MCA=american; # # 2. using alphabetic filter in userid # This statement allows connections from 172.20.10.21 only, But the userid have to start with the letters 'gb' followed by # three letters and ending with two zeroes '00'. This means that the userids would look like: gbabb00, gbwho00. # And gbilo44 is not allowed. CON=172.20.10.21;gb$$$00;MCA=uksys; # # 3. using range in userid # This statement allows connections from 172.20.*, But the userid have to start with the letter 'd' followed by a letter # in the range from 'a' thru 'd' followed by '00' and a letter in the range 'w' thru 'z'. This means that the userids would look # like: da00w, dd00z. And de00a is not allowed. CON=172.20.*;d(a-d)00(w-z);MCA=agent007; # # 4. using a host name in the filter CON=server1.mrmq.dk;mrmq; # # 5. Block all other attempts. CON=*;*;BLOCK; # |
LogFormat offers you the ability to generate various logfiles, based on date, channelname, name.
Options available:
LogFormat=
N - For name only or
ND - Name and Date or
NDC - Name Date Channel format
NCD - Name Channel Date format or any variation
This option gives you the ability to generate a new file each day, which makes it easy to investigate who did what on a certain time.
WARNING: Don't use this option on z/OS
Example of the log: <will be replaced with current>
|
04.01.20 00:11:04 BlockIP2: BlockExit
ver=1.112 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7 |
I've included the used compilation commands and option I use for building the exits. This should help you if you have another need for own compilation. For further information about how to compile please take a look in the WebSphere MQ Intercommunication manual. There is a chapter about compiling for various platforms here. This is for WebSphere MQ version 6.0.
AIX and MQ version 6.0 or 7.0:
xlc_r -q64 -e MQStart -bE:BlockIP2.exp -o BlockIP2 BlockIP2.c
-I/usr/mqm/inc -D_REENTRANT -DUNIX -DHNLUP -DAIX
cp ./BlockIP2 /var/mqm/exits64/.
chgrp mqm /var/mqm/exits64/BlockIP2
chmod 750 /var/mqm/exits64/BlockIP2
Solaris_x86 and MQ version 6.0 or 7.0:
gcc -c -m64 BlockIP2.c -ansi -fPIC -DUNIX -DSOLARIS -D_REENTRANT
-DHNLUP -I/opt/mqm/inc -Wall
/usr/ccs/bin/amd64/ld -64 -mt -G -o BlockIP2 BlockIP2.o -R/usr/lib/64 -lsocket -lnsl
-ldl
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits64
chown mqm /var/mqm/exits64/BlockIP2
Solaris SPARC and MQ version 6.0 or 7.0 using gcc:
gcc -I/opt/mqm/inc -m64 -o BlockIP2 BlockIP2.c -G -m64 -L
/usr/lib/64 -lthread -lsocket -lc -lnsl -ldl
-DUNIX -DSOLARIS -D_REENTRANT -DHNLUP
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits64
chown mqm /var/mqm/exits64/BlockIP2
Solaris SPARC and MQ version 6.0 or 7.0 using cc:
cc -xarch=v9 -xcode=abs64 -mt -G -o /var/mqm/exits64/BlockIP2 BlockIP2.c
-I/opt/mqm/inc -R/usr/lib/64 -lsocket -lnsl -ldl -DUNIX -DSOLARIS -D_REENTRANT -DHNLUP
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits64
chown mqm /var/mqm/exits64/BlockIP2
Linux86_x64 and MQ version 6.0 or 7.0:
gcc -m64 -o BlockIP2 BlockIP2.c -fPIC -ansi -shared -D_REENTRANT -D UNIX
-D_XOPEN_SOURCE -DHNLUP -Wall
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits64
chown mqm:mqm /var/mqm/exits64/BlockIP2
Linux86 and MQ version 6.0 or 7.0:
gcc -o BlockIP2 BlockIP2.c -fPIC -ansi -shared -D_REENTRANT -D UNIX
-D_XOPEN_SOURCE -DHNLUP -Wall
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits
chown mqm:mqm /var/mqm/exits/BlockIP2
HP-UX and MQ version 6.0:
c89 +DD64 +z -c -D_HPUX_SOURCE -o BlockIP2.o BlockIP2.c -I/opt/mqm/inc
ld -b +noenvvar BlockIP2.o +ee MQStart +ee BlockExit -o BlockIP2 -L/opt/mqm/lib64
-L/usr/lib/pa20_64 -lmqm_r -lpthread
chown mqm:mqm BlockIP2
/bin/cp BlockIP2 /var/mqm/exits64
chown mqm:mqm /var/mqm/exits64/BlockIP2
z/os and MQ version 5.3.1 or 6.0:
To be filled in.
z/Linux and MQ version 6.0:
To be filled in.
Windows and MQ version 6.0:
To be filled in.
OS/400:
CRTSRVPGM SRVPGM(BLOCKIP2) EXPORT(*ALL)
BNDSRVPGM(LIBMQM_R)
In the z/OS version of the exit have we added the following message id's to help automation, and troubleshooting, and make documentation a bit easier
| Message-id | Description |
| BLOCKIP-50I | Verification successful, connection accepted |
| BLOCKIP-51I | Verification successful, SSL have changes the userid, connection accepted |
| BLOCKIP-01E | Errors in SCYDATA specification. The specification don't match the required format. Check that SCYDATA() starts with 'FN=' or a valid pattern. |
| BLOCKIP-02E | Errors found in parameter file, check the extended error description |
| BLOCKIP-03E | Connection refused, User was found in the negative list. |
| BLOCKIP-04E | Connection refused, User was not found in positive list. |
| BLOCKIP-05E | Connection refused, ConName and User was not accepted in CON= specification |
| BLOCKIP-06E | Connection refused, The SSLPeer requested by CheckSSLList() was not successful |
| BLOCKIP-07E | Connection refused, for pattern [] user [] |
| BLOCKIP-08E | Connection refused, SSLPeerName too long max [] was [] |
| BLOCKIP-09E | Connection refused, CN requested blocked |
| BLOCKIP-10E | Connection refused for blank user identifier |
| BLOCKIP-11E | Connection refused for system user identifier (mqm) |
| BLOCKIP-12E | Connection refused for system user identifier (MUSR_MQMADM) |
| BLOCKIP-13E | Connection refused for system user identifier(musr_mqmadm) |
| BLOCKIP-14E | Connection refused, Pattern string is too long, max[] was [] |
| BLOCKIP-15E | Connection refused, Users string is too long, max[], was [] |
| BLOCKIP-16E | Connection refused, CON Spec string is too long, max [], was [] |
| BLOCKIP-17E | Connection refused, SSL Spec string is too long, max[], was [] |
| BLOCKIP-18E | Connection refused, BlockUsers string is too long, max[], was [] |
| BLOCKIP-19E | Error - Unknown Tag [] |
| BLOCKIP-20E | Connection refused, invalid file name pattern specified: FN=<filename...>; [] |
| BLOCKIP-21E | Connection refused, Specified file [] was not found |
| BLOCKIP-22E | Connection refused, Users string is too long, max[], was [] |
| BLOCKIP-24E | Connection refused for system user identifier (QMQM) |
| BLOCKIP-25E | Connection refused for system user identifier(CHIN task). |
| BLOCKIP-30E | Connection refused, Required ClientExit missing |
| BLOCKIP-31E | Connection refused, Wrong credentials supplied. |
| BLOCKIP-32E | Connection refused, Maximum number of channels was exceeded. |
| BLOCKIP-33E | Connection refused, number of SSL exceeds [] |
| BLOCKIP-45E | Connection refused, Self signed Certificates is not allowed. Certificate was issued by [] |
| BLOCKIP-46E | Connection refused, Self signed Certificates filtering is not supported in pre version 6.0 |
| BLOCKIP-68E | Connection refused, CON Too many CON= specs active. Max [] |
| BLOCKIP-99E | wildcmp don't support mixed patterns yet. (0-J) |
| BLOCKIP-99E | No Matching SSL settings found for certificate: [] |
| BLOCKIP-99E | Connection refused, LOGCYCLE= invalid [%s]. Legal arguments are Y or N |
| BLOCKIP-99E | Connection refused, LOGCYCLE= semicolon(;) is missing |
| BLOCKIP-99E | Configuration queue is invalid [] name too long(). max |
SSL/MCAUSER logic: suppression of special like '\', ',', ' ' some other characters before the "substring" are resolved.
Another SSL/MCAUSER enhancement could be adding a character prefix like MCA="acme"+L(1,4); or to do it twice like this
MCA=O(1,4)+L(1,4); to take the first 4 character of the organization and the first four of the location.
Release of a shared memory tool, to reset the shared memory in case of problems.
The following are trademarks of
International Business Machines Corporation:
IBM, MERVA, MQSeries, WebSphere, WBIFN, Object REXX, AIX, z/OS