Why does one user see 'Permission denied' while another can access the file? Why does your script need 'chmod +x' to run? File permissions are Linux's security backbone. Misconfigured permissions cause data breaches; correctly configured permissions protect your system. In this lesson, you'll master the permission system that every DevOps engineer uses daily to secure servers and applications.

1. Learning Objectives

By the end of this lesson, you will be able to:

  • Read and understand permission strings (-rw-r--r--)
  • Change permissions with chmod (numeric AND symbolic methods)
  • Change file ownership with chown and groups with chgrp
  • Understand umask and default permissions
  • Apply special permissions: SUID, SGID, Sticky Bit
  • Secure sensitive files and directories

2. Why This Matters

Real-world scenario: Your web server can't read the SSL certificate. The application can't write logs. A junior developer accidentally chmod 777 a configuration file containing database passwords. These are real security incidents caused by permission mistakes.

What you'll prevent:

  • ❌ Unauthorized access to sensitive files
  • ❌ Applications failing due to incorrect permissions
  • ❌ Accidental deletion of critical files
  • ❌ Privilege escalation vulnerabilities

3. Core Concepts

Understanding Permission Strings

$ ls -l
-rwxr-xr-- 1 alice devops 1234 Jan 17 10:00 script.sh
drwxr-x--- 2 bob   devops 4096 Jan 17 10:00 secrets/
-rw-r----- 1 root  root   5678 Jan 17 10:00 config.conf
Example permission strings

Breaking down -rwxr-xr--:

  • Position 1: File type (- = file, d = directory, l = link)
  • Positions 2-4: Owner permissions (read, write, execute)
  • Positions 5-7: Group permissions
  • Positions 8-10: Others (everyone else) permissions
# Permission Key:
# r = read (view contents)
# w = write (modify)
# x = execute (run as program)
# - = no permission

# Common permission patterns:
-rw-------  # Owner: read/write, Group: none, Others: none (private)
-rw-r--r--  # Owner: read/write, Group: read, Others: read (config files)
-rwxr-xr-x  # Owner: all, Group: read/execute, Others: read/execute (binaries)
drwx------  # Private directory (only owner)
drwxr-xr-x  # Public directory (anyone can list/enter)
Common permission patterns

Numeric Permissions (Octal Mode)

# Permission Values:
# r = 4
# w = 2  
# x = 1
# - = 0

# Calculate: r+w+x = 4+2+1 = 7
# r+w = 4+2 = 6
# r+x = 4+1 = 5
# r = 4
# etc.

# Common numeric permissions:
# 755 = rwxr-xr-x (Owner: all, Group/Others: read+execute)
# 644 = rw-r--r-- (Owner: read+write, Group/Others: read only)
# 600 = rw------- (Owner: read+write, others: none)
# 700 = rwx------ (Owner: all, others: none)
# 750 = rwxr-x--- (Owner: all, Group: read+execute, Others: none)
Numeric permission values
# Examples
chmod 755 script.sh   # rwxr-xr-x
chmod 644 config.txt  # rw-r--r--
chmod 600 secret.key  # rw-------
chmod 700 private_dir/ # drwx------

# Verify
ls -l script.sh config.txt secret.key private_dir/
Using numeric chmod

Symbolic Permissions

# Syntax: chmod [who][operator][permission] file
# who: u (user/owner), g (group), o (others), a (all)
# operator: + (add), - (remove), = (set exactly)
# permission: r, w, x

chmod u+x script.sh      # Add execute for owner
chmod g-w config.txt     # Remove write for group
chmod o+r public.txt     # Add read for others
chmod a+x script.sh      # Add execute for everyone
chmod u=rw,g=r,o=r file  # Set exact permissions (644)
chmod -R g+w docs/       # Recursive: add group write to all files in docs/
Symbolic chmod syntax

Changing Ownership

# chown: change file owner and group
chown alice file.txt                    # Change owner to alice
chown :devops file.txt                  # Change group only
chown alice:devops file.txt             # Change both
chown -R alice:devops directory/        # Recursive

# chgrp: change group only
chgrp devops file.txt

# View current ownership
ls -l
# -rw-r--r-- 1 alice devops 1234 Jan 17 10:00 file.txt

# Verify user and group information
id alice
# uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(devops)
Changing file ownership

Umask: Default Permissions

# View current umask
umask
# Output: 0022

# How umask works:
# Default file permission = 666 - umask
# Default directory permission = 777 - umask

# umask 022 (default):
# Files: 666 - 022 = 644 (rw-r--r--)
# Directories: 777 - 022 = 755 (rwxr-xr-x)

# umask 077 (secure):
# Files: 666 - 077 = 600 (rw-------)
# Directories: 777 - 077 = 700 (drwx------)

# Set umask temporarily
umask 077

# Set permanently (add to ~/.bashrc)
echo "umask 077" >> ~/.bashrc

# Check umask effect
touch newfile.txt
mkdir newdir
ls -ld newfile.txt newdir/
Understanding umask

Special Permissions (SUID, SGID, Sticky Bit)

# SUID (Set User ID) - runs with owner's privileges
# Numeric: 4xxx (e.g., 4755)
# Symbolic: u+s
chmod u+s /usr/bin/passwd
# -rwsr-xr-x (s instead of x for owner)

# SGID (Set Group ID) - runs with group's privileges
# Numeric: 2xxx (e.g., 2755)
# Symbolic: g+s
chmod g+s shared_directory/
# drwxr-sr-x (s instead of x for group)

# Sticky Bit - only file owner can delete
# Numeric: 1xxx (e.g., 1777)
# Symbolic: o+t
chmod 1777 /tmp
# drwxrwxrwt (t instead of x for others)
Special permissions
kubectl get pods -w
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Jan 17 10:00 /usr/bin/passwd
$ ls -ld /tmp
drwxrwxrwt 20 root root 4096 Jan 17 10:00 /tmp
$ ls -ld shared_dir/
drwxr-sr-x 2 alice devops 4096 Jan 17 10:00 shared_dir/
Special permissions in action

4. Hands-on Practice Lab

# Setup practice environment
mkdir ~/permissions-lab
cd ~/permissions-lab

# Create test files
echo "Secret data" > secret.txt
echo "Public data" > public.txt
mkdir private_dir shared_dir
Setup practice environment

Exercise 1: Basic Permissions

# Make secret.txt readable only by you (600)
chmod 600 secret.txt
ls -l secret.txt
# -rw-------

# Make public.txt readable by everyone (644)
chmod 644 public.txt
ls -l public.txt
# -rw-r--r--

# Make private_dir accessible only by you (700)
chmod 700 private_dir
ls -ld private_dir
# drwx------

# Test access
cat secret.txt           # Works (you own it)
sudo -u nobody cat secret.txt  # Fails (Permission denied)
Basic permission exercises

Exercise 2: Group Collaboration

# Create a shared directory for a team
sudo groupadd project-team
sudo usermod -aG project-team $USER

# Create shared directory with group permissions
mkdir team_project
chown :project-team team_project
chmod 770 team_project
ls -ld team_project
# drwxrwx--- 2 user project-team 4096 Jan 17 10:00 team_project/

# Allow members to edit each other's files
chmod g+s team_project
ls -ld team_project
# drwxrws--- (notice the s)
Group collaboration setup

Exercise 3: Web Server Security

# Simulate web server structure
mkdir -p webapp/{public,private,logs}

# Public files (755 for directories, 644 for files)
echo "<h1>Welcome</h1>" > webapp/public/index.html
chmod 755 webapp/public
chmod 644 webapp/public/index.html

# Private config (600 - only owner)
echo "DB_PASSWORD=secret" > webapp/private/config.env
chmod 600 webapp/private/config.env

# Logs (app can write, others can't read)
touch webapp/logs/app.log
chmod 755 webapp/logs      # Directory: enter but not list
chmod 640 webapp/logs/app.log  # Owner read/write, group read only

# Verify security
ls -lR webapp/
Web server security example

5. Complete Project: Secure File Share System

#!/bin/bash
# secure_share_setup.sh - Set up a secure shared directory structure

echo "Setting up secure file sharing system..."

# Create directory structure
mkdir -p /var/share/{incoming,processing,completed,audit}

# Set ownership
chown -R root:staff /var/share

# Set permissions
# Incoming: Anyone can drop files, but only owners can read back
chmod 1733 /var/share/incoming   # Sticky bit + write for all

# Processing: Staff group can read/write
chmod 2770 /var/share/processing  # SGID + group read/write

# Completed: Staff can read, only admins can write
chmod 2750 /var/share/completed

# Audit: Only root can access
chmod 700 /var/share/audit

# Create test users
echo "Creating test users..."
sudo useradd -m -G staff alice
sudo useradd -m -G staff bob
sudo useradd -m external_user

echo "=== Permission Summary ==="
ls -ld /var/share/*

echo ""
echo "Testing access..."
sudo -u alice touch /var/share/incoming/alice_file.txt
echo "✓ alice can write to incoming"

sudo -u bob touch /var/share/processing/bob_file.txt
echo "✓ bob can write to processing"

sudo -u external_user touch /var/share/incoming/external_file.txt
echo "✓ external can write to incoming"

echo ""
echo "Security check:"
ls -la /var/share/incoming/
echo "Note: Users can't delete others' files (sticky bit)"
Complete secure file sharing system

6. Common Errors & Solutions

7. Summary Checklist

8. Practice Exercise

Challenge: Create a directory where:

  • Files created inside automatically belong to the group 'webadmin'
  • Members of 'webadmin' can edit any file
  • Other users can only read files
  • No one outside the group can access the directory at all

9. Next Steps

Next lesson: Linux Lesson 1.4: Process Management

You'll learn to:

  • View running processes with ps, top, htop
  • Stop processes with kill and signals
  • Run processes in background (&, bg, fg)
  • Monitor system resources

Gataya Med

DevOps Engineer & Backend Developer. Sharing insights on cloud, automation, and scalable systems.

Comments (0)

Sarah Chen January 17, 2025

This is exactly what I needed! The initContainer approach solved our migration issues completely. Thanks for the detailed guide!

Reply

Leave a Comment