Apache Virtual Hosts - permissions
One thing that can cause concern and configuration headaches is virtual hosts permissions.
Using the multiple hosts layout in this article is a good way of keeping your domains in one place and with easy access. Let's take a look at the permissions of the folders.
Reminder
A quick reminder of the layout used in these articles:
All the vhosts directories are place in the user's home directory under public_html. Each domain has it's own directory with a 'standard' set of folders such as public, private, logs, cgi-bin, backup and so on.
The multiple hosts layout article has some images to show the layout in detail.
Users
We have to think of who will want access to the folders. There are two users to consider.
The first is the Slice user - in this case my username is 'demo'. It is in demo's home directory that the public_html directory is placed.
Secondly is the Apache user. On Debian based systems it is usual for Apache to be 'www-data' and be in the 'www-data' group. Other Linux distributions use the user 'nobody' or even 'apache'.
Access
Now we need to think about what actions will need to be taken by what user.
Apache needs to be able to enter the public_html folder and to be able to read the public and private directories.
The logs are written by the 'parent' Apache process which is root so we don't have to worry about that (root will have access to the logs directory anyway - all other Apache processes are completed by the child process which will be 'www-data' or 'nobody').
Write access
OK, but what happens if Apache needs write access? An example of this would be uploading images or files.
One way would be to allow world write access to the folder (setting the permissions at 777). The problem with this is that the world has write access to the folder.
Even if you had a specific upload folder and were careful with your scripts, it still leaves a 777 folder exposed to the public.
Groups
Remember the layout being used is for single user Slices. I host many websites on one Slice and I am the only one who has access to it.
What if we placed the main user (demo) in the 'www-data' group? That way, any folder that Apache needs to write to, such as the image upload folder, would only need 660 permissions.
There is no need for any other system user to access those folders. This also stops the practice of having a folder with 777 permissions.
User setup
So let's start by adding the main user to the Apache user group:
sudo usermod -a -G www-data demo
That adds the user 'demo' to the 'www-data' group. Do ensure you use both the -a and the -G options with the usermod command shown above.
You will need to log out and log back in again to enable the group change.
Check the groups now:
groups
...
# demo www-data
So now I am a member of two groups: My own (demo) and the Apache group (www-data).
Folder setup
Now we need to ensure the public_html folder is owned by the main user (demo) and is part of the Apache group (www-data).
Let's set that up:
sudo chgrp -R www-data /home/demo/public_html
As we are talking about permissions I'll add a quick note regarding the sudo command: It's a good habit to use absolute paths (/home/demo/public_html) as shown above rather than relative paths (~/public_html). It ensures sudo is being used in the correct location.
If you have a public_html folder with symlinks in place then be careful with that command as it will follow the symlinks. In those cases of a working public_html folder, change each folder by hand.
Stickyness
Good so far, but remember the command we just gave only affects existing folders. What about anything new?
We can set the ownership so anything new is also in the 'www-data' group.
The first command will change all permissions in the public_html directory so, again, be careful if you have existing content and symlinks:
sudo chmod -R 2750 /home/demo/public_html
That will ensure that any new files are given the user 'demo' and the group 'www-data'.
If we need to allow write access to Apache, to an uploads directory for example, then set the permissions for that folder like so:
sudo chmod -R 2770 /home/demo/public_html/domain1.com/public/uploads
The permissions only need to be set once as new files will automatically be assigned the correct ownership.
DRY
This may get a bit tedious when you add new domains to your public_html folder.
In that case, I would create a 'skeleton' domain structure with the relevant permissions and simply copy it to the new domain:
cp -a /home/demo/public_html/skeleton /home/demo/public_html/my_new_domain
That way you have a nice and new set of folders with the correct permissions in one simple command.
Summary
Permissions are a sensitive topic and you do have to be careful with them. Don't just enter a 'chmod -R' command without thinking about the contents and symlinks.
I hope this helps alleviate concerns about vhosts and permissions.
I'd also like to thank Placid for his help in proof-reading this article - it was one I did not want to get wrong!
PickledOnion.

Subscribe to Feed
Article Comments:
dave commented 7 months ago:
Most of what are in the articles are easy to understand for me, however, some things like the line above I don't get 100%. I see that your changing the permissions of this directory and all underneath it, but I don't quite understand what the 2750 is doing there?
Thanks!
PickledOnion commented 7 months ago:
Dave,
I was a bit quick in that section.
In the section before we changed the ownership of the directory. Then moving onto the permissions (i.e. what the owner or group can actually do to the file) we set it at 2750.
The first number (2) sets up the folder so that any new files take on the owner:group we set previously. Without this any new files would still be under demo:demo ownership - this ensures a new file has demo:www-data ownership.
The last 3 numbers (750) mean the user has full rights over the directory (7), the group has read and execute rights (5) and the 'other' group has no rights whatsoever (0) - they can't even see the files.
Difficult to explain here but I hope that helps - there will be a permissions article or two in time.
PickledOnion.
downat420 commented 5 months ago:
I am having an issue and I think it is related. Server Specs Ubuntu 7.1.0 Apache2 php5 mysql
I use an open source social networking site called dolphin from boonex.com. I am hosting it myself until it is developed. Here is the problem:
When a user joins my site (so far only test users) the user information is saved in the mysql database but the profile is not created. For instance the site is located in
/var/www/sitename/community
when i attempt to view a user profile via the web i get a 404 error and this is the link.
www.sitename.com/community/profile
the problem is the profile folder is not being created in the
/var/www/sitename/community folder.
Let me know if your solution applies here. Feel free to send me an email.
Thanks in advance, zach
PickledOnion commented 5 months ago:
Hi downat420,
My answer is this: possibly :)
Sorry I can't be more specific but I have no idea what your software does.
It could be programming issue, it could be permissions. It could be a whole host of things.
All I can suggest is to try different permissions and see if it makes a difference.
PickledOnion.
travis commented 4 months ago:
Brent commented 2 months ago:
PickledOnion,
What would you recommend as far as permissions for a server that does have multiple users instead of just one?
I use the general virtual host layout structure you recommend, but do so in /var/www, and I have two groups: "www-data" and "www-admin". The "www-admin" group is for my other users that need write access to the site files. I resorted to using ACL's for adding both groups to the site files in order to avoid using 777 on the directories that Apache needs write access to, but have found maintaining ACL's to be a huge pain, and would rather return to simplicity.
Using 777 on the dirs that Apache needs write access to would free up the group section for my "www-admin" group and simplify things a lot, but I don't want to do it if it's such a security risk.
Any recommendations for me?
PJ commented 2 months ago:
Does the www-data group apply to nginx???
If not, do i need to create a new nginx group??
PJ.
BobbyL commented 2 months ago:
I may have run into the same issue as PJ.
groups
returns demo only
Did do something wrong?
I am not getting the "www-data" group and the "demo" group. I am setting my my server nginx.
Interestingly, on another server setup which also uses nginx I am getting the correct groups.
BobbyL commented 2 months ago:
Perhaps an answer to my own problem. After setting up with Capistrano, I now get both "demo" and "www-data" when I enter the groups command.
lambo commented about 1 month ago:
I am working on configuring nginx and there is a page that refers to this article about setting permissions on the folders for nginx. This article does not explain how to do this though. It says it follows the same principles, but nginx I would assume does not have a www-data folder. So how would this same permission setting be done for an nginx setup? Thanks in advance for any help here.
Timbo commented about 1 month ago:
After typing 'groups', you will only see 'demo' (I'm using nginx).
If you login and logout and use 'groups' again, you will see both 'demo' and 'www-data' after using the 'groups' command.
It confused me too :(
John commented about 1 month ago:
The article says you need to log out and log back in again to see the changes.
What is the problem?
Aero commented about 1 month ago:
Hey folks, if you want to get the groups for the username "www-data" type
You'll see a www-data user in the www-data group with nginx.
Marcus commented 28 days ago:
I've tried this, but it doesn't work for new files or directories created in the directories. New files are given -rw-r-r--
New directories are given drwxr-sr-x
Emmanuel commented 20 days ago:
As Marcus commented doing sudo chmod -R 2770 /home/demo/public_html/domain1.com/public/uploads does not give write access to the apache user for the sub folders you create . I think you also hae to set the umask of the demo user also to 0022
samuraipenguin commented 4 days ago:
I followed this article pretty much to the letter, and was fairly easily able to create a skeleton directory, and then script the addition of vhosts in this format. It's my first run at this script, but I wanted to share with the community: http://www.samurai-penguin.com/static/addvhost.txt
Please let me know if anything looks out of place, especially security-wise.