Saturday, December 13, 2025

Linux File Permissions & Ownership

Linux File Permissions & Ownership - DevOps Security Essentials

Linux File Permissions & Ownership

Published: December 2025 | Topic: Security & Access Control for DevOps

Understanding Linux permissions is crucial for security and troubleshooting. Incorrect permissions can lead to security breaches, application failures, and data loss. As a DevOps engineer, you need to master permission management for web servers, databases, and application deployments.

Why Permissions Matter in DevOps

In DevOps environments, proper permission management ensures:

  • Security: Prevent unauthorized access to sensitive data and configuration files
  • Application Functionality: Web servers and applications need correct permissions to read/write files
  • Compliance: Meet security standards and audit requirements
  • Troubleshooting: Resolve "Permission denied" errors quickly
  • Multi-user Environments: Control access in shared development and production systems

⚠️ Common Permission Mistakes in DevOps

  • 777 Permissions: Giving everyone full access (read, write, execute) is a major security risk
  • Running as root: Applications running with root privileges can compromise the entire system
  • World-writable directories: Allow anyone to modify or delete critical files
  • Incorrect ownership: Web server can't access files if ownership is wrong
  • Sticky bit missing: In shared directories like /tmp, users can delete each other's files

The Three Pillars of Linux Permissions

1. Users, Groups, and Others

Linux categorizes access for three types of entities:

User (Owner)

The user who owns the file. Typically the creator, but ownership can be changed.

# View file owner
$ ls -l script.sh
-rwxr-xr-- 1 alice developers 2048 Dec 1 10:00 script.sh
# ↑ Owner is 'alice'

Group

A collection of users. Files belong to a group, and all group members share the group permissions.

# View group owner
$ ls -l script.sh
-rwxr-xr-- 1 alice developers 2048 Dec 1 10:00 script.sh
# ↑ Group is 'developers'

Others (World)

Everyone else who is not the owner and not in the group. Public access permissions.

$ ls -l public.txt
-rw-r--r-- 1 alice developers 1024 Dec 1 10:00 public.txt
# Others can read (r-- at the end)

2. Permission Types: Read, Write, Execute

Each entity (user, group, others) can have three types of permissions:

For Files

Read (r)

Can view file contents

$ cat file.txt
$ less file.txt

Write (w)

Can modify file contents

$ echo "text" >> file.txt
$ vim file.txt

Execute (x)

Can run file as program/script

$ ./script.sh
$ python app.py

For Directories

Read (r)

Can list directory contents

$ ls /directory
$ ls -la /directory

Write (w)

Can create/delete files in directory

$ touch /dir/newfile
$ rm /dir/file

Execute (x)

Can access (cd into) directory

$ cd /directory
$ ls /directory/file.txt

⚠️ Critical Difference: Directory Execute Permission

For directories, execute permission (x) is needed to access the directory, even if you have read permission. Without execute permission on a directory:

  • You cannot cd into it
  • You cannot access files inside, even if you know their exact names
  • ls will fail with "Permission denied"

This is a common source of confusion and troubleshooting issues.

Understanding Permission Representation

Breaking Down the Permission String

$ ls -l script.sh
-rwxr-xr-- 1 alice developers 2048 Dec 1 10:00 script.sh
# │└─ Permissions (10 characters)
# └── File type (- = regular file)

The 10-character permission string breaks down as follows:

-
r
w
x
r
-
x
r
-
-
Position Character Meaning Examples
1 - File type - (file), d (directory), l (link)
2-4 rwx User (owner) permissions rwx, rw-, r-x, r--, ---
5-7 r-x Group permissions rwx, rw-, r-x, r--, ---
8-10 r-- Others (world) permissions rwx, rw-, r-x, r--, ---

Common Permission Patterns in DevOps

# Web server files (nginx/apache)
$ ls -l /var/www/html/index.html
-rw-r--r-- 1 www-data www-data 5120 Dec 1 10:00 index.html

# Configuration files (readable by all, writable only by owner)
$ ls -l /etc/nginx/nginx.conf
-rw-r--r-- 1 root root 24576 Dec 1 10:00 nginx.conf

# Executable scripts
$ ls -l /usr/local/bin/deploy.sh
-rwxr-xr-x 1 root root 2048 Dec 1 10:00 deploy.sh

# Log files (append-only for services)
$ ls -l /var/log/nginx/access.log
-rw-r----- 1 www-data adm 10485760 Dec 1 10:00 access.log

Changing Permissions: chmod Command

Two Notation Systems: Symbolic vs Numeric

Symbolic Notation (Easy to Read)

Uses letters to specify who and what permissions to change.

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

$ chmod u+x script.sh
# Add execute for user
$ chmod go-w file.txt
# Remove write for group and others
$ chmod a=rx directory
# Set read+execute for everyone
$ chmod g=u file.txt
# Make group permissions same as user

Numeric (Octal) Notation (More Precise)

Uses numbers 0-7 to represent permission sets.

# Each digit: user(4) + group(2) + others(1)
# r=4, w=2, x=1 (sum for each category)

$ chmod 755 script.sh
# 7=4+2+1=rwx, 5=4+0+1=r-x, 5=r-x
# user: rwx, group: r-x, others: r-x

$ chmod 644 config.conf
# 6=4+2+0=rw-, 4=4+0+0=r--
# user: rw-, group: r--, others: r--

$ chmod 700 secret.txt
# user: rwx, group: ---, others: ---
# Only owner can read, write, execute

Common Numeric Permissions in DevOps

Permission Numeric Symbolic Use Case
Read-only for all 444 r--r--r-- Static configuration files
User full, others read 744 rwxr--r-- Executables with read access
User full, group read/exec 750 rwxr-x--- Scripts for team sharing
User read/write, group read 640 rw-r----- Log files, sensitive configs
User full, group write, others none 730 rwx-wx--- Shared development directory
DANGER: Full access 777 rwxrwxrwx Avoid! Security risk

Changing Ownership: chown and chgrp

Managing File Owners and Groups

chown - Change Owner

Change both user and group ownership.

# Syntax: chown [user]:[group] file
$ chown alice:developers script.sh
# Change owner to alice, group to developers
$ chown www-data /var/www/html
# Change owner only (keep group)
$ chown :nginx /etc/nginx/nginx.conf
# Change group only (keep owner)
$ chown -R www-data:www-data /var/www
# -R: recursive (all files/directories)

chgrp - Change Group

Change only the group ownership.

$ chgrp developers script.sh
# Change group to developers
$ chgrp -R www-data /var/www/html
# Recursive group change
$ chgrp adm /var/log/auth.log
# Common: log files owned by adm group

Finding User/Group Info

Commands to check user and group information.

$ id
# Show current user's uid, gid, groups
$ groups username
# List groups a user belongs to
$ getent group groupname
# Show group information
$ whoami
# Show current username

⚠️ Only root can change ownership

Regular users cannot change file ownership to another user. Only root can use chown to change a file's owner to someone else. This prevents users from giving away files to avoid disk quotas or hide ownership.

However, users can change group ownership to any group they belong to using chgrp.

Special Permission Modes

Beyond Basic Permissions: SUID, SGID, and Sticky Bit

These special modes provide additional security and functionality features.

SUID (Set User ID)

File executes with owner's privileges, not executor's.

# Shows as 's' in user execute position
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 63960 Feb 7 2020 /usr/bin/passwd
# ↑ 's' instead of 'x'

$ chmod u+s file
# Set SUID bit (symbolic)
$ chmod 4755 file
# Set SUID bit (numeric: 4xxx)

Use Case: /usr/bin/passwd needs root access to modify /etc/shadow

SGID (Set Group ID)

For files: execute with group's privileges.
For directories: new files inherit directory's group.

$ ls -ld /var/www/html
drwxr-sr-x 2 www-data www-data 4096 Dec 1 10:00 /var/www/html
# ↑ 's' in group execute position

$ chmod g+s directory
# Set SGID on directory
$ chmod 2755 directory
# Set SGID bit (numeric: 2xxx)

DevOps Use: Shared directories where all files should belong to same group

Sticky Bit

On directories: only file owner can delete/rename their files.

$ ls -ld /tmp
drwxrwxrwt 14 root root 4096 Dec 1 10:00 /tmp
# ↑ 't' in others execute position

$ chmod +t directory
# Set sticky bit
$ chmod 1777 directory
# Set sticky bit (numeric: 1xxx)

Use Case: /tmp directory - users can create files but only delete their own

⚠️ Security Considerations with Special Bits

  • SUID risks: SUID root programs are prime targets for privilege escalation attacks
  • SUID best practice: Minimize SUID binaries, especially with root privileges
  • Find SUID/SGID files: find / -type f -perm /6000 2>/dev/null
  • Sticky bit necessity: Always set on world-writable directories like /tmp

Default Permissions: Understanding umask

Controlling Default File and Directory Permissions

The umask (user mask) determines default permissions for newly created files and directories.

# Check current umask
$ umask
0022

# How umask works:
# Default file permissions: 666 (rw-rw-rw-)
# Default directory permissions: 777 (rwxrwxrwx)
# umask 022 subtracts: 666 - 022 = 644 (rw-r--r--)
# 777 - 022 = 755 (rwxr-xr-x)
umask File Permission Directory Permission Use Case
0000 666 (rw-rw-rw-) 777 (rwxrwxrwx) Shared development (insecure!)
0022 644 (rw-r--r--) 755 (rwxr-xr-x) Default for most systems
0027 640 (rw-r-----) 750 (rwxr-x---) More restrictive
0077 600 (rw-------) 700 (rwx------) Private files only

Setting umask for Different Scenarios

# Set umask for current session
$ umask 027

# Set in shell profile (e.g., ~/.bashrc)
$ echo "umask 027" >> ~/.bashrc

# For system services, set in service file
# In /etc/systemd/system/myservice.service:
[Service]
UMask=0027

# Check umask for another user's process
$ grep -i umask /proc/$(pgrep nginx)/status

Advanced: Access Control Lists (ACLs)

Granular Permissions Beyond Standard Model

ACLs allow setting permissions for specific users and groups beyond the standard user/group/others model.

Viewing ACLs

Check if a file has extended ACL permissions.

$ getfacl file.txt
# file: file.txt
# owner: alice
# group: developers
user::rw-
user:bob:r--
group::r--
group:contractors:r--
mask::r--
other::---

Setting ACLs

Add specific permissions for users or groups.

$ setfacl -m u:bob:r-x file.txt
# Give bob read+execute
$ setfacl -m g:contractors:rw- directory/
# Give contractors group read+write
$ setfacl -x u:bob file.txt
# Remove bob's ACL entry
$ setfacl -b file.txt
# Remove all ACL entries

Default ACLs

Set default ACLs on directories for new files.

$ setfacl -d -m u:bob:rwx shared_dir/
# Default ACL: bob gets rwx on new files
$ setfacl -k directory
# Remove all default ACL entries

When to Use ACLs in DevOps

  • Web servers needing access from multiple service accounts
  • Shared development environments with complex access needs
  • Granting temporary access without changing group membership
  • Compliance requirements needing detailed access logs

Note: Not all filesystems support ACLs. Check with mount | grep acl

Practical DevOps Scenarios

Web Server Configuration (Nginx/Apache)

Proper permissions are critical for web server security and functionality:

# Typical web server directory structure
$ ls -la /var/www/
drwxr-xr-x 4 root root 4096 Dec 1 10:00 .
drwxr-xr-x 14 root root 4096 Dec 1 10:00 ..
drwxr-xr-x 2 www-data www-data 4096 Dec 1 10:00 html
drwxrwx--- 2 www-data developers 4096 Dec 1 10:00 uploads

# Set correct permissions for web content
$ chown -R www-data:www-data /var/www/html
$ chmod -R 755 /var/www/html
# For upload directories with write access
$ chmod 775 /var/www/uploads
$ chown www-data:developers /var/www/uploads

# Log files - readable by admin group
$ chown www-data:adm /var/log/nginx/*.log
$ chmod 640 /var/log/nginx/*.log

Application Deployment Permissions

Common patterns for different application components:

Component Recommended Permission Owner:Group Reason
Source Code 644 (rw-r--r--) deploy:developers Readable by all, writable by deploy user
Configuration Files 640 (rw-r-----) deploy:developers Sensitive data, group readable
Upload Directory 775 (rwxrwxr-x) app:app Web server needs write access
Log Files 664 (rw-rw-r--) app:developers App writes, developers can read
Executable Scripts 750 (rwxr-x---) deploy:developers Team can run, others cannot
Database Credentials 600 (rw-------) app:app Extremely sensitive

Troubleshooting Permission Issues

Diagnosing and Fixing Common Problems

"Permission Denied" Errors

Systematic approach to diagnose:

# 1. Check file permissions
$ ls -l file.txt

# 2. Check directory permissions (for cd/ls)
$ ls -ld /path/to/

# 3. Check user and group membership
$ id
$ groups

# 4. Check for ACLs
$ getfacl file.txt

Useful Diagnostic Commands

Tools to investigate permission issues:

$ namei -l /path/to/file
# Show permissions of each path component

$ strace -e trace=file command 2>&1 | grep EACCES
# Trace system calls for permission errors

$ find /path -type f -perm /o+w
# Find world-writable files

$ find /path -type f -perm -4000
# Find SUID files

Common Fixes

Quick solutions for common scenarios:

# Web server can't read files
$ chown -R www-data:www-data /var/www
$ chmod -R 755 /var/www

# Script won't execute
$ chmod +x script.sh

# Can't delete file in shared directory
$ chmod +t /shared/dir
# Add sticky bit

Security Best Practices for DevOps

Golden Rules for Permission Management

  1. Principle of Least Privilege: Give only the permissions absolutely needed, nothing more.
  2. Avoid 777: Never use chmod 777. Find the minimal permission needed instead.
  3. Use Groups: Instead of making files world-accessible, use group permissions.
  4. Regular Audits: Periodically check for world-writable files and incorrect ownership.
  5. Service Accounts: Run services under dedicated users (nginx, mysql, etc.), not root.
  6. SUID/SGID Minimization: Remove unnecessary SUID/SGID binaries.
  7. Sticky Bit on /tmp: Always ensure /tmp has sticky bit (1777 or drwxrwxrwt).
  8. Secure umask: Use restrictive umask (027 or 077) for production systems.
  9. Document Permissions: Include permission requirements in deployment documentation.
  10. Test Changes: Test permission changes in staging before production.

Quick Reference: Permission Cheat Sheet

Common Numeric Permissions

777 - rwxrwxrwx (DANGER: full access)
755 - rwxr-xr-x (dirs, executables)
750 - rwxr-x--- (team executables)
644 - rw-r--r-- (files, configs)
640 - rw-r----- (sensitive configs)
600 - rw------- (private files)
400 - r-------- (read-only)

Essential Commands

ls -l # View permissions
chmod 755 file # Change permissions
chown user:group file
chgrp group file
umask # Show default mask
getfacl file # View ACLs
setfacl -m u:user:perms file

Practice Exercises

Test your understanding with these real-world scenarios:

  1. A web application reports "Permission denied" when trying to write to /var/www/uploads. Diagnose and fix.
  2. Create a shared directory where team members can read/write files but can only delete their own files.
  3. Find all files in /etc that are world-writable and report them.
  4. Set up a deployment directory where new files are automatically owned by the "deploy" group.
  5. A script needs to run as root but should be executable by developers. Set appropriate permissions.
  6. Configure Nginx log files to be readable by the "adm" group for monitoring.
  7. Create a secure umask for a production server that creates private files by default.

Key Takeaways for DevOps Engineers

  • Permissions are security: Incorrect permissions are common attack vectors.
  • Understand the difference between file and directory execute permissions.
  • Use numeric permissions for precision in scripts and automation.
  • Default to restrictive permissions and add access as needed (not the reverse).
  • Regular audits catch permission drift and security issues.
  • Document expected permissions as part of your infrastructure as code.
  • Test permission changes thoroughly - they can break applications.

Mastering Linux permissions takes practice, but it's fundamental to building secure, reliable systems. Start with the basics, understand the principles, and build up to advanced concepts like ACLs as needed.

No comments:

Post a Comment

Linux Security & Permissions for DevOps

Linux Security & Permissions - DevOps Security Guide Linux Security & Permissions ...