I am going through an audit at work, and there is a company requirement that certain services do not run as the root user for linux systems. Apache starts the first process as the root user to bind to port 80 (or 443) then spawns the remaining processes as www-data. Is there a way to configure apache and Ubuntu (14.04) to start the first process as www-data also?
3 Answers
I disagree with the existing answer (and a hundred answers around the Internet).
It is possible to run Apache2 as something other than root.
That's not how it is by default though and it's that default behaviour that ships with Ubuntu that is making things really difficult for you. All its scripts and configuration expect to use the root-then-drop-privileges model.
I'll just address the things commonly cited as "definitely needing root" (above and elsewhere):
Port 80. Forget for a minute that you might want to run on an unprivileged port (some people do, I used to run Apache like this behind Nginx)... You can still bind low ports as non-root using the Linux capabilities framework (since
2.6.24
); giving Apache the rights to bind to whatever ports it likes, regardless of user:sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/apache2
Or you can use iptables to redirect port 80 to an unprivileged port.
Reading config files and certificates. By default, the config can be read by any user. If you block
www-data
(or whatever user is running Apache) from reading config or certificates —which you can— you'll break the server.Some people talk about the initial root process as if it can be used to get privileges after startup. That's not the case. That would be horribly insecure. It just marshals unprivileged child processes.
Truth is you can break things to make this work. Don't do this. At least not until you've read the whole post.
sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/apache2
sudo /etc/init.d/apache2 stop
sudo chown -R www-data: /var/{log,run}/apache2/
sudo -u www-data apache2ctl start
And there you are. Running Apache like a badass as www-data
.
But I wouldn't do this in production. My code above doesn't have an init script for it so you would need to replace or "fix" /etc/init.d/apache2
to stop a root-run version being run, and start your www-data version. That's not a small undertaking; look at the script.
More than anything, the privilege-de-escalation model Apache has been using is battle tested. For years. Other servers do it that way too. It's not evil.
If your admins are going to get in a hyper-tiffy about what you're running, you have a couple of options:
Do it in a VM (like I did for testing this answer).
lxc
,docker
, etc, etc, etc. Minimal setup, lovely light and clean and can run as a "normal" user on the outside while looking like bare metal on the inside.Use a httpd that doesn't need root. Apache has a whole ecosystem around it that expects certain things so it's not a good choice. But whichever you pick, you'll likely have to fight their init scripts.
If you only need super-basic stuff on a non-priv port, you could run:
python -m SimpleHTTPServer 8000
-
FWIW I didn't say you can't, I said it'd be difficult... and a substantial headache.– Thomas Ward ♦Nov 5, 2015 at 0:22
-
2
-
3+1 excellent answer and recommendations. Another reason why I wouldn't do it is because when
apt
/dpkg
upgrades theapache2
package it will undo some things you did, thus probably breaking your setup. You could install apache from source instead of from the repos, but then you must update it manually everytime there is an update available which is a PITA. Nov 5, 2015 at 9:37 -
+1 for
python -m SimpleHTTPServer 8000
. It helped me to run on server which I don't have root access to install apache.– vardhanJan 14, 2017 at 10:48
The Short Answer:
You cannot make the first master Apache process start as non-root for the master process in a sane way. This is because the master process is required to run as superuser in order to bind to port 80 (HTTP) and 443 (HTTPS), and to access configuration files (in /etc/apache2/
by default) so the workers know what they're supposed to do.
Details on this are below, and many web servers in the repositories have similar types of setups (NGINX operates on the same basic principles as well).
The Details
The Apache Master Process - This Accesses Configuration Files and Binds Workers to Ports <= 1024:
Apache's master process needs to run as root
.
This is because all the configuration files inside of /etc/apache2/...
are typically owned, as root, and in order to access (some) SSL private certificate data (/etc/ssl/private/...
usually), it will need superuser power.
Administrative access is also needed in order to bind to ports less than 1024, which include port 80 (HTTP) and 443 (HTTPS), for a web server working with typical HTTP / HTTPS ports to work properly on those ports.
The Master process doesn't do much more than this, really, and doesn't handle actual requests from clients, nor does it actually interact with web docroots, etc.
The Apache Worker Processes - They Handle Requests from and Responses To Web Browsers:
Apache's workers actually handle requests coming in to the web server, and handle accessing data on the system and sending the response to clients. This is, I believe, where your IT policy really is talking about running as non-root.
This runs as www-data
which is not an administrator-level account, and does not have elevated privileges. This is where standard access controls on the system are usable, and is really what the "Cannot run as root" restriction really covers - in so much that you do not want the worker processes to be running as root/superuser.
Why I think there is miscommunication between policy and you, or why I think your IT policies need revisited and you should be talking to the IT people in your environment:
If your company / workplace is stating "We cannot let Apache run as root at all", then check with the company's IT staff.
The reason that this is a 'bad' or 'misinterpreted' policy is because you cannot use http://somewebaddress.tld
or https://somewebaddress.tld
on your domain if Apache cannot bind to port 80 or 443 respectively. If they do not want the master process to run as root, then you will have to manually change the ownership of /etc/apache2/*
or provide a separate data directory for configurations, and then have all Apache-served sites listen on ports higher than 1024.
-
This seems like a good explanation, but in the event that the OP's audit isn't satisfied, can't you just bind Apache to a high port (without root), and then use a system-level port reroute (e.g., with
iptables
) to make traffic on port 80 go to the Apache port? Maybe that's better scoped to a completely separate answer, though. Nov 5, 2015 at 0:00 -
@apsillers potentially, however that's a different question that's outside the scope of this one. Even so, the Apache package is programmed as a service to run via root. You could run Apache manually but you'd still need 'root' access for all that stuff. You may also run into certain web applications (wordpress, etc.) not behaving correctly with that setup.– Thomas Ward ♦Nov 5, 2015 at 0:02
Using sudo
with access configured only to the apache control scripts is generally considered best practice. Doesn't completely eliminate the transient "root" state at the beginning but any security auditor that doesn't understand this is not worth the money they are getting paid.
It's also fairly straightforward to install a custom version of Apache in user space to setup all file ownership to a less-privileged user who only has this controlled elevated-privilege through sudo.
-
This will still launch the Apache master process as root, which may not be permitted by the policy, as I state in my answer in the description of why the master process runs as root or with superuser powers. In my opinion, this answer doesn't add anything. (This would not solve the port binding issues either, and I don't think they want to custom-build Apache)– Thomas Ward ♦Nov 5, 2015 at 0:10
-
hah... my clarification crossed paths with your comment... you're too fast for me.Yes, you are correct about it starting the trainsmaster process as root, however, i believe it doesn't directly provide the answer as to what is best practice for security reasons. Nov 5, 2015 at 0:18
-
True, however this is considered a 'secure' setup if the workers which actually handle website requests/data are unprivileged. I have yet to find a compiled-from-source version that doesn't deviate from Apache that actually can run the master process correctly as non-root...– Thomas Ward ♦Nov 5, 2015 at 0:19
-
sigh... hitting return in comments submits... trying again... you are correct that it is transiently started as root but if you look at the non-transient processes... they are all the non-root user. This is best practice. Port binding to a low port is done just fine. Any security auditor that wouldn't accept this is quit simply worthless. Nov 5, 2015 at 0:22
-
Thanks for you comments/answers...I'm going to take the approach of telling them it's not feasible.– BeermanNov 5, 2015 at 16:14