How to Run Apache as a Non-Root User
Running the Apache HTTP Server as a non-root user is a critical security best practice that minimizes the potential damage of a server compromise. This article provides a quick overview of why this configuration matters and walks you through the step-by-step process of modifying the Apache configuration files, adjusting file permissions, and managing privileged ports so your web server can operate safely with reduced privileges.
Why Run Apache as a Non-Root User?
By default, the Apache parent process often starts as
root so it can bind to privileged ports like 80 (HTTP) and
443 (HTTPS). However, if an attacker exploits a vulnerability in a
server running entirely as root, they gain full administrative control
over the entire system. Configuring Apache to run its worker
processes—or the entire service—under a dedicated, unprivileged user
account restricts an attacker’s access strictly to the web server’s
isolated environment.
Step 1: Create a Dedicated User and Group
Before changing the configuration, you need a dedicated, non-privileged system user and group for Apache if they do not already exist.
sudo groupadd www-data
sudo useradd -g www-data -s /bin/false -d /var/www www-dataSetting the shell to /bin/false ensures that no one can
log into the system directly using this account, adding an extra layer
of security.
Step 2: Modify the Apache Configuration File
Next, you need to instruct Apache to use the new user and group. Open
your Apache configuration file (usually httpd.conf or
apache2.conf located in /etc/httpd/conf/ or
/etc/apache2/).
Look for the User and Group directives and
update them:
User www-data
Group www-dataStep 3: Adjust File and Directory Permissions
The new non-root user must have permission to read the website files and write to specific logging or cache directories, but it should not own the root configuration files.
| Directory/File Path | Required Permission | Purpose |
|---|---|---|
/var/www/html |
Read & Execute (rx) |
Allows Apache to serve web content |
/var/log/apache2 or /var/log/httpd |
Read & Write (rwx) |
Allows Apache to write error and access logs |
/etc/apache2 or /etc/httpd |
Read-Only to root | Prevents the non-root user from modifying server configs |
Set the ownership of your web root directory using the following commands:
sudo chown -R root:www-data /var/www/html
sudo chmod -R 755 /var/www/htmlStep 4: Handle Privileged Port Restrictions (Optional)
Linux kernels prevent non-root users from binding to ports below
1024. If you plan to start the master Apache process completely as a
non-root user (rather than starting as root and dropping privileges to
www-data), you have two main options to use ports 80 and
443:
- Use setcap (Recommended): Grant the Apache binary specific permission to bind to privileged ports without running as root.
sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/apache2- Port Forwarding: Configure Apache to listen on a
non-privileged port like 8080, and use a firewall rule (like
iptablesorufw) to redirect incoming traffic from port 80 to 8080.
Step 5: Test and Restart Apache
Always test your configuration for syntax errors before restarting the service to avoid unexpected downtime.
sudo apachectl configtestIf the output reads Syntax OK, restart the Apache
service to apply the changes:
sudo systemctl restart apache2You can verify that the worker processes are running under the
unprivileged user by executing ps aux | grep apache2 or
ps aux | grep httpd in your terminal.