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

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

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

  • Коды выхода не надежно возвращаются, поэтому все команды должны выполняться в оболочке script, которая упаковывает stdout, stderr и код выхода в объект JSON и возвращает его через stdout. Этот script должен существовать на каждом подчиненном сервере.
  • Библиотека 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. Каким будет лучший способ сделать это безопасным образом, введя минимальное количество зависимостей на подчиненных серверах?

5
23 янв. '13 в 10:53
источник поделиться
2 ответов

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

1
23 янв. '13 в 16:33
источник

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

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

0
04 февр. '13 в 9:35
источник

Посмотрите другие вопросы по меткам или Задайте вопрос