Linux

Linux Permissions: Complete Guide to chmod, ACL, and Attributes

In this guide, you'll learn how to properly configure file and directory permissions in Linux using chmod, ACL, and special attributes to ensure system security and stability.

15 minutes
Medium

Introduction / Why This Matters

Permissions in Linux are a fundamental security mechanism that defines who (which user or group) can do what with files and directories. Misconfigured permissions are one of the most common causes of vulnerabilities, service failures, and "Permission denied" errors. This guide will help you confidently manage permissions, use both basic tools (chmod, chown) and advanced ones (ACL, chattr), and understand the underlying logic of the Linux system. After completing it, you'll be able to properly configure access for web servers, shared directories, scripts, and system files.

Prerequisites / Preparation

  • Access to a Linux terminal (Ubuntu, CentOS, Debian, Arch, or any other distribution).
  • Superuser privileges (sudo) to modify system file permissions and use chattr.
  • Basic command-line knowledge: ls, cd, cat.
  • The acl package installed (for working with extended ACLs) on RPM/Deb-based distributions:
    # For Debian/Ubuntu
    sudo apt update && sudo apt install acl
    
    # For RHEL/CentOS/Fedora
    sudo yum install acl
    
  • Knowledge of what you are doing. Changing permissions on system files (/etc, /bin, /usr) can render the system unusable.

Step-by-Step Guide

Step 1: Check Current File Permissions

Before making any changes, always verify the current permissions. The ls -l command is your primary tool.

ls -l /etc/passwd /home/user/documents

Example output:

-rw-r--r-- 1 root root  1234 Feb 17 10:00 /etc/passwd
drwxr-xr-x 2 user user  4096 Feb 17 10:05 /home/user/documents

How to read it:

  • First character: - is a regular file, d is a directory, l is a symbolic link.
  • Next 9 characters: three groups of three.
    • rw- (owner): read (r), write (w), no execute (x).
    • r-- (group): read-only.
    • r-- (others): read-only.
  • Owner: root, Group: root (for the first file).

Step 2: Change Permissions with Numeric Method (chmod)

This is the fastest and most common method. Each permission type (owner, group, others) corresponds to a digit in the octal system.

Logic:

  • 4 = read
  • 2 = write
  • 1 = execute
  • Sum: 7 = 4+2+1 (rwx), 6 = 4+2 (rw-), 5 = 4+1 (r-x), 0 = ---

Examples:

# Give owner all permissions (rwx), group and others only read and execute (r-x)
chmod 755 script.sh

# Allow owner read/write, group read-only, others no permissions
chmod 640 config.conf

# Recursively (including all nested files and directories) set permissions to 755 for the project/ directory
chmod -R 755 project/

⚠️ Important: Using chmod -R requires caution. Directories usually need x (to access contents), but it's not always required for files. The command chmod -R 755 /some/path will set x for all files, which may be insecure.

Step 3: Change Permissions with Symbolic Method (chmod)

A more flexible and readable method, especially when you need to modify only one part of the permissions.

Syntax: chmod [ugoa][+-=][rwx] <file>

  • Who: u (user/owner), g (group), o (others), a (all, default).
  • Operator: + (add), - (remove), = (set exactly).
  • Permissions: r, w, x.

Examples:

# Add execute permission (x) for the file's owner
chmod u+x /usr/local/bin/myscript

# Remove write permission (w) from group and others
chmod go-w sensitive_data.txt

# Owner: rwx, Group: rwx, Others: --- (full isolation)
chmod 770 private_folder/
# Or symbolically: chmod u=rwx,g=rwx,o= private_folder/

# Give the group the same permissions as the owner (common for shared work)
chmod g=u shared_file.log

Step 4: Configure Extended ACLs (setfacl)

The standard model (owner/group/others) is often insufficient. ACL (Access Control Lists) allow you to set permissions for specific users or groups without changing the file's owner or primary group.

Setting permissions:

# Give user ivan full access (rwx) to the report.pdf file
sudo setfacl -m u:ivan:rwx report.pdf

# Give the developers group read and write (rw-) permissions to the src/ directory
sudo setfacl -m g:developers:rw- src/

# Remove the ACL entry for user ivan
sudo setfacl -x u:ivan report.pdf

Viewing ACLs:

# Show standard and extended permissions
getfacl report.pdf

Example getfacl output:

# file: report.pdf
# owner: user
# group: staff
user::rw-
group::r--
mask::rwx
other::r--
user:ivan:rwx        # <- our ACL entry
group:developers:rw- # <- another ACL entry

Note: mask is the mask for ACL entries. It usually matches the maximum permissions from all ACL entries for group/others. It's set automatically but can be modified via setfacl -m m::rwx.

Recursive ACL setup for a directory:

# Set default ACLs for new files in a directory (crucial for shared folders)
sudo setfacl -d -m g:developers:rwx /projects/shared/
# Now all new files created in /projects/shared/ will inherit these permissions.

Step 5: Set Special Attributes (chattr)

Attributes managed by the chattr command work at the filesystem level (ext3/ext4, XFS) and cannot be changed by ordinary means, even by root, while set. This is a powerful tool for protecting critical files.

Key flags:

  • i (immutable) — file cannot be modified, deleted, renamed, or have links created to it.
  • a (append-only) — file can only be appended to (e.g., for logs).
  • s (secure deletion) — when the file is deleted, disk blocks are zeroed (slow).
  • u (undelete) — upon deletion, the possibility of recovery is preserved.

Examples:

# Make a file immutable (protection against accidental deletion/modification)
sudo chattr +i /etc/nginx/nginx.conf
# Check attributes: lsattr /etc/nginx/nginx.conf

# Allow changes (remove protection)
sudo chattr -i /etc/nginx/nginx.conf

# Set "append-only" mode for a log file (protection against substitution)
sudo chattr +a /var/log/application.log

Important: For directories, the i flag blocks creating/deleting files inside it.

Step 6: Working with setuid, setgid, and Sticky Bit

These are special permission bits that alter the behavior of file execution or creation.

  • setuid (4000 / s for owner): When an executable file has this bit set, it runs with the file owner's privileges, not the user who executed it. Classic example: passwd (owner is root).
    ls -l /usr/bin/passwd
    # -rwsr-xr-x 1 root root ... /usr/bin/passwd
    # Note the 's' instead of 'x' for the owner.
    

    ⚠️ Caution! Do not set setuid on scripts (bypass via interpreter) or untrusted programs.

  • setgid (2000 / s for group): Two effects:
    1. For an executable file: it runs with the group-owner's privileges.
    2. For a directory: all new files created inside inherit the directory's group-owner, not the user's primary group who created them. Essential for shared directories.
    # Set setgid on the shared directory (so new files belong to group 'devs')
    chmod 2775 /shared/
    # Or symbolically: chmod g+s /shared/
    
  • sticky bit (1000 / t for others): In a directory with the sticky bit, a user can delete/rename only their own files, even if they have write permission on the directory. Classic example: /tmp.
    ls -ld /tmp
    # drwxrwxrwt 10 root root ... /tmp
    # Note the 't' instead of 'x' for others.
    

Step 7: Manage Owner and Group (chown, chgrp)

Sometimes you need to change the ownership of a file, not just its permissions.

# Change file owner
sudo chown alice:developers config.yml
# Equivalent to: sudo chown alice config.yml && sudo chgrp developers config.yml

# Recursively change owner of the entire project directory and its contents
sudo chown -R www-data:www-data /var/www/project/

# Change only the group (chgrp)
sudo chgrp -R staff /opt/scripts/

Verification

After making changes, always verify them:

  1. For standard permissions: ls -l <file/directory>
  2. For ACLs: getfacl <file/directory>
  3. For chattr attributes: lsattr <file/directory>
  4. Practical test: Try performing the action as a different user (using sudo -u <user> <command> or switching to their session) to ensure access works as intended.

Common Issues

  • "Permission denied" when running a script: Check if the file owner and current user have execute permission (x). Also check if the i attribute is set via chattr.
  • Loss of access after chmod 777 or chmod 000: If you accidentally set overly permissive or restrictive permissions, restore the correct values via sudo chmod (if you still have sudo rights) or boot into recovery mode.
  • ACLs not working: Ensure the filesystem is mounted with the acl option (usually default in modern distributions). Check /etc/fstab. Changes in fstab may require remounting the partition.
  • Setuid on a script doesn't work: This is a Linux kernel limitation. Setuid works only with binary executable files. For scripts, use sudo with configuration in /etc/sudoers or setgid on a directory with a wrapper script.
  • Cannot delete a file in a setgid directory: Ensure you have write permission (w) on the directory itself, not just the file. Deleting a file is a modification of the directory's contents.

Want to dive deeper into privilege management? Check out our detailed guide on configuring sudoers for secure delegation of privileges: /guides/linux/linux-sudoers-config

Conclusion and Best Practices

  1. Principle of Least Privilege: Grant only the permissions necessary for operation. Avoid 777 and 666.
  2. Use groups for shared access: Create groups (groupadd devs), add users (usermod -aG devs alice), and grant permissions to the group (chmod 770 /project).
  3. For complex scenarios — use ACLs: If the owner/group/others model is insufficient, switch to ACLs immediately.
  4. Protect critical files: Use chattr +i for kernel configuration files, system utilities, or important scripts.
  5. Use setuid/setgid wisely: Set them only on trusted, verified binary executables. Never on scripts.
  6. Always verify: After setting permissions, test access from the perspective of the intended users.

Permissions are a powerful but delicate tool. Master them, and your Linux system will become significantly more reliable and secure.

F.A.Q.

What is umask and how does it affect permissions of new files?
Why is chmod 777 dangerous and when can it be used?
How to differentiate between chown and chmod?

Hints

Check current file permissions
Change permissions using numeric method (chmod)
Change permissions using symbolic method (chmod)
Configure advanced ACL (setfacl)
Set special attributes (chattr)

Did this article help you solve the problem?

FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community