JConsole через пересылку локального порта ssh

Я хотел бы иметь возможность удаленно подключаться к службе Java, на которой открыт JMX, однако она блокируется брандмауэром. Я попытался использовать пересылку локального порта ssh, однако соединение не работает. Если посмотреть на wirehark, кажется, что когда вы пытаетесь подключиться к jconsole, он хочет подключиться через некоторые эфемерные порты после подключения к порту 9999, которые блокируются брандмауэром.

Можно ли использовать jconsole только через 9999 или использовать прокси? Является эта статья по-прежнему является лучшим решением? Или я чего-то не хватает?

Ответ 1

Можно ли использовать jconsole только через 9999 или использовать прокси? Является эта статья по-прежнему лучшим решением? Или я чего-то не хватает?

Да, эта статья о праве.

Когда вы указываете порт JMX на своем сервере (-Dcom.sun.management.jmxremote.port=####), вы фактически указываете только реестр-порт для приложения. При подключении он предоставляет дополнительный сервер-порт, с которым jconsole выполняет всю свою работу. Чтобы перенаправить на работу, вам необходимо знать как реестр, так и серверные порты.

Что-то вроде следующего должно работать, чтобы запустить ваше приложение с портом реестра и сервера, установленным на 8000. Подробнее см. .

-Dcom.sun.management.jmxremote.port=8000
-Dcom.sun.management.jmxremote.rmi.port=8000

В стороне, моя библиотека SimpleJMX позволяет вам легко установить оба порта, и вы можете установить их как один и тот же порт.

Итак, как только вы знаете оба порта, которые вам нужно переслать, вы можете настроить свою команду ssh. Например, если вы настроите порты реестра и сервера как 8000, выполните следующие действия:

ssh -L 8000:localhost:8000 remote-host

Это создает локальный порт 8000, который пересылает на localhost: 8000 на удаленном хосте. Вы можете указать несколько аргументов -L, если вам нужно перенаправить несколько портов. Затем вы можете подключить jconsole к localhost: 8000, и он будет соответствующим образом подключаться к удаленному хосту.

Кроме того, если ваш сервер имеет несколько интерфейсов, вам может потребоваться установить обе следующие переменные, чтобы привязать реестр и порты сервера к правильному интерфейсу:

-Djava.rmi.server.hostname=10.1.2.3

Ответ 2

Есть еще лучший способ сделать это, используя туннель SSH socks, поскольку JConsole поддерживает SOCKS:

  • Создайте прокси-сервер SSH локально на каком-либо свободном порту (например, 7777):

    ssh -fN -D 7777 user @firewalled-host

  • Запустите JConsole, указав прокси SOCKS (например, localhost: 7777) и адрес для сервера JMX (например, localhost: 2147)

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

Как уже упоминалось в одном из ответов ниже, из JDK 8u60 + вам также необходимо иметь параметр -J-DsocksNonProxyHosts=, чтобы заставить его работать.

Ответ 3

С почти всеми текущими версиями JDK (7u25 или новее) теперь можно легко использовать JConsole и Visual JVM поверх SSH (потому что теперь вы можете привязать JMX к одному порту).

Я использую следующие параметры JVM

-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

Затем я запускаю SSH-соединение

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

После подключения к JConsole

Удаленный процесс: → localhost: 8090

И Java Visual VM

Щелкните правой кнопкой мыши на Local → Добавить соединение JMX → localhost: 8090

Ответ 4

Продолжая метод SSH socks, с новыми версиями java (около 8u66) вам также нужно установить socksNonProxyHosts пустым, в результате чего:

jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 -J-DsocksNonProxyHosts=