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=