Tomcat JMX


JMX allows you to monitor your Tomcat health remotely. You'll be able to see the JVM status, threads and so on.


Although it's really useful, especially on production environment, it's also a big security risk!

If you choose to use it you must, at least:

  • Restrict access by login / password
  • Protect the JMX INPUT port with source IP @ filtering.


Requirements

You must have a working Tomcat installation


Restricted access configuration

Protect the JMX access by login / password.


JMX user logins

# Package installation
vim /var/lib/tomcat7/conf/jmxremote.access

# Manual installation, adjust your Tomcat instance
vim /opt/tomcat-base/conf/jmxremote.access


Put the following

monitorRole readonly
controlRole readwrite

→ replace monitorRole and controlRole by your myUserNames


JMX user passwords

# Package installation
vim /var/lib/tomcat7/conf/jmxremote.password

# Manual installation, adjust your Tomcat instance
vim /opt/tomcat-base/conf/jmxremote.access


Put the following

monitorRole myCrazyPassword1
controlRole myCrazyPassword2

→ replace monitorRole and controlRole by your myUserNames, as you did earlier


File rights

Set rights and permissions upon login files

# Package installation
chmod 600 /var/lib/tomcat7/conf/jmxremote.*
chown tomcat7:tomcat7 /var/lib/tomcat7/conf/jmxremote.*

# Manual installation, adjust your Tomcat instance
chmod 600 /opt/tomcat-base/conf/jmxremote.*
chown tomcat8:tomcat /opt/tomcat-base/conf/jmxremote.*


Start/stop script configuration

You need to edit your Tomcat launcher:

# Package installation
vim /etc/default/tomcat7

# Manual installation, adjust your Tomcat instance
vim /etc/init.d/tomcat8


Add the following lines:

# JMX configuration
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.port=8090"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.ssl=false"
JAVA_OPTS="${JAVA_OPTS} -Djava.rmi.server.hostname=preprodrtd.vehco.com"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.authenticate=true"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.access.file=/var/lib/tomcat7/conf/jmxremote.access"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.password.file=/var/lib/tomcat7/conf/jmxremote.password"

!! Notes:

  • The rmi.server.hostname must match /etc/hostname
  • You can change the JMX remote port
  • The com.sun.management.jmxremote.access.file must match your Tomcat instance


Apply changes

Restart tomcat

service tomcat7 restart


Firewall

Edit your firewall script

vim /etc/firewall/firewall-start.sh


Incoming connections

## Tomcat JMX (source IP @ filtering)
$IPTABLES -A INPUT -p tcp --dport 8090 -s 192.168.1.0/24 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 8090 -s 5.39.81.23 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 8090 -s 0.0.0.0/0 -j DROP


Outgoing connections

$IPTABLES -t filter -A OUTPUT -p tcp -m state --state NEW --dport 8090 -j ACCEPT      # Tomcat JMX


Just restart your firewall to apply changes

firewall restart


Access JMX data

Just execute jvisualvm or jconsole.

Fill up the information and use a none-secure connection.