У нас есть некоторые приложения, которые иногда попадают в плохое состояние, но только в производстве (конечно!). Хотя получение дампа кучи может помочь собрать информацию о состоянии, часто проще использовать удаленный отладчик. Настроить это легко - нужно только добавить это в его командную строку:
-Xdebug -Xrunjdwp: transport = dt_socket, server = y, suspend = n, address = PORT
Похоже, что нет никакого доступного механизма безопасности, поэтому включение отладки в производственном процессе фактически позволило бы выполнить произвольный код (через горячую замену).
У нас есть смесь 1.4.2 и 1.5 Sun JVM, работающих на Solaris 9 и Linux (Redhat Enterprise 4). Как мы можем включить безопасную отладку? Есть ли другие способы достижения нашей цели проверки производственного сервера?
Обновление: Для JVM JDK 1.5+ можно указать интерфейс и порт, к которому должен быть привязан отладчик. Таким образом, предложение KarlP о привязке к loopback и просто использовании SSH-туннеля к локальному блоку разработчика должно работать, если SSH правильно настроен на серверах.
Однако, похоже, что JDK1.4x не позволяет указывать интерфейс для порта отладки. Таким образом, мы можем либо заблокировать доступ к порту отладки где-нибудь в сети, либо выполнить некоторую системную блокировку в самой ОС (IPChains, как предложил Джаред, и т. Д.)?
Обновление № 2: это хак, который позволит нам ограничить наш риск, даже на 1.4.2 JVM:
Параметры командной строки:
-Xdebug
-Xrunjdwp:
transport=dt_socket,
server=y,
suspend=n,
address=9001,
onthrow=com.whatever.TurnOnDebuggerException,
launch=nothing
Java-код для включения отладчика:
try {
throw new TurnOnDebuggerException();
} catch (TurnOnDebugger td) {
//Nothing
}
TurnOnDebuggerException может быть любым исключением, которое гарантированно не будет выброшено где-либо еще.
Я проверил это на Windows-боксе, чтобы доказать, что (1) порт отладчика не получает соединения изначально, и (2) выдает исключение TurnOnDebugger, как показано выше, вызывает оживление отладчика. Параметр запуска был обязательным (по крайней мере, в JDK1.4.2), но JVM изящно обработал значение мусора.
Мы планируем создать небольшой сервлет, который при соответствующей безопасности может позволить нам включить отладчик. Конечно, потом его нельзя отключить, и отладчик все равно беспорядочно прислушивается. Но это ограничения, которые мы готовы принять, поскольку отладка производственной системы всегда приводит к перезапуску.
Обновление № 3: В итоге я написал три класса: (1) TurnOnDebuggerException, простое исключение Java, (2) DebuggerPoller, фоновый поток проверяет существование указанного файла в файловая система и (3) DebuggerMainWrapper, класс, который запускает поток опроса и затем рефлексивно вызывает метод main другого указанного класса.
Вот как это используется:
- Замените ваш "основной" класс на DebuggerMainWrapper в ваших скриптах запуска.
- Добавьте два системных (-D) параметра, один из которых задает реальный основной класс, а другой - файл в файловой системе.
- Сконфигурируйте отладчик в командной строке с добавленной частью onthrow = com.whwhat.TurnOnDebuggerException
- Добавьте банку с тремя упомянутыми выше классами в путь к классам.
Теперь, когда вы запускаете JVM, все то же самое, за исключением того, что запускается фоновый поток опроса. Предполагая, что файл (наш называется TurnOnDebugger) изначально не существует, он проверяет его каждые N секунд. Когда поллер впервые замечает это, он выдает и сразу же ловит исключение TurnOnDebuggerException. Затем агент стартует.
Вы не можете выключить его, и машина не очень защищена, когда включена. С другой стороны, я не думаю, что отладчик допускает несколько одновременных соединений, поэтому поддержание отладочного соединения - ваша лучшая защита. Мы выбрали метод уведомления о файлах, потому что он позволил нам воспользоваться нашим существующим автором / автором Unix, указав файл триггера в каталоге, где права имеют только правильные пользователи. Вы можете легко создать небольшой файл войны, который достиг той же цели через соединение через сокет. Конечно, поскольку мы не можем отключить отладчик, мы будем использовать его только для сбора данных перед тем, как завершить работу некорректного приложения. Если кто-то хочет этот код, пожалуйста, дайте мне знать. Тем не менее, вам понадобится всего несколько минут, чтобы собрать все вместе.