Вопрос или проблема
Я использую php-fpm
с включенной опцией PrivateTmp. Мне нужно прочитать файл из PHP, который копируется агентом удаленного развертывания в директорию /tmp
. Поскольку PrivateTmp включен, я не могу напрямую получить доступ к директории /tmp
.
Возможно ли прочитать файл из системной папки /tmp
, когда включен PrivateTmp? Я попытался создать символическую ссылку на /tmp
в /var/temp
и получить доступ к файлу через /var/temp
, но это не сработало. /var/tmp
в данный момент монтирована с /tmp
, и я также пытался получить доступ к файлу через /var/tmp
безуспешно.
Из документации:
PrivateTmp=
Принимает логический аргумент. Если установлено в true, настраивает новое пространство имен файловой системы для выполняемых процессов и монтирует частные директории/tmp
и/var/tmp
внутри него, которые не разделяются процессами за пределами этого пространства имен. Это полезно для защиты доступа к временным файлам процесса, но делает невозможным совместное использование между процессами через/tmp
или/var/tmp
.
Итак, нет, вы не можете читать из системной директории /tmp/
.
Но в том же разделе документации есть обходной путь:
… Возможно запустить два или более единиц в одном и том же частном пространстве имен /tmp и /var/tmp с помощью директивы
JoinsNamespaceOf=
, см. подробности в systemd.unit(5).
Так что если ваш агент удаленного развертывания также запускается из unit-сервиса systemd, вы можете объединить их в один PrivateTmp, общий для них, но все же изолированный от остальной системы.
Если это не вариант: не сохраняйте файл в системной /tmp/
и просто поместите/переместите его в другое место…
Вы можете использовать nsenter
для выполнения команды внутри сетевого пространства имен.
Например, если вы хотите просмотреть файлы внутри /tmp для службы apache2, вы можете сделать что-то вроде этого:
pid=$(systemctl show --property=MainPID --value apache2.service)
nsenter -t $pid -m ls /tmp
Это выполнит ls /tmp
внутри пространства монтирования, в котором работает процесс apache2.
Кроме того, частная директория tmp в настоящее время находится по пути типа /tmp/systemd-private-*-apache2.service-*
, где *
— это какой-то идентификатор. Хотя, вероятно, лучше не полагаться на конкретный формат или местоположение.
.
Ответ или решение
В контексте работы с PHP-FPM и включённой функцией PrivateTmp возникает важная задача: как получить доступ к файлам, находящимся в системной директории /tmp
, особенно когда файлы записываются туда внешними агентами развёртывания. Давайте детально рассмотрим, как с этим справиться, используя теоретические знания, практические примеры и их применение.
Теория
PrivateTmp — это опция, доступная в systemd для изоляции временных директорий /tmp
и /var/tmp
. Когда этот параметр активирован, создаётся уникальное пространство имён для процесса, в котором данные временные директории недоступны другим процессам. Это повышает безопасность, так как делает невозможным случайное или намеренное взаимодействие процессов через временные файлы в /tmp
или /var/tmp
.
Основная задача PrivateTmp состоит в ограничении доступа для предотвращения утечек данных между сервисами и улучшения общей безопасности системы. Важно понимать: такая изоляция означает, что один процесс не может напрямую взаимодействовать с /tmp
, который видят остальные процессы системы.
Однако, несмотря на такие жёсткие ограничения, systemd предоставляет инструмент для объединения нескольких процессов в одно пространство временных директорий.
Пример
Согласно документации systemd, директива JoinsNamespaceOf=
позволяет процессам делить одно пространство временных директорий. Это означает, что, если ваш агент развёртывания также управляется systemd, вы можете настроить его с помощью той же директивы, чтобы они оба работали в одном и том же пространстве имен.
Применение
Итак, какие конкретные шаги можно предпринять, чтобы обойти ограничения PrivateTmp?
-
Использование JoinsNamespaceOf=:
Вы можете настроить файл юнита systemd для вашего PHP-FPM, используя директивуJoinsNamespaceOf=
, чтобы объединить пространство временных директорий с тем, которое использует агент развёртывания. Это позволит обоим процессам обмениваться файлами через изолированное пространство/tmp
. -
Смена директории для временных файлов:
Если объединение пространств имен не представляется возможным (например, если агент развёртывания не управляется systemd), более простым и зачастую более безопасным решением является просто изменение пути хранения временных файлов. Можно использовать другую директорию, не связанную с/tmp
, например, специально созданную для этих целей. -
Использование nsenter:
Если вам нужно временно получить доступ к файлам в изолированном/tmp
, вы можете воспользоваться утилитойnsenter
. Эта команда позволяет вам выполнить операции в пространстве имен другого процесса. Примером может служить:pid=$(systemctl show --property=MainPID --value php-fpm.service) nsenter -t $pid -m ls /tmp
Данная команда позволит вам просмотреть файлы в изолированном
/tmp
, который используется PHP-FPM. -
Изучение местоположения приватного tmp:
Обычно private tmp directory может быть найдена по пути наподобие/tmp/systemd-private-*-php-fpm.service-*
. Хотя такая информация может быть полезной, не стоит полагаться на форматирование или расположение, так как они могут меняться в зависимости от версии systemd и различных конфигураций.
Применение данных стратегий позволит вам решать задачи взаимодействия с файлами в /tmp
даже при активации PrivateTmp, оставаясь в рамках безопасности и оптимизации работы системы. Важно адаптировать предложенные решения под конкретные условия вашей системы и требований безопасности, чтобы добиться эффективного функционирования приложений.