I thought I would complete the work I did with using JMX in the mqweb server. It was another example of Hofstadter’s Law:
It always takes longer than you expect, even when you take into account Hofstadter’s Law.
I spent a lot of time looking for things on the web, expecting them to be obvious, only to find that the things do not behave as expected. I could not find them, because they were not there. For example I expected to be able to configure the JMX server to use my OS userid and password. I could have a file with userids and passwords, or lookup in LDAP, but not my normal userid.
I found there are two ways of getting the JMX data from the mqweb server.
- Use of the native JMX support
- Using the Liberty REST API
I think the REST API is easier to set up and is more secure.
I’ll document a high level overview of the two approaches, and how to configure them
- Use the Liberty REST API to access the JMX data in Liberty
- Setting up Liberty(as used in mqweb) to use native JMX
Overview of using the native JMX support.
To use this, you configure parameters in the jvm.options file, including a port solely for JMX.
You can use TLS certificates to set up a secure link between the client and the server.
You can decide if you want to logon with userid and password. If you do you can set up
- A file with userids and passwords; and a file with userids and permitted access. The documentation talks about userids like monitorRole and controlRole. You have to put a process in place to periodically change these passwords.
- Use and LDAP server to do userid validation and to get the access.
- I could not find how to use your operating system userid and password for authentication.
- I could not find how to use the DN as authorization.
If your certificate is valid (either because it is signed by a CA, or there is a copy of a self signed certificate in the trust store), this is good enough for the checking. You can enable userid and password checking, but this solution feels weak, as you have to do extra work to manage it properly; you do not have a single signon. Not all tools support using userid and password, for example I could not pass userid and password on the jconsole command.
Overview of Using the Liberty REST API
As with the MQ REST API you can issue an HTTP request and get data back. See here. For example
curl –cacert ./cacert.pem –cert-type P12 –cert colinpaice.p12:password https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere:name=com.ibm.mq.console.javax.ws.rs.core.Application,type=ServletStats/attributes=*
There is a small amount of configuration you need to do – less than with the native JMX support. The data comes back as JSON (as you might expect) and also includes a time stamp, which is very useful when post processing.
You define <administrator-role><user>..</user></administrator-role> in a similar way to setting up authorisation for mqconsole and mqrest. It takes the cn= value from your certificate as the userid, so you can give individual access.
“Securely” is a good laugh.
There are different levels of (in)security.
If you are using the native JMX support
- You can have no passwords or access checks needed. The data is read only, and is not sensitive.
- You can set up userid(s) and passwords in a file
- You cannot use the operating system userid and password
- You can use LDAP to check the userid and password, and get the role for that userid
- You can use TLS, so anyone with a valid certificate can access the data
- You can use TLS and use the userid and password in a file to determine access
- You can use TLS and LDAP to get the role for that certificate
If you are using the WLP REST support
- You can specify a userid and password
- You can use a certificate, and the Common Name is used as the userid
- You can specify in the configuration file, what access userids, or groups have
You can use TLS to protect your communications to and from the server.
Java leaks passwords
You need to be aware that your client machine may leak information. For example I ran a Java program to issue JMX requests from a script.
I could use the linux command ps -ef to display information about my request
ps -ef |grep JMX
colinpa+ 1871 1870 79 10:27 pts/2 00:00:01 java … -Djavax.net.ssl.keyStore=/home/colinpaice/ssl/ssl2/colinpaice.p12 -Djavax.net.ssl.keyStorePassword=password … -username monitorRole -password password …
This exposed the password to my keystore and password to my userid! I could not find a way of having all these java system parameters in a file.
I found export JAVA_TOOL_OPTIONS=”-D…” and this get picked up, but then java displays the variables as in Picked up JAVA_TOOL_OPTIONS: …
Some programs have been designed to protect information for example jconsole you can put your system properties in a file
and so keep your parameters secure, but I could not get this to work.
Curl can be configured not to display parameters
With curl you have a command like
curl -n –cacert ./cacert.pem –cert-type P12 –cert colinpaice.p12:password
which gives away your password. If you do not specify it inline, you get prompted for it.
You can put your parameters in a config file, for example curl.config,
cacert ./cacert.pem cert ./colinpaice.pem:password key colinpaice.key.pem cookie cookie.jar.txt cookie-jar cookie.jar.txt url https://127.0.0.1:9443/ibmmq/rest/v1/login
curl –config curl.config
Protecting key files
It is important to protect the certificate file (with the important private key) so it is accessible by just the owner. The linux command ls -ltr colinpaice.p12 gives
-rw------- 1 colinpaice colinpaice 4146 Jan 31 17:56 colinpaice.p12
Of course anyone with super user authority has access to this file!