JConsole over ssh local port forwarding

后端 未结 4 655
被撕碎了的回忆
被撕碎了的回忆 2020-11-30 17:15

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

相关标签:
4条回答
  • 2020-11-30 17:43

    There's an even nicer way to do this using an SSH socks tunnel, since JConsole supports SOCKS:

    1. Create the SSH socks proxy locally on some free port (e.g. 7777):

      ssh -fN -D 7777 user@firewalled-host

    2. Run JConsole by specifying the SOCKS proxy (e.g. localhost:7777) and the address for the JMX server (e.g. localhost:2147)

      jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 service:jmx:rmi:///jndi/rmi://localhost:2147/jmxrmi -J-DsocksNonProxyHosts=

    As mentioned in one of the answers below, from JDK 8u60+ you also need to have the -J-DsocksNonProxyHosts= option in order to get it working.

    0 讨论(0)
  • 2020-11-30 17:48

    Continuing the SSH socks method, with newer java versions (around 8u66) you also need to set socksNonProxyHosts empty resulting in:

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 -J-DsocksNonProxyHosts=
    
    0 讨论(0)
  • 2020-11-30 17:50

    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.

    Something like the following should work to run your application with both the registry and server ports set to 8000. See here for more details.

    -Dcom.sun.management.jmxremote.port=8000
    -Dcom.sun.management.jmxremote.rmi.port=8000
    -Djava.rmi.server.hostname=127.0.0.1
    

    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 port(s) you need to forward, you can set up your ssh command. For example, if you configure the registry and server ports as 8000, you would do:

    ssh -L 8000:localhost:8000 remote-host
    

    This creates a local port 8000 which forwards to localhost:8000 on the remote-host. You can specify multiple -L arguments if you need to forward multiple ports. Then you can connect your jconsole to localhost:8000 and it will connect to the remote-host appropriately.

    Also, if your server has multiple interfaces, you may need to set the java.rmi.server.hostname variable to bind to the right interface.

    -Djava.rmi.server.hostname=10.1.2.3
    
    0 讨论(0)
  • 2020-11-30 18:07

    With almost all current JDK versions (7u25 or later) it's now possible to use JConsole and Visual JVM over SSH quite easily (because now you can bind JMX to single port).

    I use the following JVM parameters

    -Dcom.sun.management.jmxremote.port=8090
    -Dcom.sun.management.jmxremote.rmi.port=8090
    -Djava.rmi.server.hostname=127.0.0.1
    -Dcom.sun.management.jmxremote.authenticate=false
    -Dcom.sun.management.jmxremote.ssl=false
    

    Then I launch SSH connection

    ssh my.javaserver.domain -L 8090:127.0.0.1:8090
    

    After I can connect from JConsole

    Remote Process: -> localhost:8090

    And Java Visual VM

    Right Click on Local -> Add JMX Connection -> localhost:8090

    0 讨论(0)
提交回复
热议问题