Optimal Permission Settings for PHP Session Directory in FastCGI/PHP-FPM Environments Running as Nobody


1 views

When dealing with PHP-FPM running under the 'nobody' user, session directory permissions become particularly tricky. The error message clearly shows the struggle between security and functionality:

PHP Warning: Unknown: open(/var/lib/php/session/sess_cskfq4godj4ka2a637i5lq41o5, O_RDWR)
failed: Permission denied (13) in Unknown on line 0

While setting chmod 777 /var/lib/php/session might temporarily solve the problem, it creates significant security vulnerabilities:

  • Any process on the system can write to the directory
  • Session hijacking becomes easier
  • Violates principle of least privilege

Here's the correct approach for CentOS/RHEL systems (adapt for your distro):

# Create the session directory if it doesn't exist
sudo mkdir -p /var/lib/php/session

# Set proper ownership
sudo chown nobody:nobody /var/lib/php/session

# Set secure permissions
sudo chmod 1733 /var/lib/php/session

The 1733 permissions break down as:

  • 1: Sticky bit prevents users from deleting others' files
  • 7: Owner (nobody) gets rwx
  • 3: Group gets wx (for directory operations)
  • 3: Others gets wx

For systems where you want more control:

# Create a dedicated group
sudo groupadd phpsession

# Add nobody and web server user to the group
sudo usermod -a -G phpsession nobody
sudo usermod -a -G phpsession nginx

# Set directory permissions
sudo chown root:phpsession /var/lib/php/session
sudo chmod 2770 /var/lib/php/session

Ensure your php.ini has the correct path:

; In /etc/php.ini or appropriate conf file
session.save_path = "/var/lib/php/session"
session.save_handler = files

For PHP-FPM pools configuration:

; In /etc/php-fpm.d/www.conf
php_value[session.save_path]    = /var/lib/php/session
php_value[session.save_handler] = files

If permissions still don't work:

  1. Verify the effective user with ps aux | grep php-fpm
  2. Check directory permissions with namei -l /var/lib/php/session
  3. Test write access as nobody: sudo -u nobody touch /var/lib/php/session/test

Remember that session files contain sensitive data. Additional hardening measures include:

  • Regularly clean old sessions with a cron job
  • Consider separate session directories for different PHP applications
  • Monitor the directory for unusual activity

When running PHP-FPM under the nobody user, session file permissions become crucial for proper application functionality. The error message clearly indicates the PHP process cannot write session data to the specified directory:

Warning: Unknown: open(/var/lib/php/session/sess_cskfq4godj4ka2a637i5lq41o5, O_RDWR)
failed: Permission denied (13) in Unknown on line 0

While setting permissions to 777 might temporarily solve the problem, it creates significant security vulnerabilities:

  • Any system user can modify session files
  • Potential for session hijacking attacks
  • Violates principle of least privilege

The proper solution involves creating a dedicated group that both the web server and PHP-FPM can access:

# Create a new group for shared access
sudo groupadd phpsess

# Add both nginx and nobody to the group
sudo usermod -a -G phpsess nginx
sudo usermod -a -G phpsess nobody

# Change directory ownership
sudo chown -R :phpsess /var/lib/php/session

# Set proper permissions
sudo chmod -R 0770 /var/lib/php/session

# Set sticky bit to maintain group ownership
sudo chmod g+s /var/lib/php/session

For more complex setups, consider these additional options:

Option 1: Specific PHP-FPM User

[www]
user = php-fpm-user
group = php-fpm-group

Option 2: Custom Session Path

Modify php.ini to use a custom session path:

session.save_path = "/path/to/custom/sessions"

After implementing changes, verify with:

# Check directory permissions
ls -ld /var/lib/php/session

# Check group membership
groups nobody
groups nginx

# Test session creation
php -r "session_start(); $_SESSION['test'] = 'value';"

If problems persist:

  1. Ensure SELinux contexts are correct if enabled:
    sudo chcon -R -t httpd_sys_rw_content_t /var/lib/php/session
    
  2. Verify PHP-FPM pool configuration matches system users
  3. Check for conflicting umask settings in PHP or system