Безопасная отладка для производственных JVM - PullRequest
17 голосов
/ 28 мая 2009

У нас есть некоторые приложения, которые иногда попадают в плохое состояние, но только в производстве (конечно!). Хотя получение дампа кучи может помочь собрать информацию о состоянии, часто проще использовать удаленный отладчик. Настроить это легко - нужно только добавить это в его командную строку:

-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 другого указанного класса.

Вот как это используется:

  1. Замените ваш "основной" класс на DebuggerMainWrapper в ваших скриптах запуска.
  2. Добавьте два системных (-D) параметра, один из которых задает реальный основной класс, а другой - файл в файловой системе.
  3. Сконфигурируйте отладчик в командной строке с добавленной частью onthrow = com.whwhat.TurnOnDebuggerException
  4. Добавьте банку с тремя упомянутыми выше классами в путь к классам.

Теперь, когда вы запускаете JVM, все то же самое, за исключением того, что запускается фоновый поток опроса. Предполагая, что файл (наш называется TurnOnDebugger) изначально не существует, он проверяет его каждые N секунд. Когда поллер впервые замечает это, он выдает и сразу же ловит исключение TurnOnDebuggerException. Затем агент стартует.

Вы не можете выключить его, и машина не очень защищена, когда включена. С другой стороны, я не думаю, что отладчик допускает несколько одновременных соединений, поэтому поддержание отладочного соединения - ваша лучшая защита. Мы выбрали метод уведомления о файлах, потому что он позволил нам воспользоваться нашим существующим автором / автором Unix, указав файл триггера в каталоге, где права имеют только правильные пользователи. Вы можете легко создать небольшой файл войны, который достиг той же цели через соединение через сокет. Конечно, поскольку мы не можем отключить отладчик, мы будем использовать его только для сбора данных перед тем, как завершить работу некорректного приложения. Если кто-то хочет этот код, пожалуйста, дайте мне знать. Тем не менее, вам понадобится всего несколько минут, чтобы собрать все вместе.

Ответы [ 4 ]

8 голосов
/ 28 мая 2009

Если вы используете SSH, вы можете разрешить туннелирование и туннелирование порта на ваш локальный хост. Разработка не требуется, все сделано с использованием sshd, ssh и / или putty.

Сокет отладки на вашем Java-сервере может быть настроен на локальном интерфейсе 127.0.0.1.

2 голосов
/ 28 мая 2009

Вы абсолютно правы: API отладки Java по своей природе небезопасен. Однако вы можете ограничить его сокетами домена UNIX и написать прокси-сервер с SSL / SSH, чтобы позволить вам проверять подлинность и шифровать внешние соединения, которые затем перенаправляются в сокет домена UNIX. Это, по крайней мере, уменьшает вашу подверженность тому, кто может получить процесс на сервере, или тому, кто может взломать ваш SSL.

0 голосов
/ 28 мая 2009

Хороший вопрос.

Мне не известно о какой-либо встроенной возможности шифрования соединений с портом отладки.

Возможно, есть гораздо лучшее / более простое решение, но я бы сделал следующее:

  1. Поместите производственную машину за брандмауэр, который блокирует доступ к портам отладки.
  2. Запуск прокси-процесса на самом хосте, который подключается к порту и шифрует ввод и вывод из сокета.
  3. Запустите прокси-клиент на рабочей станции отладки, которая также шифрует / дешифрует ввод. Имейте это, соединяются с прокси сервера. Связь между ними будет зашифрована.
  4. Подключите ваш отладчик к прокси-клиенту.
0 голосов
/ 28 мая 2009

Экспорт информации / услуг в JMX, а затем использование RMI + SSL для удаленного доступа к нему. Ваша ситуация - это то, для чего предназначен JMX (M обозначает Management).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...