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:
Understanding Permission Representation
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.
# 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.
# 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
⚠️ 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.
⚠️ 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.
$ 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
$ 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.
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:
$ 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
Security Best Practices for DevOps
Golden Rules for Permission Management
- Principle of Least Privilege: Give only the permissions absolutely needed, nothing more.
- Avoid 777: Never use chmod 777. Find the minimal permission needed instead.
- Use Groups: Instead of making files world-accessible, use group permissions.
- Regular Audits: Periodically check for world-writable files and incorrect ownership.
- Service Accounts: Run services under dedicated users (nginx, mysql, etc.), not root.
- SUID/SGID Minimization: Remove unnecessary SUID/SGID binaries.
- Sticky Bit on /tmp: Always ensure /tmp has sticky bit (1777 or drwxrwxrwt).
- Secure umask: Use restrictive umask (027 or 077) for production systems.
- Document Permissions: Include permission requirements in deployment documentation.
- Test Changes: Test permission changes in staging before production.
Quick Reference: Permission Cheat Sheet
Common Numeric Permissions
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
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:
- A web application reports "Permission denied" when trying to write to /var/www/uploads. Diagnose and fix.
- Create a shared directory where team members can read/write files but can only delete their own files.
- Find all files in /etc that are world-writable and report them.
- Set up a deployment directory where new files are automatically owned by the "deploy" group.
- A script needs to run as root but should be executable by developers. Set appropriate permissions.
- Configure Nginx log files to be readable by the "adm" group for monitoring.
- 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