File Permissions and ACLs
Applies to CentOS Stream 9 & 10 / AlmaLinux 9.x & 10.x / Rocky Linux 9.x & 10.x
Linux file permissions are the cornerstone of system security. Every file and directory has a set of permission rules that control who can read, write, and execute them. When basic permissions are insufficient, ACLs (Access Control Lists) provide finer-grained control.
What You Will Learn
Section titled “What You Will Learn”- Understand the rwx permission model
- Use
chmodto modify permissions (symbolic and octal modes) - Use
chownandchgrpto change ownership and group - SUID, SGID, and Sticky Bit special permissions
- Use ACLs for fine-grained permission control
- Understand and configure umask
Prerequisites
Section titled “Prerequisites”- A system with EL 9.x installed
- A user account with
sudoprivileges - Familiarity with the basics of User and Group Management
Basic Permission Model
Section titled “Basic Permission Model”Viewing File Permissions
Section titled “Viewing File Permissions”$ ls -l /etc/nginx/nginx.conf-rw-r--r--. 1 root root 2488 Mar 24 10:00 /etc/nginx/nginx.confBreakdown of the output:
-rw-r--r--. 1 root root 2488 Mar 24 10:00 nginx.conf│├──┤├──┤├──┤ │ │ │ │ │ ││ │ │ │ │ │ │ │ │ └─ Filename│ │ │ │ │ │ │ │ └─ Modification time│ │ │ │ │ │ │ └─ File size│ │ │ │ │ │ └─ Group│ │ │ │ │ └─ Owner│ │ │ │ └─ Hard link count│ │ │ └─ Other users' permissions (other)│ │ └─ Group permissions (group)│ └─ Owner permissions (owner)└─ File type (- regular file, d directory, l symbolic link)rwx Permission Meanings
Section titled “rwx Permission Meanings”| Permission | Character | Meaning for Files | Meaning for Directories |
|---|---|---|---|
| Read | r | Read file contents | List directory contents |
| Write | w | Modify file contents | Create/delete files in the directory |
| Execute | x | Execute the file (script/program) | Enter the directory (cd) |
chmod: Modifying Permissions
Section titled “chmod: Modifying Permissions”Symbolic Mode
Section titled “Symbolic Mode”Symbolic mode uses u (owner), g (group), o (other), a (all) combined with + (add), - (remove), = (set) to modify permissions.
$ chmod u+x script.sh$ chmod o-w file.txt$ chmod g+rw shared.doc$ chmod u=rwx,g=r,o=r script.sh$ chmod a+x script.shOctal Mode
Section titled “Octal Mode”Each permission bit corresponds to a numeric value:
| Permission | Value |
|---|---|
r | 4 |
w | 2 |
x | 1 |
- | 0 |
Add up the permission values for owner, group, and others respectively:
| Number | Permission | Description |
|---|---|---|
7 | rwx | Read + write + execute |
6 | rw- | Read + write |
5 | r-x | Read + execute |
4 | r-- | Read-only |
3 | -wx | Write + execute |
2 | -w- | Write-only |
1 | --x | Execute-only |
0 | --- | No permissions |
$ chmod 755 script.sh$ chmod 644 config.conf$ chmod 700 private-dir/Recursive Permission Changes
Section titled “Recursive Permission Changes”$ chmod -R 755 /var/www/html/$ find /var/www/html/ -type d -exec chmod 755 {} +$ find /var/www/html/ -type f -exec chmod 644 {} +chown and chgrp: Changing Ownership and Group
Section titled “chown and chgrp: Changing Ownership and Group”Changing the Owner
Section titled “Changing the Owner”$ sudo chown webuser /var/www/html/index.html$ sudo chown webuser:webgroup /var/www/html/index.html$ sudo chown -R webuser:webgroup /var/www/html/Changing Only the Group
Section titled “Changing Only the Group”$ sudo chgrp developers project-file.txt$ sudo chgrp -R developers /opt/project/Special Permission Bits
Section titled “Special Permission Bits”In addition to the basic rwx permissions, Linux has three special permission bits.
SUID (Set User ID)
Section titled “SUID (Set User ID)”When an executable file has the SUID bit set, any user who runs the file will execute it as the file’s owner (rather than as themselves).
$ ls -l /usr/bin/passwd-rwsr-xr-x. 1 root root 32648 ... /usr/bin/passwdThe s in the owner permission is the SUID flag. When a regular user runs passwd, the process runs as root, allowing it to modify /etc/shadow.
$ sudo chmod u+s /path/to/program$ sudo chmod 4755 /path/to/program$ sudo find / -perm -4000 -type f 2>/dev/nullSGID (Set Group ID)
Section titled “SGID (Set Group ID)”For files: The process runs with the file’s group identity.
For directories: New files and subdirectories created within the directory automatically inherit the directory’s group instead of the creator’s primary group. This is very useful for team collaboration directories.
$ sudo chmod g+s /opt/shared-project/$ sudo chmod 2775 /opt/shared-project/$ ls -ld /opt/shared-project/drwxrwsr-x. 2 root developers 4096 ... /opt/shared-project/The s in the group permission is the SGID flag.
Sticky Bit
Section titled “Sticky Bit”When the Sticky Bit is set on a directory, files within it can only be deleted by the file’s owner or root, even if other users have write permission on the directory. The most common example is /tmp.
$ ls -ld /tmpdrwxrwxrwt. 15 root root 4096 ... /tmpThe t in the other users’ permission is the Sticky Bit flag.
$ sudo chmod +t /opt/shared-uploads/$ sudo chmod 1777 /opt/shared-uploads/Special Permissions Summary
Section titled “Special Permissions Summary”| Permission | Octal | Symbol | Effect on Files | Effect on Directories |
|---|---|---|---|---|
| SUID | 4 | u+s | Execute as the owner | (No special effect) |
| SGID | 2 | g+s | Execute as the group | New files inherit the directory’s group |
| Sticky | 1 | +t | (No special effect) | Only the owner can delete files |
Practical Example: Creating a Team Shared Directory
Section titled “Practical Example: Creating a Team Shared Directory”-
Create the shared directory
Create the directory $ sudo mkdir /opt/team-share -
Set the owner and group
Set ownership to the developers group $ sudo chown root:developers /opt/team-share -
Set permissions and SGID
Set SGID to ensure new files inherit the group $ sudo chmod 2775 /opt/team-share -
Verify
Confirm permissions are set correctly $ ls -ld /opt/team-sharedrwxrwsr-x. 2 root developers 4096 ... /opt/team-shareNow any member of the
developersgroup who creates files in this directory will have those files automatically belong to thedevelopersgroup. -
Test
Create a file as a developers group member $ touch /opt/team-share/test.txt$ ls -l /opt/team-share/test.txt-rw-rw-r--. 1 zhangsan developers 0 ... test.txt
umask: Default Permission Mask
Section titled “umask: Default Permission Mask”umask determines the default permissions for newly created files and directories. The permissions of a new file = base permissions - umask value.
- Base permissions for files:
666(no execute bit) - Base permissions for directories:
777
$ umask0022$ umask -Su=rwx,g=rx,o=rxEffect of umask 0022:
| Base Permissions | umask | Actual Permissions | |
|---|---|---|---|
| File | 666 | 022 | 644 (rw-r—r—) |
| Directory | 777 | 022 | 755 (rwxr-xr-x) |
Changing umask
Section titled “Changing umask”$ umask 027Effect of umask 027:
| Base Permissions | umask | Actual Permissions | |
|---|---|---|---|
| File | 666 | 027 | 640 (rw-r-----) |
| Directory | 777 | 027 | 750 (rwxr-x---) |
$ echo "umask 027" >> ~/.bashrcACLs (Access Control Lists)
Section titled “ACLs (Access Control Lists)”When the basic owner/group/other permission model is insufficient, ACLs allow you to set independent permissions for specific users or groups.
Viewing ACLs
Section titled “Viewing ACLs”$ getfacl /opt/team-share/config.txtExample output (no additional ACL):
# owner: zhangsan# group: developersuser::rw-group::rw-other::r--Setting ACLs
Section titled “Setting ACLs”$ sudo setfacl -m u:lisi:rw /opt/team-share/config.txt$ sudo setfacl -m g:qa:r /opt/team-share/config.txt$ getfacl /opt/team-share/config.txtExample output:
# owner: zhangsan# group: developersuser::rw-user:lisi:rw-group::rw-group:qa:r--mask::rw-other::r--ACL Operations in Detail
Section titled “ACL Operations in Detail”$ sudo setfacl -m u:username:permissions filepath$ sudo setfacl -m g:groupname:permissions filepath$ sudo setfacl -x u:lisi /opt/team-share/config.txt$ sudo setfacl -x g:qa /opt/team-share/config.txt$ sudo setfacl -b /opt/team-share/config.txt$ sudo setfacl -R -m u:lisi:rwx /opt/team-share/Default ACLs
Section titled “Default ACLs”Default ACLs cause newly created files within a directory to automatically inherit ACL rules:
$ sudo setfacl -d -m u:lisi:rw /opt/team-share/$ sudo setfacl -d -m g:qa:r /opt/team-share/$ getfacl /opt/team-share/Example output:
# file: opt/team-share/# owner: root# group: developers# flags: -s-user::rwxgroup::rwxother::r-xdefault:user::rwxdefault:user:lisi:rw-default:group::rwxdefault:group:qa:r--default:mask::rwxdefault:other::r-xNow new files created in this directory will automatically include ACL rules for lisi and the qa group.
The mask in ACLs
Section titled “The mask in ACLs”The mask defines the maximum permissions that users and groups can have in the ACL. Even if you set a user’s permissions to rwx, if the mask is r--, the user’s effective permissions will only be r--.
$ sudo setfacl -m m::rx /opt/team-share/config.txtPractical Example: Fine-Grained Project Permission Control
Section titled “Practical Example: Fine-Grained Project Permission Control”Suppose you have the following requirements:
- The project directory
/opt/webappbelongs to thewebdevgroup - Members of the
webdevgroup have full read-write access - The
qagroup can only read, not modify - User
deployerhas full access for deployments - Newly created files automatically inherit these rules
-
Create the directory and groups
Create the directory and groups $ sudo mkdir -p /opt/webapp$ sudo groupadd webdev$ sudo groupadd qa -
Set basic permissions
Set owner, group, and SGID $ sudo chown root:webdev /opt/webapp$ sudo chmod 2770 /opt/webapp -
Set ACLs
Read-only permissions for the qa group $ sudo setfacl -m g:qa:rx /opt/webappFull permissions for the deployer user $ sudo setfacl -m u:deployer:rwx /opt/webapp -
Set default ACLs (applied to newly created files)
Set default ACLs $ sudo setfacl -d -m g:webdev:rwx /opt/webapp$ sudo setfacl -d -m g:qa:rx /opt/webapp$ sudo setfacl -d -m u:deployer:rwx /opt/webapp -
Verify
View the complete ACL settings $ getfacl /opt/webapp
Common Issues
Section titled “Common Issues”Which Takes Priority, chmod or ACL
Section titled “Which Takes Priority, chmod or ACL”ACLs are an extension of basic permissions. When both exist:
- The file owner’s permissions are still controlled by
user:: - Other users’ permissions are jointly affected by ACL rules and the mask
chmodon group permissions modifies the mask value when ACLs are present
The File Owner is root, but Regular Users Can Still Read It
Section titled “The File Owner is root, but Regular Users Can Still Read It”Because the other (other users) permission allows reading. For example, permissions of 644 mean all users can read the file.
How to Determine Why a User Cannot Access a File
Section titled “How to Determine Why a User Cannot Access a File”$ ls -la /path/to/file$ getfacl /path/to/file$ namei -l /path/to/filenamei -l displays the permissions of each directory level in the path, helping you identify which level is blocking access.
How to Back Up and Restore ACLs
Section titled “How to Back Up and Restore ACLs”$ getfacl -R /opt/webapp > acl-backup.txt$ sudo setfacl --restore=acl-backup.txtFurther Reading
Section titled “Further Reading”- User and Group Management — Create and manage users and groups
- sudo Configuration — Administrator privilege configuration
- SELinux Introduction — Mandatory access control
man chmod/man chown/man setfacl/man getfacl