Introduction
Understanding Linux file permissions and ownership is crucial for system security and proper access control. This comprehensive guide covers everything from basic permission concepts to advanced access control lists (ACLs), helping you master one of Linux’s most important security features.
Understanding Linux File Permissions
Linux uses a permission system that controls who can read, write, or execute files and directories. This system is fundamental to Linux security and multi-user functionality.
Permission Types
- Read (r): View file contents or list directory contents
- Write (w): Modify file contents or create/delete files in directory
- Execute (x): Run file as program or access directory
User Categories
- Owner (u): The user who owns the file
- Group (g): Users belonging to the file’s group
- Others (o): All other users on the system
Viewing File Permissions
Using ls -l Command
ls -l /path/to/file
Example output:
-rw-r--r-- 1 john developers 1024 Dec 15 10:30 document.txt
drwxr-xr-x 2 john developers 4096 Dec 15 10:25 folder
Breaking Down Permission String
The permission string -rw-r--r--
breaks down as:
- Position 1: File type (- = file, d = directory, l = link)
- Positions 2-4: Owner permissions (rw-)
- Positions 5-7: Group permissions (r–)
- Positions 8-10: Other permissions (r–)
Numeric Permission Representation
Permissions can also be expressed numerically:
- Read = 4
- Write = 2
- Execute = 1
Common numeric permissions:
- 755: rwxr-xr-x (owner: read/write/execute, group/others: read/execute)
- 644: rw-r–r– (owner: read/write, group/others: read)
- 600: rw——- (owner: read/write, group/others: no access)
- 777: rwxrwxrwx (all permissions for everyone – avoid!)
Changing File Permissions with chmod
Symbolic Method
# Add execute permission for owner
chmod u+x script.sh
# Remove write permission for group and others
chmod go-w file.txt
# Set specific permissions
chmod u=rw,g=r,o= sensitive.txt
# Add read permission for all
chmod a+r document.txt
# Multiple operations
chmod u+x,g-w,o=r file.txt
Numeric Method
# Set permissions to 644 (rw-r--r--)
chmod 644 file.txt
# Set permissions to 755 (rwxr-xr-x)
chmod 755 script.sh
# Set permissions to 600 (rw-------)
chmod 600 private.key
# Recursive permission change
chmod -R 755 /path/to/directory
Common Permission Scenarios
# Executable script
chmod 755 script.sh
# Configuration file
chmod 644 config.conf
# Private SSH key
chmod 600 ~/.ssh/id_rsa
# Public SSH key
chmod 644 ~/.ssh/id_rsa.pub
# Directory for shared files
chmod 775 /shared/directory
Managing File Ownership
Viewing Ownership
# Show ownership details
ls -l file.txt
# Show numeric user and group IDs
ls -n file.txt
# Show ownership for directory contents
ls -la /path/to/directory
Changing Ownership with chown
# Change owner only
sudo chown newowner file.txt
# Change owner and group
sudo chown newowner:newgroup file.txt
# Change group only (alternative to chgrp)
sudo chown :newgroup file.txt
# Recursive ownership change
sudo chown -R user:group /path/to/directory
# Change ownership using numeric IDs
sudo chown 1001:1001 file.txt
Changing Group Ownership with chgrp
# Change group ownership
sudo chgrp developers file.txt
# Recursive group change
sudo chgrp -R www-data /var/www/html
# Change group using numeric ID
sudo chgrp 1002 file.txt
Special Permissions
Setuid (SUID) – 4000
When set on executable files, runs with owner’s privileges instead of executor’s:
# Set SUID bit
chmod u+s /path/to/executable
# or
chmod 4755 /path/to/executable
# Example: passwd command has SUID
ls -l /usr/bin/passwd
# Output: -rwsr-xr-x
Setgid (SGID) – 2000
On executables: runs with group’s privileges. On directories: new files inherit directory’s group:
# Set SGID bit
chmod g+s /path/to/directory
# or
chmod 2755 /path/to/directory
# Example output: drwxr-sr-x
Sticky Bit – 1000
On directories: only file owner can delete files, regardless of directory permissions:
# Set sticky bit
chmod +t /shared/directory
# or
chmod 1755 /shared/directory
# Example: /tmp directory
ls -ld /tmp
# Output: drwxrwxrwt
Access Control Lists (ACLs)
ACLs provide more granular permission control beyond standard Unix permissions.
Installing ACL Support
# Ubuntu/Debian
sudo apt install acl
# CentOS/RHEL
sudo yum install acl
Viewing ACLs
# View ACL for file or directory
getfacl file.txt
# Check if filesystem supports ACLs
mount | grep acl
Setting ACLs
# Give user specific permissions
setfacl -m u:username:rw file.txt
# Give group specific permissions
setfacl -m g:groupname:r file.txt
# Remove specific ACL entry
setfacl -x u:username file.txt
# Remove all ACLs
setfacl -b file.txt
# Set default ACLs for directory
setfacl -d -m g:developers:rw /shared/project
# Recursive ACL application
setfacl -R -m u:webuser:rx /var/www/html
Practical Permission Scenarios
Web Server Setup
# Web directory permissions
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
# Make uploads directory writable
sudo chmod 775 /var/www/html/uploads
# Secure configuration files
sudo chmod 644 /var/www/html/config.php
sudo chown www-data:www-data /var/www/html/config.php
Shared Development Directory
# Create shared directory
sudo mkdir /shared/project
sudo chown :developers /shared/project
sudo chmod 2775 /shared/project
# Set default ACLs
sudo setfacl -d -m g:developers:rwx /shared/project
sudo setfacl -d -m o::r-x /shared/project
Secure File Storage
# Private user directory
chmod 700 /home/user/private
# Shared readable directory
chmod 755 /home/user/public
# Backup directory
sudo mkdir /backup
sudo chown backup:backup /backup
sudo chmod 750 /backup
Security Best Practices
Principle of Least Privilege
- Grant minimum permissions necessary
- Regularly audit file permissions
- Use groups for shared access
- Avoid 777 permissions
Critical File Permissions
# System configuration files
sudo chmod 644 /etc/passwd
sudo chmod 600 /etc/shadow
sudo chmod 644 /etc/group
# SSH configuration
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys
sudo chmod 644 /etc/ssh/sshd_config
# Sudo configuration
sudo chmod 440 /etc/sudoers
Finding Insecure Permissions
# Find world-writable files
find / -type f -perm -002 2>/dev/null
# Find SUID files
find / -type f -perm -4000 2>/dev/null
# Find SGID files
find / -type f -perm -2000 2>/dev/null
# Find files with no owner
find / -nouser 2>/dev/null
# Find large files with 777 permissions
find / -type f -perm 777 -size +1M 2>/dev/null
Troubleshooting Permission Issues
Common Problems and Solutions
Permission Denied Errors
# Check current permissions
ls -l file.txt
# Check directory permissions
ls -ld /path/to/directory
# Verify user/group membership
id username
groups username
Web Server Permission Issues
# Fix web directory permissions
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} ;
sudo find /var/www/html -type f -exec chmod 644 {} ;
SSH Permission Problems
# Fix SSH directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*
chmod 644 ~/.ssh/*.pub
Advanced Permission Management
Using umask
umask sets default permissions for new files and directories:
# View current umask
umask
# Set umask (subtract from 777 for directories, 666 for files)
umask 022 # Results in 755 for directories, 644 for files
umask 027 # Results in 750 for directories, 640 for files
# Set umask permanently in ~/.bashrc
echo "umask 022" >> ~/.bashrc
File Attributes
# View file attributes
lsattr file.txt
# Make file immutable (even root cannot modify)
sudo chattr +i important.txt
# Remove immutable attribute
sudo chattr -i important.txt
# Append-only attribute
sudo chattr +a logfile.txt
Automation and Scripting
Permission Checking Script
#!/bin/bash
# check_permissions.sh
check_file_perms() {
local file="$1"
local expected="$2"
if [[ -e "$file" ]]; then
current=$(stat -c "%a" "$file")
if [[ "$current" == "$expected" ]]; then
echo "✓ $file: $current (correct)"
else
echo "✗ $file: $current (expected $expected)"
fi
else
echo "✗ $file: does not exist"
fi
}
# Check critical files
check_file_perms "/etc/passwd" "644"
check_file_perms "/etc/shadow" "600"
check_file_perms "/etc/ssh/sshd_config" "644"
Monitoring and Auditing
Log File Analysis
# Monitor permission changes
sudo grep -i "chmod|chown|chgrp" /var/log/auth.log
# Audit file access
sudo ausearch -f /etc/passwd
# Monitor SUID/SGID execution
sudo ausearch -m EXECVE -sv yes
Regular Security Audits
# Create baseline of important files
find /etc /usr/bin /usr/sbin -type f ( -perm -4000 -o -perm -2000 ) > /tmp/setuid_baseline.txt
# Compare against baseline
find /etc /usr/bin /usr/sbin -type f ( -perm -4000 -o -perm -2000 ) | diff /tmp/setuid_baseline.txt -
Conclusion
Mastering Linux file permissions and ownership is essential for system security and proper access control. Start with understanding basic concepts, practice with common scenarios, and gradually implement advanced features like ACLs and special permissions.
Remember to always follow the principle of least privilege, regularly audit permissions, and stay vigilant about security best practices. Proper permission management is your first line of defense against unauthorized access and system compromise.