When working with Apache2 on modern Linux distributions using systemd, you might encounter an unexpected behavior where files intended for /tmp
end up in paths like:
/tmp/systemd-private-015eb2e9f67b4eef862c68e99fe0ba30-apache2.service-9h6i08/tmp/somename
This occurs because systemd creates private temporary directories for services by default, a feature called PrivateTmp.
The PrivateTmp feature provides several security benefits:
- Isolates temporary files between services
- Prevents information leaks through /tmp
- Cleans up all temporary files when service stops
To disable this behavior and use the regular /tmp directory:
sudo systemctl edit apache2.service
Add these lines to the override file:
[Service]
PrivateTmp=false
Then reload systemd and restart Apache:
sudo systemctl daemon-reload
sudo systemctl restart apache2
If you prefer to keep PrivateTmp enabled but need consistent paths, modify your PHP code:
// Get the actual temp directory
$temp_dir = sys_get_temp_dir();
// Use it in your file operations
$file_path = $temp_dir . '/somename/file.txt';
file_put_contents($file_path, $data);
Check if the change took effect:
systemctl show apache2.service | grep PrivateTmp
Should return: PrivateTmp=no
Before disabling PrivateTmp, consider:
- Review why your application needs files in /tmp
- Implement proper file permissions (chmod 600 for sensitive files)
- Consider using your application's private storage instead
Add this to your PHP script for debugging:
error_log("Actual temp directory: " . sys_get_temp_dir());
error_log("Intended path: /tmp/somename");
error_log("Full path: " . sys_get_temp_dir() . '/somename');
When running Apache under systemd, you might notice files being saved to paths like:
/tmp/systemd-private-*-apache2.service-*/tmp/somename
instead of the expected /tmp/somename
. This occurs because systemd enables PrivateTmp
by default for service isolation.
This security feature creates:
- Process isolation through namespace separation
- Protection against /tmp race conditions
- Cleaner cleanup when services restart
- Prevention of /tmp information leaks
To disable this behavior:
# Edit the Apache service file
sudo systemctl edit apache2.service
# Add these contents:
[Service]
PrivateTmp=false
# Then reload and restart
sudo systemctl daemon-reload
sudo systemctl restart apache2
If you need to maintain security while working with /tmp:
// PHP code to handle both scenarios
$tmp_base = is_dir('/tmp/systemd-private-*') ?
glob('/tmp/systemd-private-*/tmp')[0] :
'/tmp';
$file_path = $tmp_base . '/somename/file.txt';
file_put_contents($file_path, $data);
For permanent changes across all services:
# Edit systemd's global config
sudo nano /etc/systemd/system.conf
# Add or modify:
DefaultPrivateTmp=no
Check the effective settings with:
systemctl show apache2 | grep PrivateTmp
You should see PrivateTmp=no
after making these changes.
Before disabling PrivateTmp, consider:
- Using application-specific directories in /var/tmp
- Implementing proper file permissions
- Setting up tmpwatch or similar cleanup mechanisms
- Using PHP's sys_get_temp_dir() for portable temp paths