9

I have a Debian server on which I am running Apache HTTPD.

I have configured it to use certain SSL certificates which reside in /etc/ssl/private/. Only root user has read-write access to this directory. The HTTPD process is run as www-data user, but it is started using an init.d script (that comes with HTTP installation) by root user.

When apache2 process is running as www-data and the SSL certs can only be read by root user, how is Apache able to read the certs and function without any problem?

I am facing similar problem with an init.d script that I have written for a custom server written in Python. This init.d script was working just fine as long as I was not using SSL certs. As soon as I added these certs, the process just won't start because it won't be able to read the certs as www-data user can't read the certs.

I have used nginx as well in a similar situation and the results were similar as they were with Apache. So how do these two projects tackle this problem?

vaidik
  • 2,191
  • 1
  • 16
  • 22
  • "I am facing similar problem" > What is your exact 1st problem - I don't see it? Also, why is your 'custom' 'server' init script written in python? Start Apache using the provided system server init script for your OS; it's what it for and is thoroughly tested. Then you can use python all you want to interact with server which is running as root. Do not start server any other way! What is the reasoning behind starting Apache or any other system/root service with a python script? – B. Shea Sep 11 '17 at 14:46

3 Answers3

4

When you run

ps aux | grep apache2

You'll notice that there is a process owned by root, I think this may be the reason, because this process can access the files/dirs owned by root.

M. Adel
  • 401
  • 5
  • 7
  • Hmm. Possible but there is still not enough evidence to prove that. Did lsof -p PID_OF_ROOT_OWNED_PROCESS and got nothing that could show that this process is holding an fd for the cert file. Its possible that the user read the contents and then released the fd. But as I said, its not conclusive. – vaidik Apr 30 '14 at 10:14
  • Good answer.. I have expanded on why Apache IS root and not 'www-data' or whoever else. Those are just the children/workers not the parent. – B. Shea Sep 11 '17 at 14:54
3

Root runs Apache in most situations.
Hence root is the owner of the main "parent" process.

When Apache starts, it (normally) should have been started using root (partly why you have to use sudo with the system service manager to start it correctly). Further, the parent process (running as the root user) then reads the configuration(s) in, binds to the given system ports (usually 80 and 443) and other tasks. These ports are also considered privileged (anything under 1024). Once completed, it spawns child processes (which can also use "workers" via the core modules).

Since the parent process is root and the children/workers are run under 'www-data' (or another non-privileged user), Apache can still bind to system ports and deal with root privilege files such as private SSL keys/etc in this manner.

"While the parent process is usually started as root under Unix in order to bind to port 80, the child processes and threads are launched by the server as a less-privileged user. The User and Group directives are used to set the privileges of the Apache HTTP Server child processes. The child processes must be able to read all the content that will be served, but should have as few privileges beyond that as possible. In addition, unless suexec is used, these directives also set the privileges which will be inherited by CGI scripts.*"

From: https://httpd.apache.org/docs/2.4/mod/prefork.html#how-it-works

B. Shea
  • 829
  • 14
  • 29
  • 2
    Thanks @bshea for the simple and well written explanation, came here because of the same original question since when one runs "apache2ctl -t" it will throw an error "SSLCertificateKeyFile: file '/etc/ssl/private/server.key' does not exist or is empty" as expected or better now I understand why since only "sudo apache2ctl -t" can do the syntax check while also accessing the file that requires root privileges. :) – Markus Jul 01 '20 at 12:13
1

Only the private key is protected as the certificate is publicly available in the /etc/ssl/certs directory. The /etc/ssl/private is root only readable but ssl-cert user group is granted to execute (ssl-cert group X rights). This system group is perhaps the one involved in the SSL authentication method.

could you try :

sudo chown root:ssl-cert /etc/ssl/private/your-private.key

reload apache and check again ?

I have purged all Apache2 installations on my servers so I can't test this anymore.

Hope that helps, regards

Emmanuel BRUNET
  • 1,286
  • 3
  • 19
  • 46
  • The problem is that Apache is not able to access the keys. Actually it is able to access them with root:root ownership. /etc/ssl has root:ssl-certs ownership but the key files have root:root ownership. And everything works. I came across this post http://gnuwhatimsaying.com/private-key-permissions/ which can be one of the best explanations. – vaidik May 03 '14 at 07:16
  • Sure it will run fine under root but I thought you just didn't want it to run as root. – Emmanuel BRUNET May 03 '14 at 07:38
  • So if you notice in the process list spit out by the `ps` command, Apache is run as www-data user and not as root. This user is not added in the ssl-certs group as well. So this user does not have access to any certs i.e. private or public. But, the init.d script is always run as root. I am assuming that the certs are picked up by the init.d script for Apache and passed to it somehow. Does that sound correct or close? – vaidik May 03 '14 at 20:09
  • I am interested in understanding this because I have written a server in Python using Tornado and it is not proxied behind Apache or Nginx. It runs as an independent server. When I added SSL support to this server, it wouldn't start properly because I run the server as www-data user. – vaidik May 03 '14 at 20:22
  • 1
    One thing I don't understand is that normally, at startup the initd launches processes with root authority. I think apache starts running unbder root user and then forks its worker program(s) under www-data. At init under root it should be able to read the private secured key – Emmanuel BRUNET May 06 '14 at 06:27
  • 1
    When using the service command you also need to use the root account so ... rights should be enough – Emmanuel BRUNET May 06 '14 at 06:54
  • Yeah I think that's how it is. I am starting my process using the start-stop-daemon command and pass the user and group to use to it. So my process is always running as www-data:www-data. Apache on the other hand does not seem to be using that. If you change your answer, I'd happily accept it as the correct answer. – vaidik May 07 '14 at 09:22