BlockIP2 The manual

Further input/tips is appreciated. Feel free to drop us a email.


Quick Links

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


Foreword

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. 

Top of page


End User Agreement

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.

Top of page


News

Support for WebSphere MQ version 5.3 is withdrawn.

BlockIP2 works fine with WebSphere MQ version 7.0

Top of page


Installation

When you have downloaded the BlockIP2.zip and unpacked the files it's time to install the Exit. 

Windows 2000/2003/XP

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.

 

z/OS

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
quote SITE recfm=fb lrecl=80 blksize=8000
put blockip2.c.mvs

put blockip2.load.mvs
put blockip2.obj.mvs
ascii
quit

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>


cd 'MQ.BLOCKIP.C'
quote SITE SBDataconn=(IBM-1047,ISO8859-1)
put blockip2.c
quit

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.

 

Linux (Intel 32 bit)

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 

 

Linux (Intel 64 bit)

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 

 

AIX MQ 6.0

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 

 

Sun/Solaris SPARC

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 

 

Sun/Solaris (x86_64)

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 

 

HP-UX

You have to compile the exit your self, because I don't have this platform. See the commands here

Top of page


Activation

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.

Top of page


Configuration

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;]}')

A simple filtering

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.

 

Flags implemented

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??

Top of page


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.

Top of page


Configuration examples

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)') 

WARNING: Using this option is causing a security hole, so anybody using a java application or a security client exit to connect to the queue manager and get up to mqm authority.


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)


Enhanced SSL

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.

Top of page


Single configuration file for multi channels/queue managers

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. 

Top of page


Specifying patterns

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;
#

 

Top of page


Using LogFormat

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

Top of page


Logfile example

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
04.01.20 00:11:04 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="mrmq"
04.01.20 00:11:04 BlockIP2: ConName"127.0.0.1" Pattern "127.0.0.*;172.221.*;10.31.*;" Flags"-n ".
04.01.20 00:11:04 BlockIP2: BlockExit Connection accepted for pattern 127.0.0.* .
04.01.20 00:11:28 BlockIP2: BlockExit ver=1.112 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7
04.01.20 00:11:28 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL3" ConnectionName="127.0.0.1" Userid="mrmq"
04.01.20 00:11:28 BlockIP2: ConName"127.0.0.1" Pattern "127.0.0.2" Flags"".
04.01.20 00:11:28 BlockIP2: BlockExit Connection refused.
04.01.20 00:15:33 BlockIP2: BlockExit ver=1.112 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7
04.01.20 00:15:33 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="musr_mqadmin"
04.01.20 00:15:33 BlockIP2: BlockExit Connection refused for system user identifier.-3
04.01.20 00:16:23 BlockIP2: BlockExit ver=1.112 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7
04.01.20 00:16:23 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid=""
04.01.20 00:16:23 BlockIP2: BlockExit Connection refused for blank user identifier.
04.01.22 23:22:45 BlockIP2: BlockExit ver=1.12 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7
04.01.22 23:22:45 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="JHP" ConnectionName="127.0.0.1" Userid="root"
04.01.22 23:22:45 BlockIP2: ConName"127.0.0.1" Pattern "128*" Flags "".
04.01.22 23:22:45 BlockIP2: BlockExit Connection refused for Conname 127.0.0.1 .
04.01.22 23:23:07 BlockIP2: BlockExit ver=1.12 env=non-MVS ExitId=11 ExitReason=16 ChannelType=7
04.01.22 23:23:07 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="root"
04.01.22 23:23:07 BlockIP2: ConName"127.0.0.1" Pattern "128*;127.*;" Flags "-n".
04.01.22 23:23:07 BlockIP2: BlockExit Connection accepted for pattern 127.* .
04.02.15 09:07:17 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="root"
04.02.15 09:07:17 BlockIP2: BlockExit Connection refused, invalid file name pattern specified: FN=<filename...>; "FN=/var/mqm/exit/blockip2.txt " .04.02.15 09:08:08 BlockIP2: BlockExit QMgr="QSJHPT99" ChannelName="JHP" ConnectionName="127.0.0.1" Userid="root"
04.02.15 09:08:08 BlockIP2: BlockExit Connection refused, Specified file "/var/mqm/exit/blockip2.txt" was not found.
04.02.15 09:09:57 BlockIP2: BlockExit QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="root"
04.02.15 09:09:57 BlockIP2: BlockExit Connection refused, user don't match positive list xxx,yyy,zzz*,etc,mrmq,us???mq .
04.02.15 09:15:06 BlockIP2: BlockExit ConName "127.0.0.1" Pattern "10.1.*;10.1.11.*;etc;127.0.?.1" Flags "BlockMqmUsers=Y" users "xxx,yyy,zzz*,etc,mrmq,root,us???mq".
04.02.15 09:15:06 BlockIP2: BlockExit Connection accepted QMgr="QSJHPT01" ChannelName="CHANNEL2" ConnectionName="127.0.0.1" Userid="root"

Top of page


Compilation

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)

Top of page


Messages

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 

Top of page


Considered changes in the near future

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.

Top of page


The following are trademarks of International Business Machines Corporation:
IBM, MERVA, MQSeries, WebSphere, WBIFN, Object REXX, AIX, z/OS

Copyright © 2002, 2009 MrMQ.dk formerly(M-Invent). All rights are reserved.
Last updated: 2009.07.11.