Вопрос или проблема
Я запускаю rsync --archive
, который включает параметр -p, занимающийся разрешениями файла. Синхронизация идет с удаленного компьютера на локальный. Это работает в SSH-оболочке.
Но если я вызываю ту же команду из PHP, появляются сообщения об ошибках:
var_dump(shell_exec("/usr/bin/rsync -v --archive --rsh="/usr/bin/ssh <sshparameters>" remotecomputer /local/path/ 2>&1"));
rsync: [generator] failed to set permissions on "/local/path/subdir/single-file": Permission denied (13)
PHP запускается с тем же пользователем, что и SSH. PHP может изменить права доступа на тот же файл, который копируется правильно, но имеет неправильные разрешения:
var_dump(shell_exec("chmod -v 777 /local/path/subdir/single-file 2>&1"));
Что здесь происходит? Есть ли какая-либо переменная окружения, которая может вызвать ошибки в rsync?
Ответ или решение
Теория
rsync
— мощный инструмент для синхронизации файлов и каталогов между двумя компьютерами. Основное его преимущество заключается в способности выполнять инкрементные передачи данных, минимизируя объем передаваемой информации и время, затрачиваемое на синхронизацию. Использование флага --archive
(-a
) включает в себя несколько параметров, таких как рекурсия и сохранение прав доступа файла.
Однако, при запуске rsync
внутри PHP через функцию shell_exec
, возникают ошибки, связанные с изменением прав доступа к файлам. Следует учитывать, как работают обе команды — rsync
и chmod
— и какие особенности исполнения могут влиять на их поведение.
Пример
В случае, описанном в вашем сценарии, имеется команда выполнения rsync
, которая получает ошибку разрешений:
rsync: [generator] failed to set permissions on "/local/path/subdir/single-file": Permission denied (13)
С другой стороны, команда chmod
, выполненная в том же окружении, успешно изменяет права доступа:
chmod -v 777 /local/path/subdir/single-file 2>&1
Это говорит о том, что rsync
, запущенная из PHP, не может изменить права доступа, тогда как напрямую вызванная команда chmod
может.
Применение
Права и Привилегии
Первоочередной фактор — различия в правах и привилегиях между выполняемыми командами. Хотя PHP запускается под тем же пользователем, что и SSH, контекст выполнения может различаться. Например, SELinux или AppArmor, распространённые в системах на базе Linux, могут накладывать дополнительные ограничение на процессы, запущенные веб-серверами.
Проверка:
- Убедитесь, что PHP действительно запускается под тем же пользователем.
- Проверьте, не активированы ли дополнительные механизмы безопасности, такие как SELinux/AppArmor, которые могут ограничивать выполнение системных команд из PHP.
Сгруппированное и Разрешенное Идентифицирование
Иногда rsync
может требовать дополнительных полномочий, особенно при изменении владельца или группы, что может запрашивать права суперпользователя (sudo). Если PHP не может выполнять команды с поднятием привилегий, это может вызвать сбой.
Проверка:
- Попробуйте визуально отслеживать журнал ошибок rsync или систему.
- Попробуйте использовать
sudo
с надлежащей конфигурацией пользовательского доступа, если это применимо и приемлемо в вашей ситуации безопасности.
Проблемы с Конфигурацией Окружения
Команды, выполняемые с помощью shell_exec
, могут использовать разные переменные среды по сравнению с интерактивной сессией SSH. Переменные окружения, такие как $PATH
, могут быть различными, что приводит к тому, что найденные и выполняемые версии команд отличаются от ожидаемых.
Проверка:
- Можно вывести переменные окружения из обеих команд, выполненных из PHP и интерактивного SSH, для сравнения.
- Убедитесь, что в конфигурации PHP (например,
disable_functions
вphp.ini
) не заблокированы вызовыrsync
или связанных системных функций.
Решение
-
Журналы и Уведомления: Добавьте журнальные записи, чтобы отслеживать различия в поведении и найти точное место сбоя.
-
Управление SELinux/AppArmor: Попробуйте временно отключить их или настройте соответствующие профили, чтобы разрешить необходимые операции.
-
Скрипты Оболочки: Возможно, вам стоит поместить
rsync
вызов в скрипт оболочки (.sh), который гарантирует, что выполняемая команда имеет все необходимые настройки переменных окружения, затем вызывайте этот скрипт из PHP. -
Привилегии: Расширьте привилегии использующего аккаунта либо настройте
sudo
, чтобы позволить изменение привилегированных файлов или компонентов системы, если это допустимо в рамках модели безопасности.
Установите эти меры, чтобы определить и устранить причины возникшей ошибки. Это не только поможет в текущем контексте, но и повысит защищенность и надежность инфраструктуры в долгосрочной перспективе.