76

Updated Summary

The /var/www directory is owned by root:root which means that no one can use it and it's entirely useless. Since we all want a web server that actually works (and no-one should be logging in as "root"), then we need to fix this.

Only two entities need access.

  1. PHP/Perl/Ruby/Python all need access to the folders and files since they create many of them (i.e. /uploads/). These scripting languages should be running under nginx or apache (or even some other thing like FastCGI for PHP).

  2. The developers

How do they get access? I know that someone, somewhere has done this before. With however-many billions of websites out there you would think that there would be more information on this topic.


I know that 777 is full read/write/execute permission for owner/group/other. So this doesn't seem to be needed correct as it gives random users full permissions.

What permissions are need to be used on /var/www so that:

  1. Source control like git or svn
  2. Users in a group like "websites" (or even added to "www-data")
  3. Servers like apache or lighthttpd
  4. And PHP/Perl/Ruby

can all read, create, and run files (and directories) there?

If I'm correct, Ruby and PHP scripts are not "executed" directly - but passed to an interpreter. So there is no need for execute permission on files in /var/www...? Therefore, it seems like the correct permission would be chmod -R 1660 which would make

  1. all files shareable by these four entities
  2. all files non-executable by mistake
  3. block everyone else from the directory entirely
  4. set the permission mode to "sticky" for all future files

Is this correct?

Update 1: I just realized that files and directories might need different permissions - I was talking about files above so i'm not sure what the directory permissions would need to be.

Update 2: The folder structure of /var/www changes drastically as one of the four entities above are always adding (and sometimes removing) folders and sub folders many levels deep. They also create and remove files that the other 3 entities might need read/write access to. Therefore, the permissions need to do the four things above for both files and directories. Since none of them should need execute permission (see question about ruby/php above) I would assume that rw-rw-r-- permission would be all that is needed and completely safe since these four entities are run by trusted personnel (see #2) and all other users on the system only have read access.

Update 3: This is for personal development machines and private company servers. No random "web customers" like a shared host.

Update 4: This article by slicehost seems to be the best at explaining what is needed to setup permissions for your www folder. However, I'm not sure what user or group apache/nginx with PHP OR svn/git run as and how to change them.

Update 5: I have (I think) finally found a way to get this all to work (answer below). However, I don't know if this is the correct and SECURE way to do this. Therefore I have started a bounty. The person who has the best method of securing and managing the www directory wins.

7 Answers 7

55

After more research it seems like another (possibly better way) to answer this would be to setup the www folder like so.

  1. sudo usermod -a -G developer user1 (add each user to developer group)
  2. sudo chgrp -R developer /var/www/site.com/ so that developers can work in there
  3. sudo chmod -R 2774 /var/www/site.com/ so that only developers can create/edit files (other/world can read)
  4. sudo chgrp -R www-data /var/www/site.com/uploads so that www-data (apache/nginx) can create uploads.

Since git runs as whatever user is calling it, then as long as the user is in the "developer" group they should be able to create folders, edit PHP files, and manage the git repository.

Note: In step (3): '2' in 2774 means to 'set Group ID' for the directory. This causes new files and sub directories created within it to inherit the group ID of the parent directory (instead of the primary group of the user) Reference: http://en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_directories

6
  • Looks reasonable to me.
    – wazoox
    Mar 26, 2010 at 11:24
  • Good. Maybe if I can confirm this with a couple more people I'll be using this approach. It seems to be the best answer I have been able to squeeze out of people.
    – Xeoncross
    Mar 26, 2010 at 18:59
  • You aren't specifying who would be the owner of the files. Would you leave it as root? Then only sudoers can edit your uploads folder (probably not what you intended).
    – Nic
    Mar 26, 2010 at 23:18
  • Yes, root would remain the owner. However, since the group owner is now "developer" (and has wrx permission) then all the devs (and apache/nginx) could also read. No need for sudo.
    – Xeoncross
    Mar 27, 2010 at 3:00
  • 7
    One more thing to watch for is umask. Many systems have a default umask of 022 which will remove write permissions for both group and public on new files. I suspect you want 002 (no write for public) or 007(no access for public). You can set the umask in Apache's config and/or the startup scripts for any process that needs access to the directory. Don't forget to add this to /etc/profile or /etc/bashrc so that it is set by default for your developers as well Mar 27, 2010 at 15:06
8

I'm not sure whether it's "right", but here's what I do on my server:

  • /var/www contains a folder for each website.
  • Each website has a designated owner, which is set as the owner of all files and folders in the website's directory.
  • All of the users that maintain the website are put into a group for the website.
  • This group is set as the group owner of all files and folders in the directory.
  • Any files or folders that need to be written by the webserver (ie. PHP) have their owner changed to www-data, the user that apache runs under.

Keep in mind that you should have the execute bit enabled on directories so that you can list the contents.

5
  • How does git/svn or PHP create new folders then?
    – Xeoncross
    Mar 22, 2010 at 16:10
  • 2
    PHP runs in the same user context as the webserver, so it can create files and folders in any directory owned by the webserver. There are generally only a few folders like this (/uploads/ for example). I'm not sure about git/svn - could you add them to the group account that controls the website?
    – Nic
    Mar 22, 2010 at 20:00
  • apparently git runs as the user running it - just like any other tool.
    – Xeoncross
    Mar 24, 2010 at 3:30
  • Then add the git user to the apache group and give the folder group write permissions. Mar 26, 2010 at 11:48
  • I just said, git doesn't have a user - it runs as the current user using it.
    – Xeoncross
    Mar 26, 2010 at 18:58
7

After doing more research it seems that git/svn TOOLS are NOT a problem since they run as whatever user is using them. (However, the git/svn daemons are a different matter!) Everything I created/cloned with git had my permissions and the git tool was listed in /usr/bin which fits this thesis.

Git permissions solved.

User permissions seems to be solvable by adding all users that need access to the www directory to the www-data group that apache (and nginx) run as.

So it seems that one answer to this question goes like this:

By default /var/www is owned by root:root and no one can add or changes files there.

1) Change group owner

First we need to change the www directory group to be owned by "www-data" instead of "root" group

sudo chgrp -R www-data /var/www

2) Add users to www-data

Then we need to add the current user (and anyone else) to the www-data group

sudo usermod -a -G www-data demousername

3) CHMOD www directory

Change the permissions so that ONLY the owner (root) and all users in the group "www-data" can rwx (read/write/execute) files and directories (no one else should even be able to access it).

sudo chmod -R 2770 /var/www

Now all files and directories created by any user that has access (i.e. in the "www-data" group) will be readable/writable by apache and hence php.

Is this correct? What about files that PHP/Ruby create - can the www-data users access them?

3
  • 6
    I don't like the idea of having all web files writable by PHP, it increases your possible exposure if there is a script vulnerability.
    – Nic
    Mar 24, 2010 at 14:49
  • Ok, well I know I use PHP to create lots of text, tar, log, and image files (plus folders) so I was just assuming that everything should be writable. However, perhaps your right and PHP should be able to only CHANGE FILES IT CREATES which would be harmless since 99% of all PHP apps never makes script files. The other choice seems to be to only allow certain directories PHP write access (/uploads/) which doesn't make since because then PHP could still be used to create something bad there. Any ideas?
    – Xeoncross
    Mar 24, 2010 at 16:31
  • 2
    Try to keep script and data separate. Even if an attacker manages to drop something in /uploads/, it shouldn't be executable. Security in layers is key.
    – Nic
    Mar 26, 2010 at 1:16
6

Stickiness is not permissions inheritance. Stickiness on a directory means that only the owner of a file, or the directory owner, can rename or delete that file in the directory, despite the permissions saying otherwise. Thus 1777 on /tmp/.

In classical Unix, there is no permissions inheritance based on the file-system, only on the current process' umask. On *BSD, or Linux with setgid on the directory, the group field of newly created files will be set to the same as that of the parent directory. For anything more, you need to look into ACLs, with the 'default' ACL on directories, which do let you have inherited permissions.

You should start by defining: * what users have access to the system * what your threat model is

For instance, if you're doing web hosting with multiple customers and you don't want them seeing each others files, then you might use a common group "webcusts" for all those users and a directory mode of 0705. Then files served by the webserver process (not in "webcusts") will see the Other perms and be allowed; customers can't see each others files and the users can mess with their own files. However, this does mean that the moment you allow CGI or PHP you have to make sure that the processes run as the specific user (good practice anyway, for multiple-users-on-one-host, for accountability). Otherwise, customers could mess with each others' files by having a CGI do so.

However, if the run-time user for a website is the same as the owner of the website, then you do have issues with not being able to protect content from abusers in the case of a security hole in the script. Which is where dedicated hosts win, so that you can have a run-time user distinct from the static content owner and not have to worry so much about interaction with other users.

3
  • Good answer. On MacOS X, the system behaves as if the SGID bit is on the directories automatically. The sticky bit usually means you can only remove the file if you can write it. That is, anyone can remove a publicly writable file in /tmp. On MacOS X, /tmp is a symlink to a private directory for the user - so there is no sharing after all. Mar 22, 2010 at 5:19
  • Thanks for the answer, I have updated the question with more information.
    – Xeoncross
    Mar 22, 2010 at 16:09
  • Jonathan: the sticky bit means only the owner of the directory, or the owner of the file, can rename or delete it (ie, act upon its entry in the directory 'file'). Permissions on the individual file do not come into play for these directory operations (rename(), unlink()), only for actions on the file itself (open()). This is the "usual" behaviour.
    – Phil P
    Mar 29, 2010 at 23:37
2

I do believe that the best way to do this is using Posix ACLs. They are comfortable to work with and offer all the functionality you need.

http://en.wikipedia.org/wiki/Access_control_list#Filesystem_ACLs

2
  • +1 for the helpful information about ACL's. However, I don't want extra junk bogging the system down just to manage a simple server with a couple of developers. I'm also not comfortable with recompiling the Kernel in order to use ACL's.
    – Xeoncross
    Mar 26, 2010 at 17:01
  • @Xeoncross: ACLs dont bog down anything. They are just metainformation like normal file permissions. It's not all that "extra" and complicated, I believe that it's the simplest and best way to manage permissions rather than some confusing sticky/group/whatever solution. Don't be scared, just remount with acl and give it a try! Mar 28, 2010 at 18:21
1

The owner of the file should be the person who creates it, while the group should be www-data. The mode for directories/files is then in general 755/644. While for directories and files the group needs write access the mod is 775/664. Assume paddy is the developer. Altogether this makes:

chown -R paddy:www-data /var/www/websiteindevelopment
chmod -R 755 /var/www/websiteindevelopment
chmod -R 775 /var/www/websiteindevelopment/directorywritablebygroup
find /var/www/websiteindevelopment -type f -perm 755 -print -exec chmod 644 {} \;  
find /var/www/websiteindevelopment -type f -perm 775 -print -exec chmod 664 {} \;
0

Adding to @Xeoncross's answer, I think it would be good to configure permissions on files and directories separately.

sudo find /var/www -type d -exec chmod 775 {} \;  # Change permissions of directories to rwxrwxr-x
sudo find /var/www -type f -exec chmod 664 {} \;  # Change file permissions to rw-rw-r--

This will allow developers to create and modify directories within /var/www. Which seems important because, developers might need to create additional directories or remove a directory that's no longer needed.

It will also allow developers to create and modify code files (read HTML, PHP files and the like). But, will still only allow read-only access for everyone else.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .