Imagine a high-security building with different levels of access—some people can enter any room, others can only access certain floors, and visitors are restricted to the lobby. That’s exactly how Linux file permissions work, controlling who can read, write, or execute files on your system.
Linux file permissions are the foundation of system security. They determine who can access files, modify configurations, execute programs, and potentially compromise your entire server. In 2026, with cybersecurity threats at an all-time high, understanding and properly managing file permissions is not just a skill—it’s a necessity.
In this comprehensive guide, we’ll demystify Linux file permissions, from basic concepts to advanced security configurations, with practical examples you can apply immediately.
Understanding the Basics
The Linux Permission Model
Linux uses a simple but powerful permission system based on:
- Users: Individual accounts (e.g.,
john,root) - Groups: Collections of users (e.g.,
developers,admins) - Others: Everyone else on the system
The Three Permission Types
Every file and directory has three types of permissions:
| Permission | Symbol | File Effect | Directory Effect |
|---|---|---|---|
| Read | r | View file contents | List directory contents |
| Write | w | Modify file | Create/delete/rename files |
| Execute | x | Run as program | Enter/cd into directory |
The Three Access Levels
Owner (User) → Group → Others
↓ ↓ ↓
rwx rwx rwx
- User/Owner: The user who owns the file
- Group: Users belonging to the file’s group
- Others: Everyone else on the system
Reading Permission Strings
When you run ls -l, you see something like:
-rw-r--r-- 1 john developers 1024 Mar 15 10:30 document.txt
drwxr-xr-x 2 john developers 4096 Mar 15 10:30 folder/
Let’s decode the permission string:
-rw-r--r--
││││││││││
│││││││││└─ Others: -- (no execute)
││││││││└─── Others: r- (read)
│││││││└───── Others: r-- (read only)
││││││└─────── Group: - (no execute)
│││││└───────── Group: r- (read)
││││└─────────── Group: r-- (read only)
│││└───────────── User: - (no execute)
││└─────────────── User: w- (write)
│└───────────────── User: r-- (read)
└─────────────────── File Type: - (regular file)
Common File Types
| Symbol | File Type |
|---|---|
- | Regular file |
d | Directory |
l | Symbolic link |
c | Character device |
b | Block device |
s | Socket |
p | Named pipe (FIFO) |
Numeric (Octal) Representation
Permissions can be represented numerically using octal values:
| Permission | Binary | Octal | Letter |
|---|---|---|---|
| No permission | 000 | 0 | --- |
| Execute only | 001 | 1 | —x |
| Write only | 010 | 2 | -w- |
| Write + Execute | 011 | 3 | -wx |
| Read only | 100 | 4 | r— |
| Read + Execute | 101 | 5 | r-x |
| Read + Write | 110 | 6 | rw- |
| Read + Write + Execute | 111 | 7 | rwx |
Permission Calculation
Owner: rw- = 4+2+0 = 6
Group: r-- = 4+0+0 = 4
Others: r-- = 4+0+0 = 4
Result: 644
Changing Permissions with chmod
Symbolic Method
# Add execute permission for user
chmod u+x script.sh
# Remove write permission for group
chmod g-w file.txt
# Add read permission for others
chmod o+r file.txt
# Set full permissions for user, read for others
chmod u=rwx,g=rx,o=r file.txt
# Add execute for all
chmod +x script.sh
# Recursive change (apply to all files and subdirectories)
chmod -R 755 directory/
Numeric Method
# Set rw-r--r-- (644)
chmod 644 file.txt
# Set rwxr-xr-x (755)
chmod 755 script.sh
# Set rwxr-x--- (750)
chmod 750 directory/
# Set rw------- (600) - private
chmod 600 ssh-key
# Set rw-rw-r-- (664)
chmod 664 shared-file.txt
Common Permission Patterns
| Pattern | Numeric | Meaning | Use Case |
|---|---|---|---|
rwx------ | 700 | Private file | SSH keys, personal scripts |
rwxr-x--- | 750 | Group access | Project files for team |
rwxr-xr-x | 755 | Public executable | Web scripts, programs |
rw-r----- | 640 | Group readable | Configuration files |
rw-r--r-- | 644 | Public readable | Web content, documents |
rwxrwxr-x | 775 | Shared group | Collaborative directories |
rwx------ | 700 | Private directory | ~/.ssh directory |
Changing Ownership with chown
Basic Syntax
# Change owner only
sudo chown john file.txt
# Change owner and group
sudo chown john:developers file.txt
# Change group only
sudo chown :developers file.txt
# Change ownership of directory recursively
sudo chown -R john:developers /project/
# Use reference file for ownership
chown --reference=template.txt newfile.txt
Advanced chown Examples
# Change owner for symbolic link
chown -h john symlink
# Preserve file attributes
chown --preserve-root -R john:users /
# Verbose output
chown -v john file.txt
# Change if current owner matches
chown --from=olduser john file.txt
Changing Groups with chgrp
# Change group only
sudo chgrp developers file.txt
# Change group recursively
sudo chgrp -R developers /project/
# Verbose mode
sudo chgrp -v developers file.txt
# Change group for symbolic links
sudo chgrp -h developers symlink
Special Permissions
1. SUID (Set User ID)
When a file has SUID set, it runs with the owner’s privileges, not the user who executes it.
# Set SUID (4 at the beginning)
chmod u+s /usr/bin/passwd
chmod 4755 /usr/bin/passwd
# Remove SUID
chmod u-s /usr/bin/passwd
Example: /usr/bin/passwd needs root privileges to modify /etc/shadow.
2. SGID (Set Group ID)
For files: Runs with the group’s privileges. For directories: New files inherit the directory’s group.
# Set SGID (2 at the beginning)
chmod g+s directory/
chmod 2770 directory/
# Remove SGID
chmod g-s directory/
# SGID on directory example
mkdir shared-project
sudo chown :developers shared-project
chmod g+s shared-project
# Now all files created in shared-project belong to developers group
3. Sticky Bit
Prevents users from deleting files they don’t own within a directory.
# Set sticky bit (1 at the beginning)
chmod +t /tmp
chmod 1777 /tmp
# Remove sticky bit
chmod -t /tmp
Example: /tmp directory uses sticky bit so users can’t delete others’ temporary files.
Understanding Special Permission Codes
| Special Bit | Symbol | Numeric | Directory Effect | File Effect |
|---|---|---|---|---|
| SUID | s on user | 4 | - | Runs as owner |
| SGID | s on group | 2 | Inherits group | Runs as group |
| Sticky | t on others | 1 | Owner-only deletion | - |
Full Numeric Representation
chmod 4755 script.sh
││││
│││└─ Others: r-x (5)
││└─── Group: r-x (5)
│└───── User: rwx (7)
└─────── Special: SUID (4)
Default Permissions with umask
umask defines the default permissions for newly created files and directories.
Understanding umask
- Files: Default 666 (rw-rw-rw-) minus umask
- Directories: Default 777 (rwxrwxrwx) minus umask
Common umask Values
| umask | File Permissions | Directory Permissions |
|---|---|---|
0000 | rw-rw-rw- (666) | rwxrwxrwx (777) |
0022 | rw-r—r— (644) | rwxr-xr-x (755) |
0027 | rw-r----- (640) | rwxr-x--- (750) |
0077 | rw------- (600) | rwx------ (700) |
Setting umask
# Check current umask
umask
# Set umask temporarily
umask 0022
# Make persistent (add to ~/.bashrc)
echo "umask 0027" >> ~/.bashrc
# System-wide umask
sudo nano /etc/profile
# Add: umask 0027
Advanced Permission Management
Access Control Lists (ACL)
ACLs provide more granular control than standard Unix permissions.
Installing ACL
# Ubuntu/Debian
sudo apt install acl
# CentOS/RHEL
sudo yum install acl
Basic ACL Commands
# Check if filesystem supports ACL
sudo tune2fs -l /dev/sda1 | grep "Default mount options"
# Grant read permission to specific user
setfacl -m u:john:r file.txt
# Grant write permission to specific group
setfacl -m g:developers:w file.txt
# Revoke permissions
setfacl -x u:john file.txt
# View ACLs
getfacl file.txt
# Recursive ACL
setfacl -R -m u:john:rwx directory/
# Set default ACL for new files
setfacl -d -m u:john:rwx directory/
Extended Attributes
# List extended attributes
lsattr file.txt
# Set immutable (cannot be modified/deleted)
sudo chattr +i file.txt
# Remove immutable
sudo chattr -i file.txt
# Set append-only
sudo chattr +a file.log
# Set secure deletion
sudo chattr +s sensitive-file
Security Best Practices
1. System File Permissions
# Critical system files
chmod 644 /etc/passwd
chmod 640 /etc/shadow
chmod 644 /etc/group
chmod 600 /etc/ssh/sshd_config
# Web root directory
chown -R www-data:www-data /var/www/
find /var/www/ -type f -exec chmod 644 {} \;
find /var/www/ -type d -exec chmod 755 {} \;
2. User Home Directories
# Standard home directory permissions
chmod 755 /home/username
chmod 700 /home/username/.ssh
chmod 600 /home/username/.ssh/authorized_keys
chmod 600 /home/username/.bash_history
3. Sensitive Files
# Private SSH keys
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
# Database configuration
chmod 640 /etc/mysql/my.cnf
# Application secrets
chmod 600 /var/www/.env
4. World-Writable Directories
# Find world-writable files
find / -type f -perm -0002 -ls 2>/dev/null
# Find world-writable directories
find / -type d -perm -0002 -ls 2>/dev/null
# Find SUID/SGID files
find / -perm /4000 -type f 2>/dev/null
find / -perm /2000 -type f 2>/dev/null
5. Automate Permission Audits
#!/bin/bash
# permission-audit.sh
echo "=== World-Writable Files ==="
find / -type f -perm -0002 2>/dev/null | head -20
echo "=== World-Writable Directories ==="
find / -type d -perm -0002 2>/dev/null | head -20
echo "=== SUID/SGID Files ==="
find / -perm /4000 -o -perm /2000 -type f 2>/dev/null | head -20
echo "=== Files Without Owner ==="
find / -nouser -o -nogroup 2>/dev/null | head -20
echo "=== Open Directories ==="
find / -type d -perm -o+w 2>/dev/null | head -20
Troubleshooting Permission Issues
Common Problems and Solutions
1. Permission Denied
# Check current permissions
ls -l file.txt
# Check effective user
whoami
groups
# Check ACLs
getfacl file.txt
2. Cannot Execute Script
# Add execute permission
chmod +x script.sh
# Check shebang line
head -1 script.sh
# Should be: #!/bin/bash
3. Cannot Edit File as Root
# Check extended attributes
lsattr file.txt
# If 'i' is set, remove immutable
chattr -i file.txt
4. SELinux Context Issues
# Check SELinux context
ls -Z file.txt
# Restore default context
restorecon -v file.txt
# Check audit logs
ausearch -m avc -ts recent
Practical Examples
Example 1: Web Server Setup
# Create web directory
sudo mkdir -p /var/www/myapp
# Set ownership to web user
sudo chown -R www-data:www-data /var/www/myapp
# Set directory permissions
sudo find /var/www/myapp -type d -exec chmod 755 {} \;
# Set file permissions
sudo find /var/www/myapp -type f -exec chmod 644 {} \;
# Make upload directory writable
sudo mkdir -p /var/www/myapp/uploads
sudo chmod 775 /var/www/myapp/uploads
# Set SGID for shared uploads
sudo chown :www-data /var/www/myapp/uploads
sudo chmod g+s /var/www/myapp/uploads
Example 2: Shared Development Directory
# Create shared project
sudo mkdir /var/development
# Set group ownership
sudo chown :developers /var/development
# Set permissions
sudo chmod 2775 /var/development
# SGID ensures new files inherit group
# Configure default permissions for new files
sudo setfacl -d -m u::rwx,g::rwx,o::r-x /var/development
# Grant specific user access
sudo setfacl -m u:john:rwx /var/development
Example 3: Secure File Transfer Directory
# Create secure directory
mkdir ~/secure-files
# Strict permissions
chmod 700 ~/secure-files
# Create encrypted subdirectory
mkdir ~/secure-files/encrypted
chmod 700 ~/secure-files/encrypted
# Set default permissions
umask 0077
# Add sticky bit to shared temp
mkdir /tmp/project
chmod 1777 /tmp/project
Example 4: Restore Default Permissions
#!/bin/bash
# restore-perms.sh
# Restore /etc permissions
sudo chmod 644 /etc/passwd /etc/group /etc/hosts
sudo chmod 600 /etc/shadow /etc/gshadow
sudo chmod 644 /etc/ssh/*.pub
sudo chmod 600 /etc/ssh/sshd_config
# Restore home directories
for user in $(ls /home); do
chown -R $user:$user /home/$user
chmod 755 /home/$user
chmod 700 /home/$user/.ssh 2>/dev/null
done
# Restore web directories
sudo chown -R www-data:www-data /var/www
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
Commands Reference
Quick Reference Table
| Command | Purpose | Example |
|---|---|---|
ls -l | View permissions | ls -l file.txt |
chmod | Change permissions | chmod 644 file.txt |
chown | Change owner/group | chown user:group file |
chgrp | Change group | chgrp group file |
umask | Set default permissions | umask 0022 |
setfacl | Set ACLs | setfacl -m u:user:rwx file |
getfacl | View ACLs | getfacl file.txt |
chattr | Set extended attributes | chattr +i file.txt |
lsattr | View extended attributes | lsattr file.txt |
Permission Cheat Sheet
# Common permission commands
# Symbolic method
chmod u+x file # Add execute for user
chmod g-w file # Remove write for group
chmod o+r file # Add read for others
chmod a+x file # Add execute for all
chmod u=rwx,go=r file # Set exact permissions
# Numeric method
chmod 755 file # rwxr-xr-x
chmod 644 file # rw-r--r--
chmod 700 file # rwx------
chmod 600 file # rw-------
chmod 750 file # rwxr-x---
chmod 640 file # rw-r-----
# Recursive
chmod -R 755 dir/ # Apply to all files and subdirectories
# Reference
chmod --reference=template file
# Special bits
chmod 4755 file # +SUID
chmod 2755 file # +SGID
chmod 1777 dir # +Sticky bit
chmod u+s file # +SUID symbolic
chmod g+s file # +SGID symbolic
chmod +t dir # +Sticky bit symbolic
# Ownership
chown user file # Change owner
chown :group file # Change group
chown user:group file # Change both
chown -R user:group dir # Recursive
Conclusion
Mastering Linux file permissions is essential for system security and administration. In 2026, with increasingly sophisticated attacks, proper permission management remains one of the most effective security controls available.
Key Takeaways:
- Always use the principle of least privilege
- Regularly audit permissions on your systems
- Use ACLs for complex permission requirements
- Special permissions (SUID/SGID/sticky bit) require careful consideration
- Document your permission policies
- Automate permission checks and remediation
Remember: Permissions are your first line of defense. Properly configured permissions can prevent data breaches, system compromises, and unauthorized access. Take the time to understand and implement them correctly.
Deepen your Linux knowledge: Explore our Complete Linux Security Hardening Guide.
Frequently Asked Questions (FAQs)
Q: What’s the difference between chmod 755 and chmod 755?
A: Nothing—they’re the same! Both set rwxr-xr-x permissions. The confusion might be with chmod 755 vs chmod 0755 (leading zero doesn’t change the meaning).
Q: Why can’t I delete a file I have write permission to? A: You need write permission on the directory containing the file, not the file itself. The directory’s write permission controls file creation/deletion.
Q: What happens if a file has SUID set on a directory? A: SUID is ignored on directories. Use SGID instead for directory inheritance.
Q: How do I check what groups I’m in?
A: Run groups or id to see your group memberships.
Q: Why is my umask value inverted from what I expect? A: Umask is subtracted from defaults (666 for files, 777 for directories). So umask 0022 gives files 644 and directories 755.
Q: Can I set different permissions for different groups?
A: Yes, use ACLs (setfacl) or create multiple groups and use group permissions.
Q: How do I make files created in a directory automatically inherit permissions?
A: Set SGID on the directory (chmod g+s dir) and use default ACLs (setfacl -d -m ...).
Discussion
Loading comments...