Proper permissions for web server's directory

I have a doubt that I think is very basic but to which strangely I couldn’t find a concrete answer no matter how much I’ve googled for it.

When configuring a web server (Nginx, in my case), most people recommend setting the permissions as follows:

  • Create a new user other than root, and add it to the www-data group.
  • Set the ownership of /var/www to the www-data user and www-data group.
  • Directories 755
  • Files 644

This means that:

  • The user owner of the directory (www-data) can read, write and execute.
  • The assigned group (www-data, where my user is) can read and execute, but not write.
  • Everyone else can read and execute, but not write.

The problem with this is that, if the permissions are set in this way, I can’t edit files from the FTP because my user doesn’t have write permissions; this would require allowing the group to write adjusting the permissions like this:

  • Directories 775
  • Files 664

However, I don’t know if this could be a security issue, or why do people recommend doing it the other way if it doesn’t work through FTP. So, what is the most appropriate way to set permissions for the server directory?

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

I was poking for info on how ppl set their permissions, i have see a fair share of setups even on big shared hostings on many distributions.

The ones i liked are: Webserver credentials: $webserveruser:www-data user credentials : $username:$privateusergroup (same as username) php pool credentials: same as user credentials.

Now for files: Usually you have a root folder for the user (sort like homedir) and a root folder por serving web pages. Something like: /var/www/user1/html /var/www/user2/html /var/www/proyect1/html

Now, each “home dir” is owned by its own user, example /var/www/user2 is owned by user2:user2 Every subfolder too, exactly like a homedir, this is where many ppl get confused, how do you let the webserver read the files? (remember, php is using user credentials so it will always have full permissions on the working dir of the user, example, user2/html), Well… Assign $webserveruser to each $privateusergroup, everytime you add an user, do: usermod -aG $privateusergroup $webserveruser not the other way around, its confusing because the privategroup has the same name as the user. Now, you can set home dir to: chmod 710 /var/www/user2 and user2/html should have a default mask and permissions, example 75x, the root dir is already locked to others so it doesn’t matter. The webserver should be able to traverse a serve files, the user should not have problems using ftp with default mask and permissions, and php should be able to edit and read user files. Other users wont be able to read the files.

The other solution is using ACLs, but in the end its the exact same thing as my solution above, as setfacl will set a mask on the group permissions when setting a particular user or group access, it means the ‘extra’ permissions ser using acl will be controlled using the group permissions ‘mask’, And the extra headche to manage ACLs on a server is not worth it in my exprience.

setguid and group traditionals groups like www-data are a problem when the owner of the root dir is the user as it can change or delete permissions.

If many users have to access proyect1 for example, ACLs can be used but i like to ser the owner of the proyect to a particular user or root, set a group for collaboration like $project1group, chmod g+s bit on that dir, set 770, and asign the $webserveruser and the users of the proyect to $project1group.

So I’ve been thinking a lot about this lately, and something occurs to me. There will only ever be one web server, but there could be multiple developers working on a website.

So instead of assigning the group to www-data, assign the user to www-data, and create a group dev-websitename and assign your development users to it.

Then you can easily give more permissions to the dev group, and restrict permissions to the owner. I don’t see why “Other” users ever need any access what so ever.

Here’s the code:

    sudo chown -R www-data:dev-mysitenamehere .
    sudo find . -type f -exec chmod 0460 {} \;
    sudo find . -type d -exec chmod 2570 {} \;

The 2 in the directory chmod makes it so files inherit the folder’s group

Now, the issue here is when you create new files as your user, their owner will be your user name, not the server’s name (www-data). But in some ways, this is ideal, forcing you to manually change the ownership of new files so that they are visible by the server. Of course you could always set git post.receive to do this for you too.

For “storage” folders or other folders the server needs access to you can use this mode so your server can also edit these files:

    sudo find storage -type f -exec chmod 0660 {} \;
    sudo find storage -type d -exec chmod 2770 {} \;

I have not sufficiently tested this method - it may be that there are downsides, but it just seems like it makes more sense to me. There will only be one server user, but there will be multiple developer users. So group makes sense for developers, while owner makes sense for the server, and other users have no business here.

Is there an automated way to set these permissions properly for all folders?