0

This follows on from "How to access JMX interface in docker from outside?" which talks about setting up unencrypted JMX connections.

I could use either RMI or JMXMP which Glassfish uses.

There is a set of JVM options that are required and I'm looking for the changes I need to set up JMX with SSL:

com.sun.management.jmxremote=true
com.sun.management.jmxremote.local.only=false
com.sun.management.jmxremote.ssl=true
com.sun.management.jmxremote.authenticate=true
com.sun.management.jmxremote.port=12345
com.sun.management.jmxremote.rmi.port=12346
java.rmi.server.hostname=10.11.12.176
com.sun.management.jmxremote.access.file=/.secure/jmxremote.access
com.sun.management.jmxremote.password.file=/.secure/jmxremote.pass
com.sun.management.jmxremote.login.config=ldap-ad-config
java.net.preferIPv4Stack=true
com.sun.management.jmxremote.ssl.config.file=/.secure/jmxremotessl.properties
javax.net.ssl.keyStore=/config/app.jks
javax.net.ssl.keyStorePassword=teabag
javax.net.ssl.trustStore=/config/cacerts
javax.net.ssl.trustStorePassword=milk

The problem is the same:

java.rmi.ConnectException: Connection refused to host: 172.0.0.85; nested exception is
    java.net.ConnectException: Operation timed out

That IP address is the internal IP address of the docker container. I assume that this is happening despite the java.rmi.server.hostname solution because it's on SSL.

I tried to reverse proxy the SSL to non-SSL with nginx but that failed with the error

java.rmi.ConnectIOException: non-JRMP server at remote endpoint

so I guess I should be forwarding extra headers in nginx.

I'm now attempting to set up JMXMP but the documentation on how to do it is pretty thin on the ground. There's a Spring implementation and a Glassfish implementation but not with findable docs (as yet) - so I'm adding the glassfish tag.

Adam
  • 4,560
  • 3
  • 40
  • 78

1 Answers1

0

The answer is that I can set up my app to use JMXMP and configure it to implement TLS connections using these JVM options:

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=true
-Dcom.sun.management.jmxremote.access.file=C:/dev/.secure/jmxremote.access
-Dcom.sun.management.jmxremote.password.file=C:/dev/.secure/jmxremote.pass
-Dcom.sun.management.jmxremote.login.config=spnego-server
-Djava.net.preferIPv4Stack=true
-Dcom.sun.management.jmxremote.ssl.config.file=/.secure/jmxremotessl.properties

however I have to code up a configuration class to launch the JMXConnectorServer like so:

@Configuration
public class JmxServer {

    public JmxServer(
            @Value("${jmx.remote.hostname}") final String hostname,
            @Value("${jmx.remote.port}") final String port) {
        try {
            Map<String, Object> env = new HashMap<>();
            env.put("jmx.remote.profiles", "TLS SASL/PLAIN");
            env.put(JMXConnector.CREDENTIALS,
                    new String[] {"myusername", "password"});
            JMXConnectorServerFactory.newJMXConnectorServer(
                    new JMXServiceURL(
                            String.format("service:jmx:jmxmp://%s:%s",
                                    hostname, port)),
                    env,
                    ManagementFactory.getPlatformMBeanServer()
            ).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

But this is only half of it. I am now wrangling with JConsole to get it to do JMXMP with TLS.

For that I'm following this fossil question from 2007 on the Oracle forums:

Can JConsole connect to a remote JMX agent using JMXMP and TLS?

but still struggling...

Adam
  • 4,560
  • 3
  • 40
  • 78