Why does a web server like Apache run some processes as root and most as www-data?
Binding to ports below 1024 needs root, so a small root parent process opens ports 80 and 443; the processes that handle requests run as the unprivileged service account www-data.
ps -ef | grep apache shows one parent process as root and several worker processes as www-data. The split follows least privilege:
- On Linux only root may bind ports 1–1023, the privileged ports, by default.
- The code that parses requests from the internet is the part most likely to be exploited. If a worker is compromised, the attacker gets
www-data, a user that can do very little, instead of root.
The best practice goes one step further: run the application without any root rights on a port above 1023, and get traffic from port 80 to it with an iptables redirect or a reverse proxy. (A more targeted option is the capability CAP_NET_BIND_SERVICE, which allows low ports and nothing else.)
Some services still run as root because they need privileged operations. SSSD is an example: it has to read the host's Kerberos keytab and serve logons for every user. Recent SSSD versions can run most of their processes as a non-root sssd user.
Go deeper:
man7.org: capabilities(7) —
CAP_NET_BIND_SERVICEand the other pieces root is split into.sssd.io: Running SSSD as a non-root user — which SSSD tasks really need root and how it drops privileges.
Wikipedia: Principle of least privilege — the principle behind the root/www-data split.