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.
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).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:
- Source control like git or svn
- Users in a group like "websites" (or even added to "www-data")
- Servers like apache or lighthttpd
- 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
- all files shareable by these four entities
- all files non-executable by mistake
- block everyone else from the directory entirely
- 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.
After more research it seems like another (possibly better way) to answer this would be to setup the www folder like so.
sudo usermod -a -G developer user1
(add each user to developer group)sudo chgrp -R developer /var/www/site.com/
so that developers can work in theresudo chmod -R 2774 /var/www/site.com/
so that only developers can create/edit files (other/world can read)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
I'm not sure whether it's "right", but here's what I do on my server:
Keep in mind that you should have the execute bit enabled on directories so that you can list the contents.
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 byroot: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
2) Add users to www-data
Then we need to add the current user (and anyone else) to the www-data group
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).
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?
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.
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
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:
Adding to @Xeoncross's answer, I think it would be good to configure permissions on files and directories separately.
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.