Linux permissions form the backbone of system security, controlling who can read, write, or execute files and directories. Understanding this system is crucial for maintaining a secure environment and managing multi-user systems effectively.
Linux uses a three-tiered permission system that defines access rights for three categories of users:
- Owner (User): The person who created or owns the file
When you run ls -l
, you see output like this:
-rw-r--r-- 1 username groupname 1024 Jul 19 10:30 document.txt
drwxr-xr-x 2 username groupname 4096 Jul 19 10:30 my_directory
Let's break down the permission string -rw-r--r--
:
- rw- r-- r--
│ │ │ │
│ │ │ └── Others permissions (r--)
│ │ └────── Group permissions (r--)
│ └────────── Owner permissions (rw-)
└──────────── File type (-=file, d=directory, l=link)
1. Read (r)
2. Write (w)
3. Execute (x)
1. Setuid (s): File executes with owner's privileges 2. Setgid (s): File executes with group's privileges, or new files inherit group ownership 3. Sticky bit (t): Only owner can delete files in the directory
Permissions can be represented as three-digit numbers:
Owner Group Others
rwx rwx rwx
421 421 421
- 755: rwxr-xr-x (Owner: full, Group/Others: read+execute)
# Add permissions
chmod u+x file.txt # Add execute for user (owner)
chmod g+w file.txt # Add write for group
chmod o+r file.txt # Add read for others
chmod a+x file.txt # Add execute for all (user, group, others)
# Remove permissions
chmod u-w file.txt # Remove write for user
chmod g-x file.txt # Remove execute for group
chmod o-r file.txt # Remove read for others
chmod a-w file.txt # Remove write for all
# Set exact permissions
chmod u=rwx file.txt # Set user to read, write, execute
chmod g=r file.txt # Set group to read only
chmod o= file.txt # Remove all permissions for others
chmod a=r file.txt # Set all to read only
# Common permission settings
chmod 755 script.sh # rwxr-xr-x (executable script)
chmod 644 document.txt # rw-r--r-- (regular file)
chmod 600 private.txt # rw------- (private file)
chmod 777 public_dir # rwxrwxrwx (full access - be careful!)
chmod 700 private_dir # rwx------ (private directory)
# Recursive permission changes
chmod -R 755 directory/ # Apply to directory and all contents
chmod -R u+x scripts/ # Add execute for user recursively
# Change owner only
sudo chown newuser file.txt
# Change owner recursively
sudo chown -R newuser directory/
# Change owner and group
sudo chown newuser:newgroup file.txt
sudo chown newuser: file.txt # Use user's primary group
# Change group only
sudo chgrp newgroup file.txt
# Change group recursively
sudo chgrp -R developers project/
# Change group with reference to another file
sudo chgrp --reference=template.txt file.txt
# Create project structure
mkdir ~/project
cd ~/project
mkdir {src,docs,scripts,config}
# Set directory permissions
chmod 755 src docs # Read/execute for all
chmod 700 config # Private configuration
chmod 755 scripts # Executable scripts directory
# Create and set file permissions
touch src/main.py docs/README.md scripts/deploy.sh config/secrets.conf
# Set appropriate file permissions
chmod 644 src/main.py # Regular source file
chmod 644 docs/README.md # Documentation
chmod 755 scripts/deploy.sh # Executable script
chmod 600 config/secrets.conf # Private configuration
# Typical web server permissions
sudo chown -R www-data:www-data /var/www/html/
chmod -R 755 /var/www/html/ # Directories executable
find /var/www/html/ -type f -exec chmod 644 {} \; # Files readable
chmod 600 /var/www/html/config/database.conf # Secure config files
# Create shared directory for team
sudo mkdir /shared/project
sudo chgrp developers /shared/project
sudo chmod 2775 /shared/project # Setgid bit ensures group ownership
# Files created here will inherit the 'developers' group
cd /shared/project
touch team_file.txt
ls -l team_file.txt # Should show 'developers' group
The umask
command sets default permissions for new files and directories:
# View current umask
umask
# Common umask values
umask 022 # Default: files 644, directories 755
umask 002 # Group-friendly: files 664, directories 775
umask 077 # Paranoid: files 600, directories 700
# Set umask in shell profile
echo "umask 022" >> ~/.bashrc
# Set setuid on executable
chmod 4755 program # or chmod u+s program
ls -l program # Shows -rwsr-xr-x
# Common setuid programs
ls -l /usr/bin/passwd # Allows users to change passwords
ls -l /usr/bin/sudo # Allows privilege escalation
# Set setgid on directory
chmod 2755 shared_directory # or chmod g+s shared_directory
ls -ld shared_directory # Shows drwxr-sr-x
# Set setgid on file
chmod 2755 group_program # Executes with group privileges
# Set sticky bit on directory
chmod 1755 temp_directory # or chmod +t temp_directory
ls -ld temp_directory # Shows drwxr-xr-t
# Common example: /tmp directory
ls -ld /tmp # Usually shows drwxrwxrwt
For more granular control beyond basic permissions:
# Check if filesystem supports ACLs
mount | grep acl
# View ACLs
getfacl filename
# Set ACL for specific user
setfacl -m u:username:rw filename
# Set ACL for specific group
setfacl -m g:groupname:r filename
# Remove ACL
setfacl -x u:username filename
# Remove all ACLs
setfacl -b filename
Grant only the minimum permissions necessary:
# Instead of 777, use specific permissions
chmod 755 script.sh # Not 777
chmod 644 data.txt # Not 666
# Use groups for shared access
sudo groupadd projectteam
sudo usermod -aG projectteam user1
sudo usermod -aG projectteam user2
sudo chgrp projectteam shared_file
chmod 664 shared_file
# Protect sensitive configuration
chmod 600 ~/.ssh/id_rsa # Private key
chmod 644 ~/.ssh/id_rsa.pub # Public key
chmod 700 ~/.ssh # SSH directory
chmod 600 ~/.my.cnf # Database credentials
chmod 600 /etc/shadow # Password hashes
# Scripts should not be world-writable
chmod 755 script.sh # Good
chmod 775 script.sh # Acceptable for group work
chmod 777 script.sh # Dangerous!
# Check for dangerous permissions
find /home -type f -perm -002 # World-writable files
find /home -type f -perm -004 # World-readable files (if sensitive)
# Home directory permissions
chmod 700 /home/username # Private home directory
chmod 755 /home/username # Readable home directory
# Temporary directories
chmod 1777 /tmp # Sticky bit prevents deletion by others
chmod 755 /var/tmp # Standard temporary directory
# Check file permissions
ls -l problematic_file
# Check directory permissions (need execute to access)
ls -ld directory_path
# Check ownership
ls -l file_or_directory
# Fix common issues
chmod +x script.sh # Make script executable
chmod +r file.txt # Make file readable
chmod +w file.txt # Make file writable
# Web files should be readable by web server
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 {} \;
# Special handling for upload directories
sudo chmod 775 /var/www/html/uploads/
sudo chown www-data:www-data /var/www/html/uploads/
# Fix SSH key permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts
# Find files with specific permissions
find /home -perm 777 # World-writable files
find /home -perm -u+s # Setuid files
find /home -perm -g+s # Setgid files
# Find files owned by specific user
find /home -user username
# Find files belonging to specific group
find /home -group groupname
# Check user's groups
groups username
id username
#!/bin/bash
# permission_audit.sh
echo "=== Permission Audit Report ==="
echo "Date: $(date)"
echo
echo "World-writable files:"
find /home -type f -perm -002 2>/dev/null
echo
echo "Setuid files:"
find /home -type f -perm -u+s 2>/dev/null
echo
echo "Files with no owner:"
find /home -nouser 2>/dev/null
echo
echo "Files with no group:"
find /home -nogroup 2>/dev/null
#!/bin/bash
# fix_permissions.sh
PROJECT_DIR="$1"
if [ -z "$PROJECT_DIR" ]; then
echo "Usage: $0 <project_directory>"
exit 1
fi
echo "Fixing permissions for: $PROJECT_DIR"
# Set directory permissions
find "$PROJECT_DIR" -type d -exec chmod 755 {} \;
# Set file permissions based on type
find "$PROJECT_DIR" -name "*.sh" -exec chmod 755 {} \; # Scripts
find "$PROJECT_DIR" -name "*.py" -exec chmod 644 {} \; # Python files
find "$PROJECT_DIR" -name "*.txt" -exec chmod 644 {} \; # Text files
find "$PROJECT_DIR" -name "*.md" -exec chmod 644 {} \; # Markdown files
echo "Permission fixing completed."
# Create test environment
mkdir ~/permission_test
cd ~/permission_test
# Create test files and directories
touch file1.txt file2.txt script.sh
mkdir dir1 dir2
# Practice permission changes
chmod 644 file1.txt # Regular file
chmod 755 script.sh # Executable script
chmod 700 dir1 # Private directory
chmod 755 dir2 # Public directory
# Verify changes
ls -la
# Create a shared project (requires sudo)
sudo mkdir /shared/team_project
sudo groupadd developers
# Add users to group (replace with actual usernames)
sudo usermod -aG developers user1
sudo usermod -aG developers user2
# Set up shared directory
sudo chgrp developers /shared/team_project
sudo chmod 2775 /shared/team_project
# Test group ownership inheritance
cd /shared/team_project
touch test_file.txt
ls -l test_file.txt
# Find potentially dangerous permissions
find ~ -type f -perm -002 2>/dev/null # World-writable files
find ~ -type f -perm -004 2>/dev/null # World-readable files
# Fix any issues found
# chmod o-w filename # Remove world write
# chmod o-r sensitive_file # Remove world read if needed
# Monitor file access with auditd (install if needed)
sudo apt install auditd
# Add audit rule for file access
sudo auditctl -w /etc/passwd -p rwxa -k passwd_changes
# View audit logs
sudo ausearch -k passwd_changes
# Monitor directory changes
sudo auditctl -w /etc -p wa -k etc_changes
# Create script to log permission changes
#!/bin/bash
# log_chmod.sh
# Function to log permission changes
log_chmod() {
local file="$1"
local old_perms="$(stat -c %a "$file" 2>/dev/null)"
# Run the actual chmod command
command chmod "$@"
local new_perms="$(stat -c %a "$file" 2>/dev/null)"
echo "$(date): Changed $file from $old_perms to $new_perms" >> ~/permission_changes.log
}
# Replace chmod with logging version
alias chmod='log_chmod'
Read (r) = 4
Write (w) = 2
Execute (x) = 1
Common Combinations:
7 = rwx (4+2+1)
6 = rw- (4+2+0)
5 = r-x (4+0+1)
4 = r-- (4+0+0)
3 = -wx (0+2+1)
2 = -w- (0+2+0)
1 = --x (0+0+1)
0 = --- (0+0+0)
# View permissions
ls -l file # Basic permissions
ls -ld directory # Directory permissions
stat file # Detailed file info
# Change permissions
chmod 755 file # Numeric method
chmod u+x file # Symbolic method
chmod -R 644 directory/ # Recursive
# Change ownership
chown user file # Change owner
chgrp group file # Change group
chown user:group file # Change both
# Special permissions
chmod u+s file # Set setuid
chmod g+s directory # Set setgid
chmod +t directory # Set sticky bit
# Files
644 # Regular files (rw-r--r--)
755 # Executable files (rwxr-xr-x)
600 # Private files (rw-------)
# Directories
755 # Standard directories (rwxr-xr-x)
700 # Private directories (rwx------)
775 # Group-writable directories (rwxrwxr-x)
1777 # Temporary directories with sticky bit
- Linux permissions control access through owner, group, and others categories
Understanding Linux permissions is fundamental to system security and effective file management. Practice these concepts regularly, and you'll develop an intuitive understanding of how to secure your files and directories appropriately.
---
This is Part 5 of our comprehensive Linux mastery series.
Previous: Linux File Management - Master file operations and organization
Next: Text Processing Tools - Master grep, sed, and awk for powerful text manipulation
Beginner Foundation:
Intermediate Skills:
Ready for Intermediate Skills? Continue with text processing to manipulate and analyze data efficiently!
---
Next: Dive into text processing and manipulation tools like grep, sed, and awk to become a command-line text processing expert.