oerdnj / deb.sury.org

Public bugreports for anything ppa:ondrej/*
821 stars 25 forks source link

Systemd services should be hardened #2050

Open martipoe opened 10 months ago

martipoe commented 10 months ago

Frequently asked questions

Is your feature request related to a problem? Please describe.

Hardening of the PHP-FPM systemd units has been implemented by the PHP devs and Distros like Ubuntu and CentOS.

Describe the solution you'd like

I would like to see some hardening applied to the systemd services. E.g. PrivateTmp=true is a standard feature of default PHP-FPM units from Ubuntu and CentOS repositories.

Distribution (please complete the following information):

Package(s) (please complete the following information): php*-fpm

Additional context The default configuration for PHP 8.1 does not include any security measures:

#/lib/systemd/system/php8.1-fpm.service

[Unit]
Description=The PHP 8.1 FastCGI Process Manager
Documentation=man:php-fpm8.1(8)
After=network.target

[Service]
Type=notify
ExecStart=/usr/sbin/php-fpm8.1 --nodaemonize --fpm-config /etc/php/8.1/fpm/php-fpm.conf
ExecStartPost=-/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
ExecStopPost=-/usr/lib/php/php-fpm-socket-helper remove /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

For comparison, a unit file from CentOS repos:

# It's not recommended to modify this file in-place, because it
# will be overwritten during upgrades.  If you want to customize,
# the best way is to use the "systemctl edit" command.

[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=notify
ExecStart=/usr/sbin/php-fpm --nodaemonize
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true
RuntimeDirectory=php-fpm
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
datadestroyd commented 10 months ago

Hardening of the PHP-FPM systemd units has been implemented by the PHP devs and Distros like Ubuntu and CentOS.

That is not true for Ubuntu. I just checked the service file on Ubuntu 22.04 (PHP 8.1): there are no hardening features enabled whatsoever.

Additionally, changing hardening options has the potential to break applications. For instance, setting NoNewPrivileges=true will prevent PHP from sending mail via sendmail.

I am not against hardening, but I think this should not be done by some minor update. Maybe introducing it with the next release, 24.04, would be acceptable.

Additionally, you can enable the hardening features yourself using systemctl edit.

oerdnj commented 7 months ago

Additionally, changing hardening options has the potential to break applications.

I've seen this too many times already.

I guess PrivateTmp=true might be safe, but what if somebody has already configured something that needs a pipe placed in /tmp? This has a potential to break stuff hard.

martipoe commented 7 months ago

Understood, I will close this issue.

oerdnj commented 7 months ago

You didn’t have to close the issue, but I need to hear from people running servers, what are the safe options to add.

Magissia commented 2 months ago

I never had issue adding PrivateTmp=true and ProtectSystem=full for php-fpm. Read/writes to /home is a real use when using a pool per website to allow the website owner to edit files themselves while chrooted to their /home.

AgentOak commented 1 month ago

You can't really make a one-size-fits-all configuration for php-fpm since it's used to run thousands of applications all of which have their own needs. I have a rather strict drop-in (with ProtectSystem=strict to mount everything read-only and a few ReadWritePaths) but that only works because I know my applications well and spent some time doing trial-and-error.

Upstream php repo has a pretty tame service unit that all *sensible* applications should work with: https://github.com/php/php-src/blob/master/sapi/fpm/php-fpm.service.in But then, imagine some questionable management panel that directly writes files in /etc. That would break with ProtectSystem=true. PrivateTmp=true could be problematic for apps that try to exchange files with other daemons by storing them in /tmp. The others should be fine.

If anything this repo could adopt the upstream template but shouldn't add anything on top: Sandbox-related issues are very hard to diagnose. All you get is generic "No such file or directory" or "Permission denied" errors. The very same errors you commonly hit when messing up file permissions or a path in some config - making it nearly impossible to google for. Even worse when the issue would be sury-specific.

On Debian 12 I additionally use the following:

ProtectKernelLogs=true
ProtectClock=true
ProtectHostname=true

# Don't allow setting SUID/SGID bits on files
RestrictSUIDSGID=true

# Block legacy ABI (such as x86 compatibility on x86_64) and rarely used system calls
SystemCallArchitectures=native
SystemCallFilter=@system-service
LockPersonality=true

# Hides other users processes from /proc
ProtectProc=invisible
# Hides non-process files from /proc like cpuinfo and meminfo
ProcSubset=pid

# Hides /home, /root and /run/user. Disable when you cannot move php apps out of /home
ProtectHome=true

# Disable SUID/SGID elevation. Disable when using mail(), i.e. messages pass through local mail daemon which requires sendmail/maildrop
NoNewPrivileges=true

Not security-related but nice to have:

# Restart if php-fpm hangs or crashes
Restart=on-failure
RestartSec=10
TimeoutStartSec=60
WatchdogSec=60

# Kill if stop takes too long. Should be >=max_execution_time so all requests may finish as usual
TimeoutStopSec=90
oerdnj commented 1 month ago

I guess it makes sense to merge the upstream to what we already have: https://github.com/php/php-src/blob/master/sapi/fpm/php-fpm.service.in