Reputation: 699
I'm moving my web app from CentOS 5 to CentOS 7, and new security features regarding the /tmp directory are breaking my code. I'm wondering how best to handle it.
I have PHP code that creates a LaTeX file, then executes commands to turn that into a PDF, and then serves that to the user with appropriate headers. Here are some of the relevant lines of code as it stands now:
$fileroot = "/tmp/addr".getmypid();
ob_start();
/* echo all the LaTeX stuff */
file_put_contents($fileroot.".tex",ob_get_contents());
ob_end_clean();
exec("cd /tmp;uplatex -interaction=batchmode --output-directory=/tmp $fileroot", $output, $return);
The settings in /usr/lib/systemd/system/php-fpm.service include PrivateTmp=true
, which causes /tmp
within PHP function calls to really be /tmp/systemd-private-6898f2d665d64b998981bc479ddc2306-php-fpm.service-KU8XML/tmp
. Yikes! That's fine for security, but exec() uses the /tmp
path literally, so it can't find the file that file_put_contents()
just created. The PHP function sys_get_temp_dir()
just returns /tmp
, and I can't find any environment variables with that path in them. Is there a way to get that path programmatically? Or do I need to turn off PrivateTmp? Or is there a better way to do what I need to do? Yes, I could create my own special spot with wide-open permissions, but it seems like it should be cleaner to just use the normal temporary directory.
Upvotes: 5
Views: 10631
Reputation: 568
Aleks G is the correct way, but if you still in trouble try this.
I've try "multi-user.target.wants" solution, it have worked but after restart, but at some point, PrivateTmp go back to true. Like my principal use of Apache2 is PHP, I finally edited php.ini and I've uncomment line sys_temp_dir.
By default system use temp dir assigned by function sys_get_temp_dir. Function sys_get_temp_dir will return "/tmp" but the truth is that your tmp files are storing at some path like /tmp/systemd-private-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-apache2.service-YYYYYY//tmp/*. So, what work for me was:
Edit php.ini (path can change between PHP versions)
sudo nano /etc/php/7.2/cli/php.ini
Then uncomment sys_temp_dir line
; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
sys_temp_dir = "/tmp"
Upvotes: 0
Reputation: 1195
I just had a similar issue. This is a way to find out the "real" temp path of a systemd service with PrivateTmp (in this case apache2):
grep -oP ' /tmp/systemd-private-[^/]+-apache2[^/]+/tmp(?= /tmp)' /proc/`pgrep apache2 -o`/mountinfo
What it does:
pgrep apache2 -o
/proc/PID/mountinfo
file, which contains the mount info as seen by this processgrep
It may be that with future systemd versions or different settings, the regex needs to be adjusted, if the naming is different. You may also just use ' /tmp[^ ]+(?= /tmp)'
as the regex.
Note that it may not help you much to know the path. Private temp folders have strict permissions that only allow root access.
Upvotes: 3
Reputation: 780
I had the same issue (on CentOS) and fixt it with the following steps.
nano /usr/lib/systemd/system/httpd.service
Look in to the file and
PrivateTmp=false
to PrivateTmp=true
systemctl daemon-reload
service http restart
And you are ready2go
Upvotes: 1
Reputation: 57316
The way I see it, there are only two options:
Do not use /tmp
but a different directory instead, which you predefine in your application's config file. I have done something similar recently, where I used /var/run/myapplication
directory instead of /tmp
. (I had to add a cron job to clean it up as well.)
Disable PrivateTmp
in the php-frm service. Here's one way of doing this:
# mkdir /usr/lib/systemd/system/php-fpm.service.d
# echo -e "[Service]\nPrivateTmp=no" > /etc/systemd/system/php-fpm.service.d/privatetmp.conf
# systemctl daemon-reload
# systemctl restart php-fpm
# systemctl show php-fpm | grep PrivateTmp
PrivateTmp=no
Upvotes: 4