50

I have a simple web server setup for some websites, with a layout something like:

site1: /var/www/site1/public_html/

site2: /var/www/site2/public_html/

I have previously used the root user to manage files, and then given them back to www-data when I was done (WordPress sites, needed for WP Uploads to work). This probably isn't the best way.

I'm trying to find a way to create another user (lets call it user1) that has permission to edit files in site1, but not site2, and doesn't stop the files being 'owned' by www-data. Is there any way for me to do this?

6 Answers 6

89

If we check ownership of site1, we will find something like this,

ls -ld /var/www/site1/
drwxr-xr-x 2 root root 4096 Oct 24 21:06 site1/

This means that the directory is owned by user root, group root. While user root has write permission (plus read and execute permissions) to the directory, group root has only read and execute permissions.

We will want to change the group ownership to another (new) group and add user1 to that particular group. We will give write permission to that particular group as well.

Create a new group,

sudo addgroup site1

Add user1 to the newly created group,

sudo adduser user1 site1

Check that user1 is really in that group,

groups user1

The output should be a list something like,

user1 : <other-groups> site1

Now we can change the group ownership of your intended directory.

sudo chown -vR :site1 /var/www/site1/
changed ownership of `/var/www/site1/' from root:root to :site1

Grant write permission to this new group owner,

sudo chmod -vR g+w /var/www/site1/
mode of `/var/www/site1/' changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x)

Check that all the changes are indeed there,

ls -ld /var/www/site1/
drwxrwxr-x 2 root site1 4096 Oct 24 21:06 /var/www/site1/

So, the directory now is owned by user root, group site1. Both user root and group site1 have write permission (plus read and execute permissions) to the directory. Any user belonging to group site1 will enjoy all the privileges granted to that group.

Now login as user1, move to site1 directory and try to create a file in that directory,

echo "My User1 Site" > index.html 
bash: index.html: Permission denied

This failed since most likely the primary group of user1 is not site1. So, change to that group.

newgrp - site1

Try to recreate the file (beware that you have been moved to the home directory of user1 after changing group), this should work now. Since the created files will have world read permission, apache (or your web server) should not face any problem accessing them.

EDIT

Also, as pointed out by dan08 in comment, you need to add www-data to site1 group.

sudo adduser www-data site1

On many (not all) distributions, www-data is the user under which the Apache web server runs. This also means that everything done by Apache (especially including PHP scripts) will be done with the permissions of user www-data (and also group www-data) by default. WordPress uses the user www-data to write files.

If you want to see how apache web server is running, issue the command,

ps aux | grep apache2 | less
12
  • 2
    You also need to add www-data to the site1 group. When uploading and changing files in the Wordpress web interface. The changes are done by Apache using the www-data user. so read privileges are not sufficient most of the time.
    – Dan
    Oct 24, 2013 at 16:18
  • 3
    The Permission denied message isn't due to the "primary group", but rather the user not yet actually being in that group (as far as the OS is concerned). If you log out and back in, it will work as expected (without running newgrp - site1).
    – 0b10011
    Jan 27, 2014 at 21:26
  • How exactly would this be different from giving www-data group write permissions if you end up having to add www-data to site1 anyways?
    – Matt Borja
    Jul 10, 2016 at 12:33
  • @MattBorja Your query is not very clear. Are you asking what is wrong with giving the group named www-data' write permissions? If that is the question, www-data' is not a group, it is a user. Please let me know if I misunderstood your question.
    – Masroor
    Jul 10, 2016 at 18:04
  • i think, this is not secure configuration because users can access each other's sites via php script, for example, a php file manager.
    – qdinar
    Feb 2, 2017 at 12:18
18

For those who have their wordpress root folder under their home folder:

Ubuntu/apache

  1. Add your user to www-data group:

    CREDIT Granting write permissions to www-data group

    You want to call usermod on your user. So that would be:

    sudo usermod -aG www-data yourUserName
    

    Assuming www-data group exists

  2. Check your user is in www-data group:

    groups yourUserName
    

    You should get something like:

    yourUserName : yourUserGroupName www-data
    

    yourUserGroupName is usually similar to you user name

  3. Recursively change group ownership of the folder keeping your user ownership

    chown yourUserName:www-data -R yourWebSiteFolder/*
    
  4. Change directory to yourWebSiteFolder

    cd yourWebSiteFolder
    
  5. Recursively change group premissions of the folders and sub-folders to enable write permissions:

    find . -type d -exec chmod -R 775 {} \;
    

    mode of /home/yourUserName/yourWebSiteFolder/' changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x)

  6. Recursively change group premissions of the files and sub-files to enable write permissions:

    find . -type f -exec chmod -R 664 {} \;
    

    The result should look something like:

    WAS:
    -rw-r--r--  1 yourUserName www-data  7192 Oct  4 00:03 filename.html
    CHANGED TO:
    -rw-rw-r--  1 yourUserName www-data  7192 Oct  4 00:03 filename.html
    

    Equivalent to:

    chmod -R ug+rw foldername
    

    Permissions will be like 664 or 775.

7

Create two groups: site1grp and site2grp

sudo groupadd site1grp && sudo groupadd site2grp

Add www-data to both groups.

sudo adduser www-data site1grp && sudo adduser www-data site2grp

Add user1 and user2 to the appropriate groups

sudo adduser user1 site1grp && sudo adduser user2 site2grp

Change the permission of your site folders so that the user owner is www-data and the group owner is the appropriate group

sudo chown -R www-data:site1grp /var/www/site1  && sudo chown -R www-data:site2grp /var/www/site2

Now www-data has the user and group permissions on both sites and each user has the group permissions for their respective site.

0
3

You have to create a new group, for the, so called, "new user", and then add the www-data and the "new user" to that group:

sudo gpasswd -a new_user new_group

Then you can change the owner to new_user and group to new_group:

sudo chown -R new_user:new_group /var/www/site1

Then you will need to give group level access to site1. www-data will still be able to access the site, because it belongs to the new_group, while new_user will not be able to access site2, because he will not belong to the www-data group, which owns site2.

2
  • Your answer is confusing, by "giving group level access to site1", did you mean "changing the group of site1 to new_group" or changing the mode (chmod)? Your answer does not mention the mode anywhere which can make the difference of being secure (or break things).
    – Lekensteyn
    Dec 29, 2013 at 21:01
  • I meant changing the mode (chmod) by revoking all permissions for OTHERS.
    – ergysdo
    Dec 30, 2013 at 1:43
1

Assuming all files already belong to www-data user (you can check it with ls -slah command) who belongs to www-data group (next column after username in list of files) you can just add you user to the same www-data group to allow editing these files

# usermod -aG www-data username

for existing user, or

# adduser username www-data

for newly created one

1

However this all only works if the default permissions when creating new files include group write permission. Default permissions on most (Linux) systems are to give write permission only to the file owner. This means that if either www-data or a user creates a file or directory the other won't be able to write to it.

I have puzzled over this problem for several years, the only solution I have come up with is to use ACLs and reset them for the whole tree at intervals.

You must log in to answer this question.

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