Подтвердить что ты не робот

Безопасная отладка для производственных JVM

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

-Xdebug -Xrunjdwp: transport = dt_socket, server = y, suspend = n, address = PORT

Кажется, что нет доступного механизма безопасности, поэтому включение отладки в производстве позволит эффективно выполнять произвольный код (через hotswap).

У нас есть сочетание 1.4.2 и 1.5 Sun JVM, работающих на Solaris 9 и Linux (Redhat Enterprise 4). Как включить безопасную отладку? Любые другие способы достижения нашей цели проверки производственного сервера?

Обновление: Для JVM 1.5+ JVM можно указать интерфейс и порт, к которым должен быть привязан отладчик. Таким образом, предложение 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, класс, который запускает поток опроса, а затем рефлексивно вызывает основной метод другого указанного класса.

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

Мне не известно о встроенной способности шифрования подключений к порту отладки.

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

  • Поместите производственную машину за брандмауэр, который блокирует доступ к порту (-ам) отладки.
  • Запустите прокси-процесс на самом хосте, который подключается к порту, и шифрует вход и выход из сокета.
  • Запустите прокси-клиент на рабочей станции для отладки, который также шифрует/расшифровывает ввод. Попросите это подключиться к прокси-серверу. Связь между ними будет зашифрована.
  • Подключите ваш отладчик к прокси-клиенту.