Apache and PHP – Recommended User and File Permissions for /var/www

apache-httpdlinuxPHPSecurityusers

I just spun up an Ubuntu 11.10 box and then ran apt-get install apache2 php5 to install apache2 and PHP 5 on the box. Now it is functioning as a "web server" and it loads the "It Works!" page. Now I'm trying to tighten up security and I have the following questions about linux web servers:

  1. Who should apache be running as?
  2. What group(s) should this user be in?
  3. What package(s) can make PHP (and Apache?) run as the owner of the files? (like on shared web hosts) Should I use these packages? Are they easy / feasible to maintain on a small system?
  4. What should the default permissions be for files and folders being served out to the web with apache running as www-data? For apache/php running as the user?

I have done the following things in examination of the default setup:

File Structure

When I cd / and do a ls -al listing of the contents, I see /var:

drwxr-xr-x 13 root root  4096 2012-02-04 20:47 var/

If I cd into var and do ls -al I see:

drwxr-xr-x  2 root root  4096 2012-02-04 20:47 www/

Finally, inside /var/www I see:

drwxr-xr-x  2 root root 4096 2012-02-04 20:47 ./
drwxr-xr-x 13 root root 4096 2012-02-04 20:47 ../
-rw-r--r--  1 root root  177 2012-02-04 20:47 index.html

My key takeaway is that so far all of these files belong to root:root, files have permissions of 644, and directories have permissions of 755.

Apache's Permissions

If I create a file as root in /var/www/test.php with the contents:

<?php echo shell_exec('whoami');

and load that file into a browser it tells me www-data, which is the same as in the /etc/apache2/envvars file:

export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

If I do ps aux | grep -i apache I see the following:

root      1916  1.2 104664  7488 Ss   20:47 /usr/sbin/apache2 -k start
www-data  1920  0.8 105144  5436 S    20:47 /usr/sbin/apache2 -k start
www-data  1921  1.0 105144  6312 S    20:47 /usr/sbin/apache2 -k start
www-data  1922  0.7 104688  4624 S    20:47 /usr/sbin/apache2 -k start
www-data  1923  0.7 104688  4624 S    20:47 /usr/sbin/apache2 -k start
www-data  1924  0.7 104688  4624 S    20:47 /usr/sbin/apache2 -k start
www-data  1925  0.7 104688  4624 S    20:47 /usr/sbin/apache2 -k start

So who is apache running as? It looks like perhaps the first process is as root, maybe from the /etc/init.d/apache script when the system started, and the other ones as www-data spawned from the first. Is that correct?

Next, if I type in groups www-data then I see www-data : www-data – so it looks to only be in the www-data group. I'm guessing this is standard practice as well.

Shared Hosting and Security

So if I understand things correctly, if apache is running as www-data and I want apache to be able to read a directory, the x bit needs to be set for the world (other) group (o+x), and that also needs to be set on all parent directories all the way up the chain (www, var). And if I want apache to be able to read from a file, then the o+r bit needs to be set.

Unfortunately I believe this introduces a security hole for multiple applications and/or multiple users on the same linux box: All web files need to be world-readable, and so they are also accessible by other applications and other users on the system. If one application installed on the system had a security vulnerability that allowed raw, unvalidated user input, which was then executed by PHP, a remote attacker could then browse all the other files on the web system which were world readable. Likewise, if the box had multiple users, and a user knew the path of another user's web files, s/he could then read the file contents (and see sensitive things like database connection strings, etc).

I've heard of two packages, suphp and phpsuexec that deal with allowing users' files to be served out "as them" on a shared system. One of the niceties of this is that it allows web applications (like WordPress) to create and modify files – very helpful for adding themes, plugins, and upgrading software. Of course it is probably more secure to do these things manually, but can a compromise be made perhaps with one of the packages mentioned above? Or by possibly using chown to make the wordpress directory group belong to www-data and set the sticky bit on the group (g+s)?

I have only used these as the end user of a web hosting company, and so I don't know the ins-and-outs of them, and if they are even reasonable to install on a small system, or if there are some other security measures I should use instead, but I thought I would mention them here as they seem like one possible way to address some of my concerns.

Back to the Questions

  1. Who should apache be running as?
  2. What group(s) should this user be in?
  3. What package(s) can make PHP (and Apache?) run as the owner of the files? (like on shared web hosts) Should I use these packages? Are they easy / feasible to maintain on a small system?
  4. What should the default permissions be for files and folders being served out to the web with apache running as www-data? For apache/php running as the user?

Best Answer

  1. not root
  2. not root
  3. SuEXEC
  4. Depends. 644 for files and 755 for folders are a safeish default.

Don't change ownership of anything to www-data unless you want php to be able to edit the contents of that file/folder

Irrespective of anything else you do: folders need read and execute permissions for the user to find files; files need read permissions for the user to read them. If you get any permissions errors when changing things - you've managed to remove these fundamentally required permissions.

If you are not writing any files via your php application, you can leave files owned by you:you. In this circumstance the world permission (xx4/5) is the one which applies.

If you leave the files as owned by you:you with file permissions of 644 (files) what that would mean is that only you can edit the website files - www-data is not you - so it cannot edit the files.

If you want to restrict access to apache + you and block out all other access chown -R you:www-data *. With file permissions of 640 and folder permissions of 750 you can edit, www-data can read - because then apache reads the group permission (x4/5x).

Restrict to a minimum the paths you allow apache/php to write to - if there's a tmp dir the application needs to write to - allow it to write to that folder only - and for any writable locations if at all possible make sure it's outside the document root or take steps to ensure this writable path is not web-accessible.

Note that "you" should not be root. Allowing direct ssh access as root is an indicator of other security lapses (such as not disallowing password login), but that's a whole bunch of questions unto itself.

Related Question