Linux Permissions Demystified: Controlling Access to Files and Directories

Linux Permissions Demystified: Controlling Access to Files and Directories
min read

Linux Permissions Demystified: Controlling Access to Files and Directories

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.

Understanding the Permission System

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

  • Group: A collection of users who share certain access rights
  • Others (World): Everyone else on the system

  • Viewing Permissions with `ls -l`

    When you run ls -l, you see output like this:

    plaintext
    -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--:

    plaintext
    - rw- r-- r--
    │ │   │   │
    │ │   │   └── Others permissions (r--)
    │ │   └────── Group permissions (r--)
    │ └────────── Owner permissions (rw-)
    └──────────── File type (-=file, d=directory, l=link)

    Permission Types

    Basic Permissions

    1. Read (r)

  • Files: Can view/read the file content
  • Directories: Can list directory contents
  • Numeric value: 4

    2. Write (w)

  • Files: Can modify/edit the file content
  • Directories: Can create, delete, or rename files within the directory
  • Numeric value: 2

    3. Execute (x)

  • Files: Can run the file as a program/script
  • Directories: Can access the directory (cd into it)
  • Numeric value: 1

  • Special Permissions

    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

    Numeric (Octal) Notation

    Permissions can be represented as three-digit numbers:

    plaintext
    Owner  Group  Others
     rwx    rwx    rwx
     421    421    421

    Common Permission Combinations:

    - 755: rwxr-xr-x (Owner: full, Group/Others: read+execute)

  • 644: rw-r--r-- (Owner: read+write, Group/Others: read only)
  • 600: rw------- (Owner: read+write, Group/Others: no access)
  • 777: rwxrwxrwx (Everyone: full access - dangerous!)
  • 700: rwx------ (Owner: full access, Group/Others: no access)

  • Changing Permissions with `chmod`

    Symbolic Method

    bash
    # 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

    Numeric Method

    bash
    # 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

    Changing Ownership with `chown` and `chgrp`

    Changing Owner

    bash
    # 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

    Changing Group

    bash
    # 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

    Practical Permission Examples

    Setting Up a Development Project

    bash
    # 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

    Web Server Directory Setup

    bash
    # 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

    Shared Project Directory

    bash
    # 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

    Advanced Permission Concepts

    Default Permissions and umask

    The umask command sets default permissions for new files and directories:

    bash
    # 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

    Special Permission Bits

    Setuid (Set User ID)

    bash
    # 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

    Setgid (Set Group ID)

    bash
    # 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

    Sticky Bit

    bash
    # 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

    Access Control Lists (ACLs)

    For more granular control beyond basic permissions:

    bash
    # 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

    Security Best Practices

    1. Principle of Least Privilege

    Grant only the minimum permissions necessary:

    bash
    # 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

    2. Secure Configuration Files

    bash
    # 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

    3. Executable Script Security

    bash
    # 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)

    4. Directory Security

    bash
    # 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

    Troubleshooting Permission Issues

    Common Permission Problems

    "Permission Denied" Errors

    bash
    # 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 Server Permission Issues

    bash
    # 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/

    SSH Key Permission Issues

    bash
    # 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

    Diagnostic Commands

    bash
    # 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

    Automation and Scripting

    Permission Audit Script

    bash
    #!/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

    Bulk Permission Fix Script

    bash
    #!/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."

    Practical Exercises

    Exercise 1: Basic Permission Management

    bash
    # 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

    Exercise 2: Multi-User Scenario

    bash
    # 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

    Exercise 3: Security Hardening

    bash
    # 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

    Monitoring and Logging

    File Access Monitoring

    bash
    # 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

    Log Permission Changes

    bash
    # 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'

    Quick Reference Guide

    Permission Values

    plaintext
    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)

    Essential Commands

    bash
    # 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

    Common Permission Patterns

    bash
    # 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

    Key Takeaways

    - Linux permissions control access through owner, group, and others categories

  • Understand both symbolic (rwx) and numeric (755) notation
  • Follow the principle of least privilege for security
  • Use groups for efficient multi-user access management
  • Special permissions (setuid, setgid, sticky bit) provide advanced functionality
  • Regular permission audits help maintain security
  • Always test permission changes in safe environments first

    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.

    ---

  • 🚀 Continue Your Linux Journey

    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

    📚 Complete Linux Series Navigation

    Beginner Foundation:

  • Part 1: Linux Introduction
  • Part 2: Terminal Commands
  • Part 3: File System Structure
  • Part 4: File Management
  • Part 5: Permissions & SecurityYou are here

    Intermediate Skills:

  • Part 6: Text Processing
  • Part 7: Package Management
  • Part 8: User & Group Management

    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.

  • Made With Love on