Php set sys temp directory

PHP: When is /tmp not /tmp?

Until a few years ago you could use PHP, or any other application, to write a file to /tmp and see it appear immediately in the server /tmp directory. This is no longer the case.

So what’s happening?

On our servers, running Linux, Apache and PHP, there are at least three factors at work:

PrivateTmp

In the systemd service configuration files for Apache2 and some other programs you will see PrivateTmp=yes or PrivateTmp=true as the default setting.

This means that the affected programs will not have access to the system /tmp directory. Instead any read/write requests for /tmp silently redirect to a location assigned by systemd. Something like:

So if you have a PHP script run by Apache, any files written to /tmp will only be accessible by Apache and not from the command-line or another application as there is no safe and reliable way (that we know of) to determine the actual file location.

libpam-tmpdir

Similarly from the command-line the libpam-tmpdir package creates separate /tmp directories for different users based on their User ID:

root /tmp/user/0 www-data /tmp/user/XX chirp /tmp/user/1001

Only it’s not as strict as the PrivateTmp as you can still write to /tmp if you want as shown below.

What’s actually happening is that the $TMP and $TMPDIR constants are updated at login for each user.

PHP sys_get_temp_dir

When writing a file to /tmp using PHP there are (at least) two different ways to specify the the path as shown in this simple script:

fwrite(«written to /tmp/ by « . posix_getpwuid(posix_geteuid())[‘name’] . «\n«); $file = NULL; $file = new \SplFileObject( sys_get_temp_dir() . «/tmp-test.txt», «a+»); $file->fwrite(«written to sys_get_temp_dir() by « . posix_getpwuid(posix_geteuid())[‘name’] . «\n«); $file = NULL; ?>

In the first case we simply use the literal /tmp while in the second case we rely on the sys_get_temp_dir function, which sometimes returns a different value.

Test Results

Using the above script, called from Apache both using a web browser and using cURL from the command-line (which is essentially the same thing) the file is consistently written to:

/tmp/systemd-private-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-apache2.service-XXXXXX/tmp/tmp-test.txt written to /tmp/ by www-data written to sys_get_temp_dir() by www-data written to /tmp/ by www-data written to sys_get_temp_dir() by www-data

Restarting the Apache process will likely change this to a new directory, but until then we can use /tmp to share files between scripts as long as they’re run from Apache.

When running PHP from the command-line as different users:

root:~# php /path/to/script.php root:~# su — www-data -s /bin/sh -c «php /path/to/script.php» chirp:~$ php /path/to/script.php

If we specify /tmp then the file appears where expected:

/tmp/tmp-test.txt written to /tmp/ by root written to /tmp/ by www-data written to /tmp/ by chirp

But using sys_get_temp_dir() results in separate files based on who is running the script:

/tmp/user/0/tmp-test.txt written to sys_get_temp_dir() by root /tmp/user/1001/tmp-test.txt written to sys_get_temp_dir() by chirp /tmp/user/XX/tmp-test.txt written to sys_get_temp_dir() by www-data

Conclusions

If you want to share PHP-generated files between Apache and command-line scripts then you will need to create your own PHP-writable directory for the scripts to use, and implement your own garbage collection and security.

And sharing between different command-line (CLI) users is only possible if you specify /tmp rather than relying on sys_get_temp_dir().

But if each user only needs access to their own files then sys_get_temp_dir() is the way to go.

Note that we haven’t changed the default sys_temp_dir setting in php.ini which could further complicate things.

Источник

Php set sys temp directory

Поведение этих функций зависит от установок в php.ini .

Директивы конфигурации файловой системы и потоков

Имя По умолчанию Место изменения Список изменений
allow_url_fopen «1» PHP_INI_SYSTEM
allow_url_include «0» PHP_INI_SYSTEM Объявлена устаревшей с версии PHP 7.4.0.
user_agent NULL PHP_INI_ALL
default_socket_timeout «60» PHP_INI_ALL
from «» PHP_INI_ALL
auto_detect_line_endings «0» PHP_INI_ALL Объявлена устаревшей с версии PHP 8.1.0.
sys_temp_dir «» PHP_INI_SYSTEM

Краткое разъяснение конфигурационных директив.

Данная директива включает поддержку обёрток URL (URL wrappers), которые позволяют работать с объектами URL как с обычными файлами. Обёртки, доступные по умолчанию, служат для работы с удалёнными файлами с использованием ftp или http протокола. Некоторые модули, например, zlib, могут регистрировать собственные обёртки.

Эта опция позволяет использование обёрток fopen, которые поддерживают работу с URL, в функциях include , include_once , require , require_once .

Замечание:

Эта опция требует включения опции allow_url_fopen.

Устанавливает отсылаемую PHP строку «User-Agent».

Значение времени ожидания по умолчанию (в секундах) для потоков, использующих сокеты. Отрицательное значения означает бесконечное время ожидания.

Адрес email, используемый в соединениях FTP без авторизации, а также в качестве значения заголовка From в HTTP соединениях при использовании ftp и http обёрток, соответственно.

Когда данная директива включена, PHP проверяет данные, получаемые функциями fgets() и file() с тем, чтобы определить способ завершения строк (Unix, MS-Dos или Macintosh).

Данная директива позволяет PHP взаимодействовать с системами Macintosh, однако, по умолчанию эта директива выключена, поскольку при её использовании возникает (несущественная) потребность в дополнительных ресурсах для определения символа окончания первой строки, а также потому, что программисты, использующие в системах Unix символы возврата каретки в качестве разделителей, столкнутся с обратно-несовместимым поведением PHP.

Источник

PHP: When is /tmp not /tmp?

Until a few years ago you could use PHP, or any other application, to write a file to /tmp and see it appear immediately in the server /tmp directory. This is no longer the case.

So what’s happening?

On our servers, running Linux, Apache and PHP, there are at least three factors at work:

PrivateTmp

In the systemd service configuration files for Apache2 and some other programs you will see PrivateTmp=yes or PrivateTmp=true as the default setting.

This means that the affected programs will not have access to the system /tmp directory. Instead any read/write requests for /tmp silently redirect to a location assigned by systemd. Something like:

So if you have a PHP script run by Apache, any files written to /tmp will only be accessible by Apache and not from the command-line or another application as there is no safe and reliable way (that we know of) to determine the actual file location.

libpam-tmpdir

Similarly from the command-line the libpam-tmpdir package creates separate /tmp directories for different users based on their User ID:

root /tmp/user/0 www-data /tmp/user/XX chirp /tmp/user/1001

Only it’s not as strict as the PrivateTmp as you can still write to /tmp if you want as shown below.

What’s actually happening is that the $TMP and $TMPDIR constants are updated at login for each user.

PHP sys_get_temp_dir

When writing a file to /tmp using PHP there are (at least) two different ways to specify the the path as shown in this simple script:

fwrite(«written to /tmp/ by « . posix_getpwuid(posix_geteuid())[‘name’] . «\n«); $file = NULL; $file = new \SplFileObject( sys_get_temp_dir() . «/tmp-test.txt», «a+»); $file->fwrite(«written to sys_get_temp_dir() by « . posix_getpwuid(posix_geteuid())[‘name’] . «\n«); $file = NULL; ?>

In the first case we simply use the literal /tmp while in the second case we rely on the sys_get_temp_dir function, which sometimes returns a different value.

Test Results

Using the above script, called from Apache both using a web browser and using cURL from the command-line (which is essentially the same thing) the file is consistently written to:

/tmp/systemd-private-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-apache2.service-XXXXXX/tmp/tmp-test.txt written to /tmp/ by www-data written to sys_get_temp_dir() by www-data written to /tmp/ by www-data written to sys_get_temp_dir() by www-data

Restarting the Apache process will likely change this to a new directory, but until then we can use /tmp to share files between scripts as long as they’re run from Apache.

When running PHP from the command-line as different users:

root:~# php /path/to/script.php root:~# su — www-data -s /bin/sh -c «php /path/to/script.php» chirp:~$ php /path/to/script.php

If we specify /tmp then the file appears where expected:

/tmp/tmp-test.txt written to /tmp/ by root written to /tmp/ by www-data written to /tmp/ by chirp

But using sys_get_temp_dir() results in separate files based on who is running the script:

/tmp/user/0/tmp-test.txt written to sys_get_temp_dir() by root /tmp/user/1001/tmp-test.txt written to sys_get_temp_dir() by chirp /tmp/user/XX/tmp-test.txt written to sys_get_temp_dir() by www-data

Conclusions

If you want to share PHP-generated files between Apache and command-line scripts then you will need to create your own PHP-writable directory for the scripts to use, and implement your own garbage collection and security.

And sharing between different command-line (CLI) users is only possible if you specify /tmp rather than relying on sys_get_temp_dir().

But if each user only needs access to their own files then sys_get_temp_dir() is the way to go.

Note that we haven’t changed the default sys_temp_dir setting in php.ini which could further complicate things.

Источник

Читайте также:  Javascript number is null
Оцените статью