Intereting Posts
Восклицательный знак перед переменным – требуется разъяснение настройка laravel на IIS7 Получение неправильного значения для функции variant_date_to_timestamp () Теги соответствия в MYSQL Шаблон DataMapper PHP: моему классу нужен экземпляр PDO, я хочу обернуть его внутри класса Db Как изменить контент в зависимости от <select>? Как отформатировать путь PHP include () как абсолютный (а не относительный)? Как искать URL-адреса, которые не находятся ни в одном теге html, а затем превращать их в гиперссылки? Создание Eclipse для просмотра разных расширений файлов как PHP Каковы различия между system (), exec () и shell_exec () в PHP? array_intersect выдает ошибки, когда массивы имеют подматрицы Динамический родственный выбор с помощью jQuery, не работает в IE Распределение памяти PHP не работает Перенаправление с использованием PHP, а не перенаправление в Cpanel Вычисление N-го корня с помощью bcmath в PHP

Как безопасно поддерживать постоянное соединение SSH в PHP?

В настоящее время я работаю над панелью VPS, которая использует модель «ведущий-ведомый». Один главный сервер запускает панель, написанную на PHP, и управляет несколькими подчиненными серверами через SSH. Доступ к подчиненным серверам осуществляется через ограниченную учетную запись, которая может подчиняться конкретным командам, связанным с администрированием сервера, и все взаимодействия регистрируются в каталоге, к которому у самой учетной записи нет доступа.

В настоящее время я использую PHP-SSH2, но этот подход имеет несколько проблем:

  • Коды выхода не надежно возвращаются, поэтому все команды должны выполняться в сценарии оболочки, который упаковывает stdout, stderr и код выхода в объект JSON и возвращает его через stdout. Этот скрипт должен существовать на каждом подчиненном сервере.
  • Библиотека PHP-SSH2 не знает понятия «пользовательского таймаута соединения», что означает, что я должен исследовать сервер с помощью fsockopen, прежде чем пытаться использовать PHP-SSH2 для подключения – если я этого не делаю, недоступный сервер может задерживайте pageload в течение минуты или более. Это еще хуже из-за следующего выпуска.
  • Стойкие соединения невозможны. Это вызывает совершенно смешное время pageload в панели, особенно в сочетании с предыдущей проблемой с таймаутами.

Сейчас я пытаюсь решить последнюю проблему в первую очередь.

Есть несколько возможных решений, с которыми я столкнулся, но у всех из них есть проблема:

  • Использование PHPSecLib, чистой реализации PHP SSH и замена всех вызовов fsockopen вызовами pfsockopen. Это сделает соединения постоянными, но это хаккер, чем я хотел бы, и последствия безопасности постоянных сокетов в PHP неясно.
  • Настройка постоянного SSH-туннеля с главного сервера на каждый подчиненный сервер и запуск простого демона (связанного с localhost) на каждом подчиненном сервере, который запускает все, что ему говорят. Это проблема по двум причинам. Во-первых, он вводит необходимость в демон на ведомых серверах, чего я бы скорее избежал. Вторая проблема заключается в том, что если кто-то должен был компрометировать ограниченную учетную запись на подчиненном сервере, они все равно могли бы запускать определенные системные команды, просто подключившись к «демонам команд», даже если бы у них не было доступа к этим командам из их собственной оболочки. Это проблема.
  • Запуск демона на главном сервере, который управляет постоянными подключениями SSH к подчиненным серверам от имени панели. Это связано с написанием SSH-клиента в Python (это единственный подходящий язык, с которым я знаком), и, вероятно, придет к использованию paramiko. Поскольку документация paramiko плохой, это не очень привлекательный вариант и может даже вызвать проблемы с безопасностью, потому что мне не совсем ясно, как все должно быть использовано в paramiko.

Ниже перечислены следующие варианты:

  • Переход на другой язык для самой панели. Я пишу панель на PHP, потому что это тот язык, с которым я больше всего знаком, и я знаю об особенностях и потенциальных проблемах, с которыми я мог бы столкнуться. Написание важного публичного проекта, подобного этому на языке, с которым я не знаком, будет плохой идеей.
  • Использование Twisted для третьего «возможного решения». Twisted – очень большая и запутанная зависимость, и документация кажется еще хуже, чем у paramiko.
  • Запуск HTTP-сервера или другого, но не SSH-открытого демон-сервера на подчиненных серверах.

На практике, я вижу время pageload иногда за минуту, когда к нескольким серверам нужно связаться с pageload. Это явно неприемлемо для панели VPS.

Моя цель состоит в том, чтобы иметь какую-то реализацию, которая позволяет избежать накладных расходов на подключение, которые появляются при использовании PHP-SSH2. Какой был бы лучший способ сделать это безопасным образом, введя минимальное количество зависимостей на подчиненных серверах?

Вы можете использовать autossh и создавать обратные (portforward) туннели с autossh. Затем пусть ваше приложение php поговорит с этими обратными портами ssh. Если сбой подключения ssh, autossh будет продолжать пытаться воссоздать соединение. Приложение php не сможет подключиться к обратному туннелю, а не к таймауту.

Как насчет опции 3, но и написать демона в PHP? Это маршрут, который я пытаюсь использовать в своем собственном проекте.

Вы можете использовать файл FIFO вместо сокетов для связи с ним.