Rsync через PHP exec() с SSH-логином без пароля ssh
Если я выполняю команду через php exec(): Это не работает. Но если я использую bash, он работает идеально. Есть идеи, в чем может быть проблема.? Я подумал, может быть, он выполняет rsync как apache и не разрешает вход по ssh.
exec('rsync -au /var/www/html/f1/ [email protected]:/var/www/html/f2/');
5 answers
PHP обычно запускается в Apache под mod_php
. Обычно Apache работает как собственная учетная запись пользователя, независимая от реальных пользователей, которые используют сервер.
Таким образом, файлы ~/.ssh
, в которых хранится ключ SSH без пароля в домашнем каталоге вашей учетной записи пользователя , недоступны для PHP внутри Apache, так как в нем нет вашего домашнего каталога. Даже если бы Apache предоставил общий доступ к вашему домашнему каталогу, у него все равно не было бы разрешений на чтение этих файлов.
Мое исследование этого материала приводит меня к следующему: я могу запустить rsync на php, который, в свою очередь, работает под управлением apache. Но я должен принять во внимание некоторые моменты:
- Домашние каталоги должны существовать для пользователя, под учетной записью которого веб-сервер запускается на локальном компьютере (возможно, http), и для удаленного пользователя, под учетной записью которого вы подключаетесь к удаленному хосту.
-
Закрытый ключ аутентификации (возможно, с пустым пароль) должен быть доступен для пользователя http. Соответствующий открытый ключ должен быть добавлен к удаленному
~/.ssh/authorized_keys
Файл. Здесь
~
- это домашний каталог удаленного пользователя на удаленном хосте. -
A локальный файл конфигурации
~/.ssh/config
Должно быть создано. Здесь
~
- это домашний каталог пользователя http на локальном хосте. Файлconfig
должен быть доступен только для пользователя http. Он может содержать что-то вроде этого:Host * User=www-data IdentityFile=~/.ssh/nopass_rsa Compression=no Ciphers=arcfour StrictHostKeyChecking=no UserKnownHostsFile=/dev/null
Здесь
User
находится имя пользователя на удаленном хостеIdentityFile
является ключевым файлом. Следующие два параметра (Compression
иCiphers
) позволяют немного увеличить пропускную способность. И последние два параметра позволяют пропустить проверку ключа хоста. -
Если вы имеете дело с
~/.ssh
каталогом локального пользователя http и~
является ли корневой каталог для веб-сервера одновременно, тогда возникает проблема с безопасностью: вы (или кто-либо другой) можете получить доступ к своим файлам ключей, просто набравwww.your-domain.com/.ssh/
В браузере. Так отрицающий доступ к этому каталогу в конфигурации веб-браузера будет хорошей идеей.
Мой пример php-кода:
exec('rsync -auq remote.host.com:/archive/ ./backup_bd/');
Который просто работает...
Думаю, я ответил на ваш вопрос.
Вот как вы указываете, где SSH должен забрать ваши ключи:
exec('rsync -e "ssh -i /home/you/.ssh/id_dsa" ...')
Я предполагаю, что Apache работает под управлением пользователя, который может прочитать ваш id_dsa
или id_rsa
.
Сохраните команду в сценарии оболочки, поскольку в нем нет динамических частей, а затем используйте exec() для выполнения сценария оболочки.
# on command line
echo 'rsync -au /var/www/html/f1/ [email protected]:/var/www/html/f2/' > sync_files
# On command line
chmod +x sync_files
<?php
// in php
exec('sync_files');
?>
Поскольку ни одно из вышеперечисленных предложений не сработало, мне пришлось разрешить учетной записи пользователя Apache доступ без пароля к серверу, который мне также был нужен для загрузки изображений. Это работает так, как я очаровываю, просто по мере необходимости, спасибо всем, кто пытался помочь с моей проблемой.