Php имеет собственный /tmp в /tmp/systemd-private-nABCDE/tmp при доступе через nginx

Я обнаружил странное поведение в отношении папок php и /tmp. Php использует другую папку, когда работает с /tmp. Php 5.6.7, nginx, php-fpm.

Я выполняю один и тот же скрипт двумя способами: через браузер и через оболочку. Но когда он запускается через браузер, файл находится не в реальной папке /tmp:

<?php
$name = date("His");

echo "File /tmp/$name.txt\n";

shell_exec('echo "123" > /tmp/'.$name.'.txt');

var_dump(file_exists('/tmp/'.$name.'.txt'));

var_dump(shell_exec('cat /etc/*release | tail -n 1'));

php -f script.php

File /tmp/185617.txt
bool(true)
string(38) "CentOS Linux release 7.0.1406 (Core)

Где файл? В /tmp

$ find / -name 185617.txt
/tmp/185617.txt

Если получить к нему доступ через http://myserver.ru/script.php, я получаю

File /tmp/185212.txt
bool(true)
string(38) "CentOS Linux release 7.0.1406 (Core)

Но где файл?

$ find / -name 185212.txt
/tmp/systemd-private-nABCDE/tmp/185212.txt

Почему php считает, что /tmp должно быть в /tmp/systemd-private-nABCDE/tmp?


person shukshin.ivan    schedule 25.05.2015    source источник


Ответы (3)


Потому что systemd настроен на предоставление nginx приватного /tmp. Если по какой-то причине вы должны вместо этого использовать системный /tmp, вам нужно будет изменить файл .service, чтобы он читался как «PrivateTmp=no».

person Ignacio Vazquez-Abrams    schedule 25.05.2015
comment
Вы правы, но это php-fpm, а не nginx. Я изменил файл /usr/lib/systemd/system/php-fpm.service строку PrivateTmp=true на PrivateTmp=false. Теперь php использует правильную папку /tmp. - person shukshin.ivan; 25.05.2015
comment
вау это гениально. именно то, что мы искали с 2 дней :) - person Milan Maharjan; 02.03.2016
comment
Учитывайте последствия этого изменения для безопасности. /tmp может содержать конфиденциальную информацию, и все php-скрипты могут внезапно получить доступ к этой информации. - person Gerben; 06.09.2018
comment
Что делать, если в вашей системе нет системной подпапки? может быть где-то еще? - person Scott; 07.09.2018
comment
@ Скотт find / -type f -name 'php-fpm.service'. Скорее всего, вам нужно будет запустить это как sudo/root, но он рекурсивно найдет любой файл, начиная с корневого (/) каталога с именем php-fpm.service. - person domdambrogia; 23.05.2019

Если вы запускаете несколько сайтов на сервере, я думаю, вы захотите оставить PrivateTmp=yes, чтобы каждый сайт оставался изолированным даже при использовании временных файлов. В противном случае, я думаю, это может быть проблемой безопасности.

person Artis    schedule 20.03.2017

У Игнасио Васкес-Абрамса есть правильный ответ, но позвольте мне добавить свое функциональное решение.

Я попробовал решение «multi-user.target.wants», оно сработало, но после перезапуска, но в какой-то момент PrivateTmp возвращается к истине. Поскольку мое основное использование Apache2 — это PHP, я, наконец, отредактировал php.ini и раскомментировал строку sys_temp_dir.

По умолчанию система использует временный каталог, назначенный функцией sys_get_temp_dir. Функция sys_get_temp_dir вернет «/tmp», но правда в том, что ваши файлы tmp хранятся по некоторому пути, например /tmp/systemd-private-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-apache2.service-YYYYYY//tmp/*. Итак, что для меня было работой:

Отредактируйте php.ini (путь может меняться между версиями PHP)

sudo nano /etc/php/7.2/cli/php.ini

Затем раскомментируйте строку sys_temp_dir

; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
sys_temp_dir = "/tmp"
person Benjamin    schedule 06.09.2019
comment
XXX можно прочитать из /proc/sys/kernel/random/boot_id, но откуда взять YYY? - person stackprotector; 19.10.2020