ACLs: Extended file-permissions
In Windows they are used for a long time already, but most Linux-users probably don't even know that their system supports them too. Access Control Lists (ACLs) extend the regular permissions we all know with the possibility to give permissions for specific users/groups.
With a little example I want to show how to use ACLs in Linux.
Before I get started I want to mention that filesystems where you want to use have to be mounted with the ACL-option. Either manually using mount -o acl or by adding acl to the options-line in /etc/fstab.
The latter looks like this:
/dev/Fedora/Root / ext4 defaults,acl,noatime,nodiratime 1 1
By running mount you can easily check if your filesystems are mounted with this option. The output for the previously shown partition looks like this:
/dev/mapper/Fedora-Root on / type ext4 (rw,noatime,nodiratime,acl)
All recent distributions should support ACLs and offer everything necessary to use them. It may be necessary to use one of the ways shown above to enable the use of ACLs though.
Okay, let's get started. I want to work with Apache as my example, offering users the possibility of their own web-directory. I guess you all know the user-directory-option of Apache, which usually accesses ~/public_html in order to share the users' sites.
Now usually Apache does not run as root, which is a good thing, except you want to add unnecessary security-risks to your system. But this imposes the problem that Apache by default will not be able to read user-directories, except they have global read-permissions, like in the permission-set 755. This of course also is not desirable since every user will be able to read any other users' home-directory.
By default the permissions of my home-directory look like this:
drwx------. 117 dennis dennis 4096 2009-06-29 15:54 dennis
Only I am permitted to work there, which is exactly what I want. Now if I want to enable Apache to read my home-directory I can specify this through an ACL.
As said, I don't want global read-permissions. I only want to enable a specific user, apache, to read my home-directory.
Using setfacl I can do this:
setfacl -m u:apache:rx /home/dennis
This gives the permissions r (read) and x (execute, or in case of directories, like here, changing into) to the user apache.
Instead of u for users you can also use g to specify a group.
Now the permissions look like this:
drwxr-x---+ 117 dennis dennis 4096 2009-06-29 15:54 dennis
You can see that now the group-field of the regular permissions also contain the permissions r and x. One might think this isn't necessary, but it actually is, which I will explain a bit later.
Also you can see that at the end of the permissions a + appeared. ls uses this to symbolize the use of an ACL.
Using getfacl we can view the ACL.
# file: home/dennis # owner: dennis # group: dennis user::rwx user:apache:r-x group::--- mask::r-x other::---
Now let's get back to the necessity of the permissions r and x in the group-field. If I remove those the output of getfacl looks like this:
# file: dennis # owner: dennis # group: dennis user::rwx user:apache:r-x #effective:--- group::--- mask::--- other::---
It's important to note the additional output of #effective:---, which tells us that the user apache effectively has no permissions here. Using the browser to access localhost/~dennis confirms this.
So: If setfacl automatically sets any permissions: Don't mess with them!
So now Apache has the necessary permissions to read my home-directory. Since inside this all permissions default to 755 I don't need to apply any ACL to public_html. Those of you who are paranoid (or have a paranoid distro) with all permissions inside their home-directory set to 700 or 750 of course have to enable Apache to access public_html, just like shown above for the home-directory.
So now we have learned how to set ACLs (setfacl), how to recognize their use in the ls-output (the + at the end of the permissions) and how to display them (getfacl).
Modifying ACLs works exactly the same way as setting them. Actually we are modifying them when we set them. The parameter -m means modify.
So if later on you want to enable Apache to write to your home-directory (whatever reason you may have to do so) you simply call
setfacl -m u:apache:rwx /home/dennis
And of course it may happen that you want to get rid of an ACL-entry. Maybe you have decided you don't want to use user-directories anymore. Also here we use setfacl, just this time we use -x to delete an entry.
setfacl -x u:apache /home/dennis
And also here we can specify a group by replacing the u with a g.
Now, coming to an end, I want to mention that ACLs of course are not limited to only one user/group, but that multiple entries can be made.
Here an example with the users apache and tomcat having read-permissions to my home-directory:
# file: dennis # owner: dennis # group: dennis user::rwx user:apache:r-x user:tomcat:r-x group::--- mask::r-x other::---
Well, I guess that's pretty much everything you need to know in order to be able to use ACLs in Linux. I hope this little tutorial will help to spread the word about ACLs, which in my opinion make permission-handling a lot more flexible. It's not always possible or desirable to use groups or even global permissions. This is where ACLs come into play and offer the possibility to give permissions to specific users/groups.