Connect to JMX(MBeans) on Tomcat behind a firewall

I recently had to configure a Tomcat to allow remote access to the JMX service. It involved some configuration to get a connection through the firewall so I’ve made a configuration-guide for those interested.

Using tools like VisualVM or JConsole can tell you a lot about how your application is performing. A typical use case could be monitoring the CPU and memory load or gather information about the running threads. Some more advanced features include reading and manipulating data by calling MBeans .

The idea is to use the JMX api to connect to MBeans on a remote Tomcat. Connecting to a local Tomcat takes no effort at all. Just start your Tomcat, open VisualVM, and click on the local application you wish to monitor. Connecting to a remote Tomcat requires some additional configuration.

What’s the problem ?

JMX allows you to specify a server port by using the com.sun.management.jmxremote.port system-property. Access to this port allows the JMX-Client to connect to the RMI-registry where the client may find the location of the RMI-server. The problem is that the RMI-server is assigned a random port which will probably be blocked if you are behind a firewall !

Oracle recommends to create your own RMI connector server programmatically in order to specify a specific port. Luckily the Tomcat team created a JMX Remote LifeCycle Listener to do the job for us.

Step by step solution:

In the Tomcat binary distribution download location you will find a folder named (version)/bin/extras with the file catalina-jmx-remote.jar. Copy this jar to the lib folder of your Tomcat installation.

Edit the server.xml in the conf folder of the Tomcat installation to include the new Listener:

1
2
3
4
5
<Listener
className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="9090"
rmiServerPortPlatform="9191"
/>

In this example the registry will be located on port 9090, the rmi-server will be accessible on 9191

Create 2 new files in the same conf directory: jmxremote.password and jmxremote.access
file jmxremote.password, contains users and passwords

1
2
admin adminpassword

file jmxremote.access, specifies the authorizations for users
1
2
admin readwrite

Add the following system-properties to your Tomcat startup-script, or your environment:
1
2
3
4
-Dcom.sun.management.jmxremote.password.file=$TOMCAT_ROOT/conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=$TOMCAT_ROOT/conf/jmxremote.access
-Dcom.sun.management.jmxremote.ssl=false

And finally don’t forget to open the two specified ports (in our example 9090 and 9191) on your firewall, in a Linux environment with Iptables you can use the following configuration:
1
2
3
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 9090 -m state --state NEW -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 9191 -m state --state NEW -j ACCEPT

Now you can connect with your favorite JMX client by using the url:
1
2
service:jmx:rmi://[SERVER_IP]:9191/jndi/rmi://[SERVER_IP]:9090/jmxrmi