Using access control lists (FACLs)

An access control list (ACL) provides a more granular approach to permissions, allowing the system administrator the ability to move past the limitations of Linux permissions when the situation warrants it.

For instance, perhaps you have a complex use case that requires granting permissions to multiple individual users, or maybe to more then a single group. Some people would get around this by simply using 777 permissions, but that in and of itself is a very poor security practice.

ACLs can help solve this as they allow you to create a sophisticated permissions scheme that grant access to the users and groups that require it, without the need to open the permissions broadly for everyone.

With all this being said, ACLs should only be used when standard permissions cannot accomplish what your looking to do. ACLs are often used as the ‘quick fix’, but while they do work, they can overly complicate an environment that could cause major headaches while troubleshooting. There is also more room for error, as you are adding an additional layer of complication when employing ACLs.

Enabling ACLs on the filesystem

Setting up a system for ACLs are pretty simple. If you are running a system that uses systemd, then ACLs should already been enabled as its a dependency for systemd. For older systems, the process is shown below for installing and enabling ACLs.

First, check to see if ACLs are already enabled on the filesystem:

[[email protected] ~]# tune2fs -l /dev/sda1 |grep acl
Default mount options:    user_xattr acl

If you do not see ‘acl’ in the output, then you can install ACLs by:

# CentOS / RHEL:
[[email protected] ~]# yum install acl

# Ubuntu / Debian:
[[email protected] ~]# apt-get update
[[email protected] ~]# apt-get install acl

Now for all distros, enable ACLs in your /etc/fstab putting ‘acl’ in the mount opens as shown below:

[[email protected] ~]# cat /etc/fstab 
/dev/mapper/VolGroup-lv_root / ext4 defaults,acl 1 1

Then remount the filesystem so the new mount option takes effect by:

[[email protected] ~]# mount -o remount /

Then verify that ACL’s are now enabled on the filesystem:

[[email protected] ~]# tune2fs -l /dev/sda1 |grep acl
Default mount options:    user_xattr acl

Using ACLs

You can determine if a file or directory has an ACL in place as the permissions will be followed by a ‘+’ as shown below:

[[email protected] ~]#  ls -al
-rw-rwxr--+  1 root root   93 Jan 12 11:22 test

You can see what ACLs have been assigned to the file by:

[[email protected] ~]# getfacl test 
# file: test
# owner: root
# group: root

So in the example above, we see a user called jdoe also rwx permissions to the file called test.

To add or modify a user ACL:

[[email protected] ~]# setfacl -m u:jdoe:permissions /var/www/vhosts/

To add or modify a group ACL:

[[email protected] ~]# setfacl -m g:devs:permissions /var/www/vhosts/

To modify the ‘other’ ACL:

[[email protected] ~]# setfacl -m o:permissions /var/www/vhosts/

To add or modify an ACL recursively, you use the -R option. It is important to note that it is considered good practice to use the -X (capital X) permission when using recursion so files can retain the execute permission if they have them, but also allow you to traverse the directory as that requires the execute permission. The benefit comes into play with the -X (capital X) as it will prevent an admin from accidentally adding the execute permission on a regular file. An example of this is below:

[r[email protected] ~]# setfacl -R -m u:jdoe:rwX /var/www/vhosts/

To set the default ACL so all new directories will inherit the ACL’s set on the parent directory:

[[email protected] ~]# setfacl -R -m default:u:jdoe:rwX /var/www/vhosts/

To remove a user from an ACL:

[[email protected] ~]# setfacl -x u:jdoe /var/www/vhosts/

To remove a group from an ACL:

[[email protected] ~]# setfacl -x g:devs /var/www/vhosts/

Remove ALL ACL’s on a file/directory:

[[email protected] ~]# setfacl -b /var/www/vhosts/

Remove ALL ACL’s on a file/directory recursively:

[[email protected] ~]# setfacl -R -b /var/www/vhosts/

RHCSA Study Guide – Objective 4 : File Systems

Everything below are my raw notes that I took while attending an unofficial RHCSA training session.  I am posting them here in hopes they will assist others who may be preparing to take this exam.  

My notes are my own interpretation of the lectures, and are certainly not a replacement to classroom training either through your company, or by taking the official RHCSA classes offered through Red Hat.  If you are new to the Red Hat world, I strongly suggest looking into their training courses over at Red Hat.

Filesystem Administration

With partitioning, obviously use fdisk. Granted, apparently something called partprobe is no longer used in RHEL6. Thats great, cause I never used it before. So you will have to reboot to bring the system back up. There is a GUI based tool caused disk utility.

So once the partitioning is done, now create the filesystem:

[[email protected] ~]# mkfs.ext4 /dev/sda2

This can help show you if the disk is dirty:

[[email protected] ~]# tune2fs -l

File system tools:

e2label : view/set filesystem label
tune2fs : view/set filesystem attributes
mount/umount : Mount and un-mount filesystems

EXAM NOTE: Be sure that anything you do on the filesystem, you add it to your /etc/fstab cause the system will be rebooted before it will be graded, so you need to ensure that it works properly upon reboot.


1.  Using fdisk, create a new 100MB partition
[[email protected] ~]# fdisk /dev/sda

2.  Create a new fs on this partition using ext4, a blocksize of 1k, and a reserve space of 2%.  Confirm settings with tune2fs.  Mount the new fs as /u01, and set it to mount at boot.
[[email protected] ~]# mkfs.ext4 -b 1024 -m 2 /dev/sda5
[[email protected] ~]# mount -t blah and update fstab accordingly

3.  Unmount the /u01 fs and force an integrity check.  Remount the /u01 filesystem.  Use e2label to set the fs label on /u01 to /u01.
[[email protected] ~]# umount /u01
[[email protected] ~]# fsck -f /dev/sda5  # NOTE:  You have to specify the -f to FORCE the fsck.  It will NOT run just because you asked for it.  
[[email protected] ~]# e2label /dev/sda5 /u01
[[email protected] ~]# mount -a
[[email protected] ~]# blkid ; just another way to verify your superblock settings.

EXAM NOTE: This may be on test, but it’ll probably be lvm stuff.

Automount (Autofs)

Autofs monitors a certain directory and can automatically mount a file system when a call is made to files in that directory. It will also unmount the directory in RHEL6 after it hasn’t been touched in 5 minutes.

Its configuration is in:


EXAM NOTE: Will need to know how to tell system which directories to monitor.

path config file
ex.  /misc /etc/auto.misc

This tells automountd to ‘watch’ the /misc pathname for activity, and if activity is observed, consult /etc/auto.misc for instructions.

So for the basic syntax:

path    options   mount device nfs -fstype=nfs,ro  nfsserver:/share/nfs

* This tells automountd to dynamically mount the nfs share to /share/nfs. Autofs will mount stuff as needed.


1.  Configure your server to automatically mount /share as an NFS share from server1 to /server1/share when a process changes directories there.

[[email protected] ~]# vi /etc/auto.master
/server1        /etc/auto.server1

[[email protected] ~]# vi /etc/auto.server1

[[email protected] ~]# service autofs restart

EXAM NOTE: I would imagine this will be on the test.

Extended Attributes

lsattr - list attributes
chattr - change attributes

EXAM NOTE: Redhat will likely test on the -i flag. So watch out for it.



You must have the acl mount option set. It’ll work on / since rh does this by default, but you will have to specify this on any new partitions.

[[email protected] ~]# setfacl -m u:bob:w memo.txt  -> Set facls
[[email protected] ~]# setfacl -x g:ru memo.txt -> removes facls
[[email protected] ~]# setfacl -m default:u:bob:w memo.txt -> setfacls

EXAM NOTE: These WILL be on the test.


Quotes allow you to limit fs resources to users. Basically disk quotas. To enable, add the following to the mount options:

[[email protected] ~]# vi /etc/fstab

[[email protected] ~]# quotacheck -mavug
[[email protected] ~]# quotaon -a # Turn on quotas
[[email protected] ~]# edquota -u test # Set limits

EXAM NOTE: These will be on the test.


1.  Create a quota for the user student with:
- block soft limit of 100M and a hard limit of 150M
- soft inode limit of 30 and a hard inode limit of 100

2.  Create a quota for the group gdm so that its members collectively have:
- a block soft limit of 200M and a hard limit of 300M
- a soft inode limit of 50 and a hard inode limit of 200


[[email protected] ~]# vi /etc/fstab # Add the following mount options

[[email protected] ~]# mount -o remount /
[[email protected] ~]# quotacheck -mavug
[[email protected] ~]# quotaon /home # Turn on quotas
[[email protected] ~]# edquota student # Set limits

# Interesting note:  To do the math quickly on the cli, do:
[[email protected] ~]# echo $((1024*1*100))
[[email protected] ~]# edquota -g gdm

# Set quotas accordingly.
[[email protected] ~]# repquota -g /home

EXAM NOTE: This may be on the exam.

Disk Encryption – LUKS

Quick start for those interested:

[[email protected] ~]# cryptsetup luksFormat   # NOTE:  This will delete all your stuff on disk!!!
[[email protected] ~]# cryptsetup luksOpen  ...  
[[email protected] ~]# cryptsetup luksOpen /dev/sda5 crypt01

This will exist in /dev/mapper/mapname ie. /dev/mapper/crypt01.
# NOTE: The luksformat will prompt for a passphrase, and you can set it to use 8 keys if you like.

Now you will be able to format it:

[[email protected] ~]# mkfs -t ext4 /dev/mapper/crypt01
[[email protected] ~]# mkdir /crypt01
[[email protected] ~]# mount /dev/mapper/crypt01 /crypt01

Now add entry into fstab:

[[email protected] ~]# vi /etc/fstab
/dev/mapper/crypt01 /crypt01 ext4 defaults 1 2

Once done, now close it (encrypt it) by:

[[email protected] ~]# cryptsetup luksClose /dev/mapper/crypt01

To make this stuff persistent at boot, edit /etc/crypttab as shown below.

1. To make a LUKS encrypted device available at boot time:

[[email protected] ~]# vim /etc/crypttab
mapname device keyfile options

2. To create a keyfile:

[[email protected] ~]# dd if=/dev/urandom of=/etc/keyfile bs=1k count=4
[[email protected] ~]# cryptsetup luksAddKey  /etc/keyfile

3. Add to crypttab

[[email protected] ~]# vi /etc/crypttab
/dev/mapper/crypt01 /dev/sda5 [/path/to/keyfile] [option] 

EXAM NOTE: Use keyfiles for test. But in practice, use a passphrase, but understand risks involved.


1.  Create a new 100M physical volume, then set up a luks encrypted ext4 filessystem on the logical volume, which will be persistent across reboots.

2.  Reboot your machine to verify LUKS filesystems prompt for the passphrase and become accessible automatically after bootup

3.  Browse through the man pages on cryptsetup and crypttab


1.  Create your 100M logical partition through fdisk
2.  Setup luks stuff
[[email protected] ~]# cryptsetup luksFormat /dev/sda5  # Answer YES, and type your passphrase
[[email protected] ~]# blkid # confirm it setup the type:  cryptoluks
[[email protected] ~]# cryptsetup luksOpen /dev/sda5 crypto  # now enter your password
3.  Now put fs on the device
[[email protected] ~]# mkfs -t ext4 /dev/mapper/crypto
[[email protected] ~]# blkid # You can now see both the raw device, and the crypted device
4.  Setup /etc/fstab
[[email protected] ~]# vi /etc/fstab
/dev/mapper/crypto /u02 ext4 default 1 2  # If the test is wonky, set it to 0 0 to prevent fsck.
5.  Mount it and your done.
6.  Now create crypttab stuff

# Quick and dirty
[[email protected] ~]# echo -n test > /etc/keyfile  # You need the -n to prevent the newline character
[[email protected] ~]# cryptsetup luksClose /dev/mapper/crypto
[[email protected] ~]# cryptsetup luksOpen /dev/sda5 crypto -d /etc/keyfile # The -d flag forces the key to be used.

# Better way of setting up key - If you don't want to use a pw at all, then do the lukFormat with the -d to specify keyfile.
[[email protected] ~]# dd if=/dev/urandom of=/etc/keyfile bs=1k count=4
[[email protected] ~]# cryptsetup luksAddKey /dev/sda5 /etc/keyfile
# add your original key password
[[email protected] ~]# chmod 400 /etc/keyfile
Now your key works, and so does your passphrase.

[[email protected] ~]# vi /etc/crypttab
crypto /dev/sda5 # If you leave it like this, it'll prompt you for pw at boot
crypto /dev/sda5 /etc/keyfile   # <-- This is how you should do it.

# The method above gives you a secure key, and also a backup passphrase to ensure all is well if you lose your key, you aren't in trouble.

# How to verify all this:
# Confirm your device is unmounted
# This is basically just a way to verify your system will boot most likely.  
[[email protected] ~]# bash
[[email protected] ~]# source /etc/init.d/functions
[[email protected] ~]# init_crypto 1 # This is the function that processes crypttab.  It accepts 0 or 1.  Think of it like mount -a sorta.
[[email protected] ~]# ls -al /dev/mapper
[[email protected] ~]# mount -a
[[email protected] ~]# ls -al /u02


Exam note: You can likely leave SElinux disabled or permissive. They will likely not test it at all. It'll be on the RHCE though.

SElinux sits on top of the kernel, telling the kernel what is permitted and what is not. There are 3 levels:

- Disabled : Extentions and hooks are not in kernel
- Permissive : Extension and hooks are there, but if there is a policy violation, the kernel will still allow it.
- Enabled:  Everything there, and blocking accordingly.

Redhat made policies called TARGETED. These are done by groups such as web, mail, ftp, db, etc. Its RHEL's way of making our lives a bit easier. Therefore, by using these targetted polcies, we may just have to fix the files/directories contexts or booleans.

So every process or object has a SELinux context:
- identity:role:domain/type

a.  What identities can use which roles
b.  What roles can enter which domains
c.  What domains can access which types.

Again, RHEL makes this easier and basically just uses the types, nothing else. We can take it further, but that is our choice to make that work.

So in short, SELinux tells the kernel weather or not to allow access to whatever thing.

If you want to view a context for a process, run:

[[email protected] ~]# ps -Z - List the processes contexts
[[email protected] ~]# ls -Z - List the file contexts

To change the context of a file, use:

[[email protected] ~]# chcon -R --reference=/var/www/html file

So what does that mean: Go to this other location (/var/www/html), and apply it to my target (file). So if I put my docroots in /srv, to get SELinux to like this directory, we had to change the context of /srv by:

[[email protected] ~]# chcon -R --reference=/var/www/html /srv

So as long as you know the default location where the contexts reside, you can cheat and just copy the context over to the new location.

All policy violations will be logged to /var/log/audit/audit.log as AVC (access vector cache) denials.
** setroubleshoot is a good tool for reading the output of that log.

Lets say you borked your entire setup, you can reapply the default contexts on all common pathnames. So to restore things, you just do:

[[email protected] ~]# restorecon -R path path...

* NOTE: This will not affect your new stuff like /srv, cause that is not in the default labeling. You can set the semanage stuff (may have to install it), and set the default paths.

restorecon knows about the policies and defaults. chcon only changes things.. that is all chcon knows.

EXAM NOTE: restorecon will not really be needed on the RHCE.. unless you break something hardcore.

There is a graphic tool for selinux: system-config-selinux.
NOTE: You MUST reboot the system when enabling selinux, or disabling it since it mucks with the kernel hooks and stuff.

The config for selinux: /etc/sysconfig/selinux
* This is where you set your enforcing/targetting/disabled, etc. Just the startup mode stuff.


getenforce - shows the current SELIinux mode
setenforce - will allow you to change the mode.  ie:  setenforce 0 (dir)
setenforce 0 # Disable selinux temporiatly
setenforce 1 # Enable selinux

NOTE: If the server is completely broken and you cannot even boot, you can disable SELinux in grub by passing the enforcing=0 to the kernel line in grub when booting.

Other troubleshooting tools:


These are basically simple on/off flags for enabling/disabling these:

[[email protected] ~]# getsebool -a |grep httpd  # or whatever.
[[email protected] ~]# setsebool -P blah

What are some practical uses for selinux:

- Allow you to change the default paths for like where you store db, web, etc, etc.  
- Change the boolean's to allow like public_html directories ie: getsebool -a |grep httpd


1.  With SELinux enforcing, configure a website to be served from /srv
2.  Dont focus on advanced apache settings, accomplish this in the simplest way possible, change the global documentroot
3.  Populate a simple index.html file.  
4.  The settroubleshoot tool is useful here.  Don't be confused by any typos in the output.

Easy enough, just get apache setup, then:

[[email protected] ~]# yum -y install setroubleshootd 
# You will see the stuff needed in /var/log/audit/audit.log or /var/log/messages.
[[email protected] ~]# service auditd restart
[[email protected] ~]# chcon -R --reference=/var/www/html /srv