blockcipher blockcipher - 3 months ago 47
Java Question

JConsole over ssh local port forwarding

I'd like to be able to remotely connect to a Java service that has JMX exposed, however it is blocked by a firewall. I have tried to use ssh local port forwarding, however the connection fails. Looking at wireshark, it appears that when you try to connect with jconsole, it wants to connect via some ephemeral ports after connecting to port 9999, which are blocked by the firewall.

Is there any way to make jconsole only connect through 9999 or use a proxy? Is this article still the best solution? Or, am I missing something?

Answer

Is there any way to make jconsole only connect through 9999 or use a proxy? Is this article still the best solution? Or, am I missing something?

Yes, that article is about right.

When you specify the JMX port on your server (-Dcom.sun.management.jmxremote.port=####), you are actually specifying just the registry-port for the application. When you connect it provides an additional server-port that the jconsole actually does all of its work with. To get forwarded to work, you need to know both the registry and server ports.

This means that you need to configure your JMX server with something like the following URI:

"service:jmx:rmi://localhost:" + p1 + "/jndi/rmi://localhost:" + p2 + "/jmxrmi"

p1 is the server port and p2 is the registry port. See here for more details. As an aside, my SimpleJMX library allows you to set both ports easily and you can set them both to be the same port.

So, once you know both the ports you need to forward, you can set up your ssh command. For example, if you configure the registry port as 9000 and the server port as 9001, you would do:

ssh -L 9000:localhost:9000 -L 9001:localhost:9001 remote-host

This creates a local port 9000 which forwards to localhost:9000 on the remote-host and the same for port 9001. Then you can connect your jconsole to localhost:9000 and it will connect to the remote-host appropriately.

Also, if your server has multiple interfaces, you may need to set both the following variable to get the registry and server ports to bind to the right interface:

-Djava.rmi.server.hostname=10.1.2.3
Comments