bueller.ca

the digital workshop of Matt Ferris

HomeArticles2016

Linux ACLs

February 26, 2016

When basic unix permissions can't express the access requirements you need to impose on a filesystem, you need to turn to the more powerful Access Control List (ACL). Enabled by default on most filesystems in most Linux distributions these days, ACLs provide a rich toolset for handling complex permissions. While they may be intimidating at first, they are actually quite easy to understand.

Checking for ACL Support

For ext3 and ext4 filesystems, we can check if ACLs are enabled by running:

tune2fs -l /dev/sda1 | grep 'Default mount options'

Replace /dev/sda1 with the path to the block device or file that backs the filesystem. In particular, if you see acl listed then you know ACL support is enabled within the filesystem. It's possible to disable ACL support for the mount itself by specifying noacl. In order to use ACLs, both the filesystem and the mount must allow it. Likely, this is already the case, but if you run into issues setting ACLs then you may need to double-check things.

You may also need to install packages to provide ACL support. On Debian-based distros you need to install acl.

apt-get install acl

First Steps

To start things off, let's pretend we work for a company. We're asked to create a directory called stooges that contains three subdirectories called larry, curly, and moe. Regardless of the companies rather unprofessional choice of names, we can do that.

mkdir -p stooges/larry stooges/curly stooges/moe

If we list the contents of stooges, we can see the current unix permissions on the subdirectories.

# cd stooges
# ls -l stooges
total 12
drwxr-xr-x 2 root root 4096 Feb 25 22:35 curly
drwxr-xr-x 2 root root 4096 Feb 25 22:35 larry
drwxr-xr-x 2 root root 4096 Feb 25 22:35 moe

The unix permissions are pretty straightforward. Only the root user can create files within these folders, while anyone else can view the files within the directories. If we wanted members of the staff group to be able to create files in the curly directory, we could simply change the group ownership and modify the permissions.

# chgrp staff curly
# chmod g+w curly
# ls -l
total 12
drwxrwxr-x 2 root staff 4096 Feb 25 22:35 curly
drwxr-xr-x 2 root root  4096 Feb 25 22:35 larry
drwxr-xr-x 2 root root  4096 Feb 25 22:35 moe

Great! Some time later, the company hires some contractors. We create a special group for them called contractors. They also need access to the curly directory. How can we resolve this? With unix permissions, we would need to either create a new group including members from both staff and contractors or add staff members to contractors or vice-versa. This is a great fit for ACLs.

ACLs provide the flexbility required to handle multiple permission sets for multiple objects. This makes working with multiple groups really easy. To set an ACL on a file or directory we use setfacl. Each group can be given their own set of permissions.

# setfacl -m group:contractors:rwx curly
# ls -l
total 12
drwxrwxr-x+ 2 root staff 4096 Feb 25 22:35 curly
drwxr-xr-x  2 root root  4096 Feb 25 22:35 larry
drwxr-xr-x  2 root root  4096 Feb 25 22:35 moe

You can see we've set an ACL on curly because it now has a + beside its permissions. To see the ACL we use getfacl.

# getfacl curly
# file: curly
# owner: root
# group: staff
user::rwx
group::rwx
group:contractors:rwx
mask::rwx
other::r-x

The lines starting eith a # are just comments. These comments can be suppressed by using the -c option. You can see that while we only set one ACL, we can actually see four sets of permissions (plus a mask). This is because ACLs treat unix permissions as generic ACL entries. The owner of the file or directory uses the user entry, the group owner uses the group entry and everyone else uses the other entry.

Members of the contractors group can now access the curly directory because members of the group will match the group:contractors:rwx entry.

For reference, setfacl allows us to add, modify, and delete ACL entries. The -m option adds or modifies an entry, while -x deletes an entry. We could delete the entry we just added simply enough.

setfacl -x group:contractors curly

When deleting ACLs, we don't specify the permissions, just the identifying part of the ACL (in this case group:contractors). We'll leave the ACL for the contractors group there for now, but it's good to know how to delete ACLs.

Managing ACLs on Files and Directories

Copying ACLs

The company decides they want to the same access on larry that curly has. While we could follow the same steps as last time, there's a faster way. setfacl has the handy ability to understand the output of getfacl, which allows us to easily copy ACLs from one directory to the other.

# getfacl curly | setfacl -M - larry
# ls -l
total 12
drwxrwxr-x+ 2 root staff 4096 Feb 25 22:35 curly
drwxrwxr-x+ 2 root root  4096 Feb 25 22:35 larry
drwxr-xr-x  2 root root  4096 Feb 25 22:35 moe

# getfacl -c larry
user::rwx
group::rwx
group:contractors:rwx
mask::rwx
other::r-x

The -M option reads ACL information from a file, or STDIN when a hyphen is used (as in the case). So we were able to copy the ACL information over but we still have a problem. Members of staff won't be able to access the directory because the group ownership didn't copy over. This is because ownership isn't recorded in ACLs. To simplify management of ACLs, it's a good idea to store as much information in the ACLs as possible.

# chgrp root curly
# setfacl -m group:staff:rwx curly larry

Now we have ACL entries for staff on both directories.

Backing ACLs Up

While our ACLs aren't difficult to restore it's good to get in the habit of backing them up. As our ACLs get more complex, it will become more and more costly if we lose them.

How can we lose them? Anytime files or directories with ACLs are copied without special attention to the use of the tools or media it's possible to lose the ACL information in transit. If the tool doesn't understand or doesn't know to look for ACL information it will ignore it. If the media the data is being copied too doesn't support ACLs, then ACL information will be discarded. By backing up the ACL information on a regular basis we can prevent the disaterous situation where we can recover the data, but can't determine who has access to it.

Fortunately, as we've seen, setfacl understands the output from getfacl. We can use this to create a backup of an entire directory tree of ACLs.

getfacl -R . > backup.acl

The -R option for getfacl specifies a recursive lookup. backup.acl can now be used to restore all ACLs for files and directories beneath the current directory. To test this, we can delete the ACLs on curly and larry and try to restore them.

# setfacl -Rb .
# ls -la
total 16
-rw-r--r-- 1 root root  470 Feb 25 23:59 backup.acl
drwxrwxr-x 2 root root 4096 Feb 25 22:35 curly
drwxrwxr-x 2 root root 4096 Feb 25 22:35 larry
drwxr-xr-x 2 root root 4096 Feb 25 22:35 moe

The -R option for setfacl specifies a recursive operation and the -b option clears all ACLs. As we can see from the absence of the + beside the unix permissions, we no longer have ACLs on curly and larry. But don't fret because we were good sys admins and backed our ACL information up. Now we just need to restore it.

setfacl --restore backup.acl

This needs to be run from the directory the backup was taken from. Our ACLs are now back and our customers are happy!

# ls -l
total 16
-rw-r--r--  1 root root  470 Feb 25 23:59 backup.acl
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 curly
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 larry
drwxr-xr-x  2 root root 4096 Feb 25 22:35 moe

Understanding How Access is Calculated

Due to curtain circumstances, HR has requested that access for a staff member (matt) to the larry directory must be revoked temporarily. To faciliate this we could create a special group for matt in which he is the only member and grant that group access to curly not larry. It would work, but if we understand how access is calculated when using ACLs we can come up with an even better solution.

Essentially, ACLs are evaluated from most-specific to least-specific. User entires are evaluated before group entries are evaluated before the other entry is evaluated. The first matching ACL entry's permissions are used to determine the access to the file or directory.

We can apply this understanding to the current problem. We have a single user who we need to revoke access for. While we grant access based on the group we can revoke access based on the user. But how do we set non-permissions? Simple.

# setfacl -m user:matt:- larry
# getfacl -c larry
user::rwx
user:matt:---
group::rwx
group:staff:rwx
group:contractors:rwx
mask::rwx
other::r-x

Non-permisions (or no permissions) can be specified by simply using a hyphen in the ACL defintion. As we can see, matt has no permissions. When matt attempts to access files in larry the ACL will first look for user entries, and upon finding the entry for matt access to the file will be denied. All other members of staff will match the group entry as per usual and will continue to have access.

Unix Permissions when Using ACLs

Because employees work all hours of the night, it can be hard to find time to complete automated backups. If staff are writing to files while we're trying to copy them, we could end up with corrupted files in our backups. The moe directory in particular maintains a unique backup schedule limiting our options (we can't remount the volume read-only). How can we easily prevent staff from making changes while we run our backups?

Let's gather some info first.

# ls -l
total 16
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 curly
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 larry
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 moe

# getfacl -c moe
user::rwx
group::r-x
group:marketing:rwx
group:finance:rwx
group:sales:rwx
group:hr:rwx
group:it:rwx
group:qa:rwx
group:legal:rwx
group:operations:rwx
group:purchasing:rwx
mask::rwx
other::r-x

Though we could change all these ACLs to rx there's enough of them to make it a pain in the butt. There might be a simpler way. Let's dive a bit deeper into the relationship between unix permissions and ACLs to find out how this can be done.

Once a file or directoy has ACLs applied to it, the semantics of the unix permissions change. They no longer reflect the permissions of the user, group or other users, rather they define the upper bound of permissions that can be granted via ACLs. This is reflected by the mask entry in the ACL, which is bound the group unix permissions.

If the mask defines the most permissive set of permissions, we can use a mask to quickly limit all ACLs to read-only.

# setfacl -m mask::rx moe
# getfacl -c moe
user::rwx
group::r-x
group:marketing:rwx             #effective:r-x
group:finance:rwx               #effective:r-x
group:sales:rwx                 #effective:r-x
group:hr:rwx                    #effective:r-x
group:it:rwx                    #effective:r-x
group:qa:rwx                    #effective:r-x
group:legal:rwx                 #effective:r-x
group:operations:rwx            #effective:r-x
group:purchasing:rwx            #effective:r-x
mask::r-x
other::r-x

# ls -l
total 16
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 curly
drwxrwxr-x+ 2 root root 4096 Feb 25 22:35 larry
drwxr-xr-x+ 2 root root 4096 Feb 25 22:35 moe

getfacl now shows us the effective permissions based on the ACL entry and the ACL mask. Also notice that the unix group permissions reflect the ACL mask as well. In reality, chmod g-w moe and setfacl -m mask::rx moe do the same thing. This is because the unix group permissions and the ACL mask are bound together.

Now that staff can no longer modify files, we can take our backup. When we're done we just need to restore the permission by changing the mask back.

setfacl -m mask::rx moe
OR
chmod g+w moe

Inheritance

Up until this point, we've not really had a functional set of ACLs given our use case. Staff would likely need to create directory structures within our directories. Currently, our ACL lists would grant them access to create files and directories within larry, curly, and moe, but the ACLs wouldn't be inherited by the new child directories. The missing piece of the puzzle in default ACLs.

Default ACLs can be added to directories. When files or directories are created within a directory with default ACLs, the default ACLs are inherited. For files, the default ACLs become regular access ACLs. For directories, they remain default ACLs.

Before we continue, let's just see what happens when we create a subdirectory without current ACL setup.

# mkdir curly/foo
# ls -l curly
total 4
drwxr-xr-x 2 root root 4096 Feb 26 01:54 foo

As we can see, the new directory hasn't inheirted any ACLs, which means nobody has permission to access it. Let's fix our current ACL situation so that our access can be inherited properly.

# getfacl -c curly
user::rwx
group::rwx
group:staff:rwx
group:contractors:rwx
mask::rwx
other::r-x

# setfacl -b curly
# setfacl -d -m g:staff:rwx,g:contractors:rwx
# getfacl -c curly
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:staff:rwx
default:group:contractors:rwx
default:mask::rwx
default:other::r-x

The -d option to setfacl means modify a default ACL entry. We also used the shorthand for group which is just g, and added two entries at the same time (every keystroke counts you know!). What happens if we re-create our subdirectory now?

# rm -r curly/foo
# mkdir curly/foo
# ls -l curly
total 8
drwxrwxr-x+ 2 root root 4096 Feb 26 01:56 foo

# getfacl -c curly/foo
user::rwx
group::rwx
group:staff:rwx
group:contractors:rwx
mask::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:staff:rwx
default:group:contractors:rwx
default:mask::rwx
default:other::r-x

Awesome! The new directory inherited the ACLs which means users will continue to have access! The remaining directories just need to receive the same treatment.

Conclusion

Unix permissions have been around a long time and provide enough flexibility to acheive the access your looking for in most cases. In the cases where unix permissions just won't cut it you can lean on ACLs for more expressive access control. Understanding the added complexity that ACLs brings is critical. ACLs are a tool in your sys admin belt, to be used where appropriate and in conjunction with safegauards to protect the information they contain.

Further Reading

Comments