HxHippy

Linux File Permissions Deep Dive

Master the Unix permission system with chmod, chown, and access control lists.

Last updated: 2024-12-18

Understanding file permissions is fundamental to Linux security. This guide covers everything from basic permissions to ACLs.

The Permission Model

Every file and directory in Linux has three permission types for three user classes:

Permission Types

Symbol Numeric Meaning for Files Meaning for Directories
r 4 Read contents List contents
w 2 Modify contents Create/delete files
x 1 Execute as program Access (cd into)

User Classes

Class Symbol Description
Owner u The file's owner
Group g The file's group
Others o Everyone else

Reading Permissions

# Long listing shows permissions
ls -l myfile.txt
# Output: -rw-r--r-- 1 user group 1024 Dec 18 10:00 myfile.txt

# Breakdown:
# -         = file type (- = file, d = directory, l = link)
# rw-       = owner permissions (read, write, no execute)
# r--       = group permissions (read only)
# r--       = others permissions (read only)

Changing Permissions with chmod

Symbolic Mode

# Add execute permission for owner
chmod u+x script.sh

# Remove write permission from group
chmod g-w file.txt

# Set exact permissions (read/write for owner, read for others)
chmod u=rw,go=r document.txt

# Add read permission for all
chmod a+r public.txt

# Multiple changes at once
chmod u+x,g-w,o-rwx private.sh

Numeric (Octal) Mode

# Calculate by adding: r=4, w=2, x=1

# 755 = rwxr-xr-x (common for scripts)
chmod 755 script.sh

# 644 = rw-r--r-- (common for files)
chmod 644 document.txt

# 700 = rwx------ (private directory)
chmod 700 private/

# 600 = rw------- (sensitive files like SSH keys)
chmod 600 ~/.ssh/id_rsa

# Common permission patterns:
# 777 = rwxrwxrwx (dangerous! everyone can do everything)
# 755 = rwxr-xr-x (public executable/directory)
# 750 = rwxr-x--- (group can read/execute)
# 644 = rw-r--r-- (public readable file)
# 640 = rw-r----- (group readable file)
# 600 = rw------- (private file)

Changing Ownership with chown

# Change owner
sudo chown newowner file.txt

# Change owner and group
sudo chown newowner:newgroup file.txt

# Change only group
sudo chown :newgroup file.txt
# or
sudo chgrp newgroup file.txt

# Recursive (all files in directory)
sudo chown -R user:group /path/to/directory

Special Permissions

SUID (Set User ID)

When set on an executable, runs as the file owner:

# Set SUID
chmod u+s program
# or
chmod 4755 program

# Example: /usr/bin/passwd runs as root to change passwords
ls -l /usr/bin/passwd
# -rwsr-xr-x (note the 's' in owner execute position)

SGID (Set Group ID)

For executables: runs as the file's group For directories: new files inherit the directory's group

# Set SGID on directory
chmod g+s shared_folder/
# or
chmod 2755 shared_folder/

# All new files will have the directory's group

Sticky Bit

Only owner can delete their files in the directory:

# Set sticky bit
chmod +t /shared/tmp
# or
chmod 1777 /shared/tmp

# Example: /tmp uses sticky bit
ls -ld /tmp
# drwxrwxrwt (note the 't' at the end)

Access Control Lists (ACLs)

For more granular permissions beyond owner/group/others:

# Check if filesystem supports ACLs
mount | grep acl

# View ACLs
getfacl file.txt

# Grant user specific permissions
setfacl -m u:alice:rw file.txt

# Grant group specific permissions
setfacl -m g:developers:rx directory/

# Set default ACL for new files in directory
setfacl -d -m u:alice:rw project/

# Remove specific ACL
setfacl -x u:alice file.txt

# Remove all ACLs
setfacl -b file.txt

Default Permissions: umask

# View current umask
umask
# Output: 0022

# umask subtracts from default (666 for files, 777 for directories)
# umask 022: files=644, directories=755

# Set restrictive umask
umask 077  # files=600, directories=700

# Make permanent (add to ~/.bashrc)
echo "umask 027" >> ~/.bashrc

Common Permission Scenarios

Web Server Directory

# Web root owned by web user
sudo chown -R www-data:www-data /var/www/html

# Directories: 755 (navigate and list)
find /var/www/html -type d -exec chmod 755 {} \;

# Files: 644 (read only)
find /var/www/html -type f -exec chmod 644 {} \;

Shared Team Directory

# Create shared directory
sudo mkdir /shared/project

# Set group ownership and SGID
sudo chown :developers /shared/project
sudo chmod 2775 /shared/project

# Now all files created here belong to 'developers' group

Secure Home Directory

# Lock down home directory
chmod 700 ~

# Secure SSH directory
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys

Troubleshooting Permission Issues

# Check effective permissions for current user
namei -l /path/to/file

# Check if you're in the right group
groups
id

# Trace permission denials
sudo strace -e openat command_that_fails 2>&1 | grep -i denied

# Find files with specific permissions
find / -perm 777 -type f 2>/dev/null  # World-writable files
find / -perm -4000 -type f 2>/dev/null  # SUID files
beginner Getting Started 20 min read

Related Tutorials

chmodchownpermissionsunix permissionsfile securityacl