In Linux, file permissions determine the levels of privilege for file owners and everyone else. It’s important to make sure any web-facing files have their permissions set correctly, so that a compromised process can’t write to places it shouldn’t.
Many articles will promote traditional way of setting permissions for your website, but from our experience that is the lowest level of security. We will explain non-traditional way of setting permissions, using ACL and isolating from other users.
First if you are hosting website on your server, you need to separate users from each other.
sudo adduser myuser --shell=/bin/false
sudo groupadd myuser
sudo usermod -g myuser myuser
Normally many authors will promote to set www-data as owner of all your websites. We recommend to have multiple users with their own groups and minimal rights.
The basic Linux permissions model works by associating each system file with an owner and a group and assigning permission access rights for three different classes of users:
File ownership can be changed using the chown
and chgrp
commands.
Three file permissions types apply to each class of users:
This concept allows you to control which users can read the file, write to the file, or execute the file.
-rw-r--r-- 12 linux users 12.0K Apr 25 11:10 file_name
|[-][-][-]- [------] [---]
| | | | | | |
| | | | | | +-----------> 7. Group
| | | | | +-------------------> 6. Owner
| | | | +--------------------------> 5. Alternate Access Method
| | | +----------------------------> 4. Others Permissions
| | +-------------------------------> 3. Group Permissions
| +----------------------------------> 2. Owner Permissions
+------------------------------------> 1. File Type
Let's set the permission for our website:
chmod a+rwx,g-w,o-rwx website_folder
or:
chmod 750 website_folder
If you are more familiar to read permission in numbers then run:
stat -c "%a %n" *
Now that we set permission for our entry folder, we need to define ACL by using setfacl tool.
The setfacl utility sets ACLs (Access Control Lists) of files and directories. On the command line, a sequence of commands is followed by a sequence of files (which in turn can be followed by another sequence of commands, and so on).
setfacl -R -m u:www-data:rx /var/www/website_folder/
After that you can run getfacl to display ACL on directory.
For each file, getfacl displays the file name, owner, the group, and the Access Control List (ACL). If a directory has a default ACL, getfacl also displays the default ACL. Non-directories cannot have default ACLs.
getfacl website_folder/
This command will display as it follows:
# file: website_folder/
# owner: myuser
# group: myuser
user::rwx
user:www-data:r-x
group::r-x
mask::r-x
other::---
If you are running PHP-FPM pools then you may add in your pool profile:
listen.acl_users = www-data,myuser
listen.acl_groups = www-data,myuser
What we did so far is that we granted access only to our user and group to have rights to read, write and execute with exception that from all other users only www-data has right to read and execute.
Many users will not bother with this and they will simply go with permission 755, which gives right to all other users to read and execute, and that is the most dangerous way to set permission for your website.