Site icon GetPageSpeed

Linux setfacl Command: Complete Guide to ACL Permissions for Read-Only Users and Beyond

setfacl

setfacl

Linux file permissions have always been a cornerstone of system security, but the traditional owner-group-others model often falls short in complex multi-user environments. Enter setfacl – the powerful Access Control List (ACL) utility that transforms how you manage file permissions on Linux servers. Whether you need to grant a developer read-only access to production files or implement fine-grained security policies, setfacl is your go-to tool.

In this comprehensive guide, you’ll learn how to use setfacl to add read-only users, implement recursive permissions, configure default ACLs for new files, and leverage advanced features that most system administrators overlook.

Why Standard Linux Permissions Aren’t Enough

Traditional Unix permissions (chmod) only allow you to set access for three entities: the owner, a single group, and everyone else. This creates real-world challenges:

The Access Control List (ACL) system solves these problems by allowing multiple users and groups to have custom permissions on any file or directory.

Installing ACL Support on Linux

Most modern Linux distributions come with ACL support pre-installed. To verify or install:

# Check if ACL is installed
getfacl --version

# Install on RHEL/CentOS/Rocky Linux/AlmaLinux
sudo dnf install acl

# Install on Debian/Ubuntu
sudo apt install acl

Your filesystem must also support ACLs. Most modern filesystems (ext4, XFS, Btrfs) have ACL support enabled by default. You can verify this in your mount options:

mount | grep acl

If ACLs are not enabled, you can enable them by adding acl to your mount options in /etc/fstab and remounting.

Adding a Read-Only User to a Website with setfacl

This is one of the most common use cases: granting a developer or auditor read-only access to website files without modifying group ownership. Let’s say you have a website at /srv/www/example.com and want to give the user sftpdev read-only access.

The Simple Command

setfacl --recursive --modify u:sftpdev:rX /srv/www/example.com

Let’s break this down:

Why Use Capital X Instead of Lowercase x?

The difference between x and X is critical:

Permission Effect on Files Effect on Directories
x Execute permission Enter directory permission
X Execute only if already executable Always enter directory permission

Using lowercase x would make all files executable (a security risk), while uppercase X intelligently applies execute only where needed.

Making ACLs Persist for New Files: Default ACLs

Here’s where many administrators make a mistake. The command above only affects existing files. New files created in the directory won’t have the ACL. To fix this, you need default ACLs:

setfacl --recursive --modify d:u:sftpdev:rX /srv/www/example.com

The d: prefix creates a default ACL that automatically applies to newly created files and directories.

The Complete Solution: Both Current and Future Files

To grant read-only access that applies to both existing and future files, combine both commands:

setfacl --recursive --modify u:sftpdev:rX,d:u:sftpdev:rX /srv/www/example.com

This single command:
1. Grants read-only access to all existing files and directories
2. Sets default ACLs so new files automatically inherit the same permissions

Understanding setfacl Syntax in Depth

The general syntax for setfacl is:

setfacl [options] [acl_spec] file/directory

ACL Specification Format

The ACL specification (acl_spec) follows this pattern:

[d:]<type>:<qualifier>:<permissions>
Component Description Examples
d: Optional prefix for default ACLs d:u:bob:rw
<type> u (user), g (group), o (other), m (mask) u, g, m
<qualifier> Username, group name, or empty for file owner/group bob, developers, (empty)
<permissions> r (read), w (write), x/X (execute), - (none) rw, r-x, rwx

Examples of ACL Specifications

# User 'alice' gets read and write
u:alice:rw

# Group 'devteam' gets read, write, execute
g:devteam:rwx

# Remove all permissions for user 'bob'
u:bob:---

# Set default ACL for group 'auditors' with read-only
d:g:auditors:r

# Modify the ACL mask (effective permissions limit)
m::rx

Essential setfacl Options Every Admin Should Know

Recursive Operations

# Apply ACL recursively to directories and files
setfacl -R -m u:developer:rX /var/www

# The long form
setfacl --recursive --modify u:developer:rX /var/www

Removing ACLs

# Remove specific ACL entry
setfacl -x u:developer /var/www/project

# Remove all ACLs (restore to standard permissions)
setfacl -b /var/www/project

# Remove default ACLs only
setfacl -k /var/www/project

# Remove all ACLs recursively
setfacl -R -b /var/www/project

Copying ACLs Between Files

# Copy ACLs from one file to another
getfacl source_file | setfacl --set-file=- target_file

# Copy ACLs recursively
getfacl -R /source/dir > acl_backup.txt
setfacl --restore=acl_backup.txt

Setting ACLs from a File

Create an ACL specification file:

# acl_config.txt
user:developer:rX
user:auditor:r
group:webteam:rwX
default:user:developer:rX
default:group:webteam:rwX

Apply it:

setfacl -M acl_config.txt /srv/www/example.com

Viewing ACLs with getfacl

The getfacl command displays current ACLs:

getfacl /srv/www/example.com

Output example:

# file: srv/www/example.com
# owner: www-data
# group: www-data
user::rwx
user:sftpdev:r-x
group::r-x
mask::r-x
other::---
default:user::rwx
default:user:sftpdev:r-x
default:group::r-x
default:mask::r-x
default:other::---

Understanding the Output

The ACL Mask: Your Security Safety Net

The mask entry is often overlooked but crucial. It defines the maximum effective permissions for all ACL entries (except the owner). Even if you grant rwx to a user, the mask limits what’s actually effective:

# Set mask to read-only
setfacl -m m::r /sensitive/file

# Now even users with 'rwx' ACL only get 'r'

To see effective permissions (considering the mask):

getfacl /sensitive/file

You’ll see output like:

user:developer:rwx    #effective:r--

Real-World Use Cases

1. Development Team Access to Staging Server

Grant different access levels to multiple teams:

# Website root
WEB_ROOT="/srv/www/staging.example.com"

# Developers get full access
setfacl -R -m u:dev1:rwX,u:dev2:rwX,d:u:dev1:rwX,d:u:dev2:rwX $WEB_ROOT

# QA team gets read-only
setfacl -R -m g:qa:rX,d:g:qa:rX $WEB_ROOT

# External auditor gets read-only to logs only
setfacl -R -m u:auditor:rX /srv/www/staging.example.com/logs

2. Protecting Configuration Files

Allow web server to read configs but prevent accidental writes:

# Apache/NGINX needs read access
setfacl -m u:www-data:r /etc/myapp/config.yml

# Developer can edit
setfacl -m u:developer:rw /etc/myapp/config.yml

# Default: no one else
setfacl -m o::--- /etc/myapp/config.yml

3. Shared Upload Directory

Multiple users can upload, but only specific users can delete:

UPLOAD_DIR="/var/www/uploads"

# Users can read and write (create files)
setfacl -m g:uploaders:rwx $UPLOAD_DIR

# But only admin can delete (via directory sticky bit + ACL)
chmod +t $UPLOAD_DIR
setfacl -m u:admin:rwx $UPLOAD_DIR

4. Git Workflow: Developer Read-Only Access to Production

In a Git-based deployment workflow, give developers read access to verify deployments without write access:

# Create the SFTP user
useradd -m -s /sbin/nologin sftpdev

# Grant read-only recursive access with defaults for new files
setfacl -R -m u:sftpdev:rX,d:u:sftpdev:rX /srv/www/production.example.com

# Verify
sudo -u sftpdev cat /srv/www/production.example.com/index.php  # Works
sudo -u sftpdev touch /srv/www/production.example.com/test     # Permission denied

Troubleshooting Common setfacl Issues

“Operation not supported” Error

Your filesystem may not have ACL support enabled:

# Check current mount options
mount | grep "on /srv"

# Remount with ACL support
sudo mount -o remount,acl /srv

# Make permanent in /etc/fstab
# Add 'acl' to options: /dev/sda1 /srv ext4 defaults,acl 0 2

ACLs Not Inherited by New Files

You forgot to set default ACLs:

# Add the 'd:' prefix for defaults
setfacl -m d:u:developer:rX /var/www

Permissions Don’t Match ACL

The mask is limiting effective permissions:

# Check effective permissions
getfacl /path/to/file

# Adjust mask if needed
setfacl -m m::rwx /path/to/file

ACLs Lost After rsync or cp

Standard cp and rsync don’t preserve ACLs by default:

# Use cp with ACL preservation
cp -a --preserve=all source dest

# rsync with ACL support
rsync -avA source/ dest/

# The -A flag preserves ACLs

Security Best Practices with setfacl

  1. Principle of Least Privilege: Start with no permissions and add only what’s needed
# Remove all access first
setfacl -b /sensitive/dir
chmod 700 /sensitive/dir

# Add specific access
setfacl -m u:authorized_user:rX /sensitive/dir
  1. Audit ACLs Regularly: Create scripts to check ACL configurations
# Find all files with ACLs
getfacl -R /srv/www 2>/dev/null | grep -B3 "^user:" | grep "^# file:"
  1. Document Your ACLs: Backup ACL configurations
# Backup
getfacl -R /srv/www > /backup/www-acls-$(date +%Y%m%d).txt

# Restore
setfacl --restore=/backup/www-acls-20260118.txt
  1. Use Groups When Possible: Easier to manage than individual user ACLs
# Create group and add users
groupadd webdevs
usermod -aG webdevs alice
usermod -aG webdevs bob

# Set ACL for group instead of individuals
setfacl -R -m g:webdevs:rwX,d:g:webdevs:rwX /var/www

setfacl vs chmod: When to Use Each

Feature chmod setfacl
Users supported Owner only Multiple users
Groups supported One group Multiple groups
Default inheritance No (use umask) Yes (default ACLs)
Complexity Simple More complex
Compatibility Universal Requires ACL-enabled FS
Best for Simple scenarios Multi-user environments

Rule of thumb: Use chmod for simple owner/group scenarios. Use setfacl when you need more granular control or multiple users/groups with different permissions.

Performance Considerations

ACLs add minimal overhead to file operations. However, for filesystems with millions of files and complex ACLs, consider:

# Find ACL entries for non-existent users
getfacl -R /srv/www 2>&1 | grep "No such user"

Quick Reference: Common setfacl Commands

Here’s a handy cheat sheet for the most frequently used setfacl operations:

# Add read-only access for a user
setfacl -m u:username:r file

# Add read/write/execute for a group
setfacl -m g:groupname:rwx directory

# Add recursive read-only with directory traversal
setfacl -R -m u:username:rX directory

# Set default ACL for new files
setfacl -m d:u:username:rX directory

# Combined: current + default ACL in one command
setfacl -R -m u:username:rX,d:u:username:rX directory

# Remove specific user ACL
setfacl -x u:username file

# Remove all ACLs
setfacl -b file

# Remove default ACLs only
setfacl -k directory

# View current ACLs
getfacl file

# Backup ACLs
getfacl -R directory > backup.acl

# Restore ACLs
setfacl --restore=backup.acl

Frequently Asked Questions

Do ACLs override standard permissions?

No, ACLs work alongside standard permissions. The most restrictive permission wins when both are evaluated. The file owner’s permissions and the “other” permissions are always determined by standard permissions, while ACLs extend control for additional users and groups.

Will ACLs survive a system reboot?

Yes, ACLs are stored in the filesystem’s metadata and persist across reboots. However, if you restore files from a backup that doesn’t preserve ACLs, you’ll lose them.

Can I use ACLs with SELinux or AppArmor?

Yes, ACLs operate at the discretionary access control (DAC) level, while SELinux and AppArmor provide mandatory access control (MAC). Both systems are evaluated independently – a file access must be permitted by both DAC (including ACLs) and MAC to succeed.

How do I know if a file has ACLs?

Files with ACLs show a + sign at the end of the permission string in ls -l output:

$ ls -l
-rw-r--r--+ 1 www-data www-data 1234 Jan 18 10:00 index.php

The + indicates extended ACLs are present.

Conclusion

The setfacl command transforms Linux file permission management from a limitation to a powerful feature. Whether you’re setting up secure developer access to production files, implementing multi-team access controls, or ensuring new files automatically inherit the right permissions, ACLs provide the flexibility that traditional Unix permissions lack.

Key takeaways:

With these techniques, you can implement enterprise-grade access control on any Linux server without the complexity of dedicated access management systems. The combination of granular user permissions, group-based access, and automatic inheritance through default ACLs makes setfacl an indispensable tool in any Linux administrator’s arsenal.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience • Maintainer of GetPageSpeed RPM repository • Contributor to open-source NGINX modules

Exit mobile version