Master Linux file permissions for secure DevOps operations. This comprehensive guide covers basic rwx permissions, special bits, ACLs, and security best practices for containers, automation, and multi-user environments.
Permission Bits Visualization
Permission Tools Comparison
| Tool | Purpose | Common Usage | Security Level |
|---|---|---|---|
| chmod | Change file permissions | chmod 755 script.sh |
MEDIUM |
| chown | Change file ownership | chown user:group file |
HIGH |
| setfacl | Access Control Lists | setfacl -m u:john:rw file |
HIGH |
| umask | Default permissions | umask 0022 |
MEDIUM |
| getfacl | View ACLs | getfacl /secure/path |
LOW |
• Check permissions:
ls -l or stat file• Change permissions:
chmod 755 script.sh• Change owner:
chown user:group file• Recursive change:
chmod -R 755 /path• Set SUID:
chmod u+s file• Set SGID:
chmod g+s directory• Sticky bit:
chmod +t /tmp• ACL:
setfacl -m u:user:rw file• Always use least privilege principle
Permission Number System
| Number | Permission | Binary | Description |
|---|---|---|---|
| 0 | --- |
000 | No permissions |
| 1 | --x |
001 | Execute only |
| 2 | -w- |
010 | Write only |
| 3 | -wx |
011 | Write + Execute |
| 4 | r-- |
100 | Read only |
| 5 | r-x |
101 | Read + Execute |
| 6 | rw- |
110 | Read + Write |
| 7 | rwx |
111 | All permissions |
Essential Permission Commands
Manage file and directory permissions with chmod and chown.
# View permissions
ls -l file.txt
stat file.txt
# Symbolic permissions
chmod u+rwx file.txt # User add rwx
chmod g-w file.txt # Group remove w
chmod o=r file.txt # Other set to r only
chmod a+x script.sh # All add execute
# Octal permissions
chmod 755 script.sh # rwxr-xr-x
chmod 644 file.txt # rw-r--r--
chmod 750 directory/ # rwxr-x---
# Change ownership
chown user file.txt
chown user:group file.txt
chown :group file.txt
# Recursive changes
chmod -R 755 /app/
chown -R user:group /data/
# Reference permissions
chmod --reference=source.txt target.txt
chown --reference=source.txt target.txt
# Special directory permissions
chmod 1777 /tmp/ # Sticky bit
chmod 2750 /shared/ # SGID bit
Use SUID, SGID, and sticky bits for advanced scenarios.
# Set SUID (Set User ID)
chmod u+s /usr/bin/passwd
# File executes with owner's privileges
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root
# Set SGID (Set Group ID)
chmod g+s /shared/directory/
# Files inherit directory's group
ls -ld /shared/directory/
# drwxr-sr-x 2 root developers
# Sticky bit on directories
chmod +t /tmp/
# Only owners can delete their files
ls -ld /tmp/
# drwxrwxrwt 14 root root
# Octal notation for special bits
chmod 4755 file # SUID set
chmod 2755 directory # SGID set
chmod 1755 directory # Sticky bit set
# Combined special bits
chmod 6755 file # SUID + SGID
# Find files with SUID/SGID
find / -type f -perm /6000 2>/dev/null
# Security check for SUID binaries
find / -type f -perm /4000 -user root 2>/dev/null
# Remove special bits
chmod u-s file
chmod g-s directory
chmod -t /tmp/
Control default file creation permissions with umask.
# Check current umask
umask
umask -S
# Set umask for session
umask 0022
umask 0002
# Permanent umask settings
# Add to ~/.bashrc or /etc/profile
umask 0022
# How umask works:
# Default file: 666 - umask
# Default directory: 777 - umask
# Examples:
umask 022 = files: 644, directories: 755
umask 002 = files: 664, directories: 775
umask 077 = files: 600, directories: 700
# Set different umask for specific users
# In /etc/bash.bashrc or user's .bashrc
if [ "$(id -u)" -eq 0 ]; then
umask 0022 # root user
else
umask 0002 # regular users
fi
# Docker container umask
docker run -it --umask 0022 ubuntu
# Systemd service umask
[Service]
UMask=0022
ExecStart=/usr/bin/myapp
# Secure umask for production
# /etc/profile
umask 0027 # files: 640, directories: 750
Advanced Permission Concepts
| Permission Type | Use Case | Security Impact | DevOps Recommendation |
|---|---|---|---|
| SUID | Privileged executables | High risk if misconfigured | Minimize use, audit regularly |
| SGID | Shared group directories | Medium risk | Use for collaboration spaces |
| Sticky Bit | World-writable directories | Low risk | Essential for /tmp, /var/tmp |
| ACLs | Complex permission needs | Medium risk | Use instead of permissive modes |
| Umask | Default file creation | Fundamental security | Set restrictive defaults |
Advanced Permission Features
Fine-grained permission control beyond basic rwx.
# Install ACL tools
sudo apt install acl
# View ACLs
getfacl file.txt
getfacl -R /directory/
# Set user ACL
setfacl -m u:john:rw file.txt
setfacl -m u:jane:rx script.sh
# Set group ACL
setfacl -m g:developers:rwx /project/
# Set mask (maximum allowed permissions)
setfacl -m m::r file.txt
# Remove specific ACL
setfacl -x u:john file.txt
# Set default ACLs (inheritance)
setfacl -d -m u:john:rw /shared/
setfacl -d -m g:team:rx /shared/
# Recursive ACL setting
setfacl -R -m u:admin:rwx /data/
# Backup and restore ACLs
getfacl -R /important/ > acl_backup.txt
setfacl --restore=acl_backup.txt
# Clear all ACLs
setfacl -b file.txt
# Useful ACL patterns:
# Web server directory
setfacl -R -m u:www-data:rwX,g:developers:rwX /var/www/
setfacl -d -R -m u:www-data:rwX,g:developers:rwX /var/www/
Secure permission practices for production systems.
# Find world-writable files
find / -type f -perm -0002 ! -path "/proc/*" 2>/dev/null
# Find SUID/SGID files
find / -type f -perm /6000 2>/dev/null
# Find files owned by specific user
find / -user www-data -type f 2>/dev/null
# Find files with no owner
find / -nouser -o -nogroup 2>/dev/null
# Secure sensitive directories
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_rsa
# Container security checks
docker exec container find / -perm /6000
docker exec container find / -type f -perm -0002
# Kubernetes security context
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
# Automated permission auditing
#!/bin/bash
AUDIT_DIR="/etc/audit"
mkdir -p $AUDIT_DIR
# Check SUID binaries
find / -type f -perm /4000 > $AUDIT_DIR/suid-files.txt
# Check world-writable
find / -type f -perm -0002 > $AUDIT_DIR/world-writable.txt
# Check sensitive file permissions
ls -l /etc/passwd /etc/shadow /etc/sudoers > $AUDIT_DIR/critical-files.txt
Permission management in modern infrastructure.
# Docker container permissions
docker run -it --user 1000:1000 ubuntu
docker run -it --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# Dockerfile permission best practices
FROM ubuntu:20.04
RUN groupadd -r app && useradd -r -g app app
USER app
WORKDIR /home/app
COPY --chown=app:app . .
# Kubernetes security context
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
securityContext:
capabilities:
drop:
- ALL
# Ansible permission management
- name: Set secure permissions
file:
path: /etc/app
owner: root
group: root
mode: '0644'
state: directory
- name: Recursive permission fix
file:
path: "{{ item }}"
mode: '0755'
recurse: yes
loop:
- /var/www
- /opt/app
# Terraform file provisioner
resource "null_resource" "permissions" {
provisioner "file" {
source = "scripts/"
destination = "/opt/app/"
connection {
type = "ssh"
user = "ubuntu"
}
}
provisioner "remote-exec" {
inline = [
"chmod -R 755 /opt/app/",
"chown -R app:app /opt/app/"
]
}
}
Practical DevOps Scenarios
Real-World Permission Management Scripts
# 1. Automated Permission Audit
#!/bin/bash
AUDIT_DIR="/var/log/permission-audit"
mkdir -p $AUDIT_DIR
echo "=== Permission Audit $(date) ===" > $AUDIT_DIR/audit.log
# SUID/SGID files
echo "SUID/SGID Files:" >> $AUDIT_DIR/audit.log
find / -type f -perm /6000 2>/dev/null >> $AUDIT_DIR/audit.log
# World-writable files
echo -e "\nWorld-writable Files:" >> $AUDIT_DIR/audit.log
find / -type f -perm -0002 ! -path "/proc/*" 2>/dev/null >> $AUDIT_DIR/audit.log
# Sensitive file permissions
echo -e "\nCritical File Permissions:" >> $AUDIT_DIR/audit.log
ls -l /etc/passwd /etc/shadow /etc/sudoers >> $AUDIT_DIR/audit.log
echo "Audit complete: $AUDIT_DIR/audit.log"
# 2. Web Application Permission Setup
#!/bin/bash
WEB_DIR="/var/www/html"
WEB_USER="www-data"
WEB_GROUP="developers"
echo "Setting up web permissions..."
# Set ownership
chown -R $WEB_USER:$WEB_GROUP $WEB_DIR
# Set directory permissions
find $WEB_DIR -type d -exec chmod 2750 {} \;
# Set file permissions
find $WEB_DIR -type f -exec chmod 640 {} \;
# Set executable permissions for scripts
find $WEB_DIR -name "*.php" -exec chmod 750 {} \;
find $WEB_DIR -name "*.sh" -exec chmod 750 {} \;
# Set upload directory permissions
chmod 2770 $WEB_DIR/uploads
chown $WEB_USER:$WEB_GROUP $WEB_DIR/uploads
echo "Web permissions configured"
# 3. Container Security Hardening
#!/bin/bash
CONTAINER_NAME="myapp"
# Drop all capabilities, add only needed
docker run -d \
--name $CONTAINER_NAME \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--user 1000:1000 \
--read-only \
--tmpfs /tmp \
nginx:alpine
# Set tmpfs permissions
docker exec $CONTAINER_NAME chmod 1777 /tmp
# Verify security
docker exec $CONTAINER_NAME whoami
docker exec $CONTAINER_NAME find / -perm /6000
# 4. Multi-User Collaboration Setup
#!/bin/bash
SHARED_DIR="/shared/project"
GROUP_NAME="project-team"
# Create shared directory
mkdir -p $SHARED_DIR
chown root:$GROUP_NAME $SHARED_DIR
chmod 2770 $SHARED_DIR
# Set ACLs for specific users
setfacl -d -m g:$GROUP_NAME:rwx $SHARED_DIR
setfacl -d -m u:manager:rwx $SHARED_DIR
setfacl -m g:$GROUP_NAME:rwx $SHARED_DIR
setfacl -m u:manager:rwx $SHARED_DIR
echo "Shared directory $SHARED_DIR configured for $GROUP_NAME"
# 5. Permission Compliance Checker
#!/bin/bash
COMPLIANCE_RULES=(
"/etc/passwd:644"
"/etc/shadow:600"
"/etc/sudoers:440"
"$HOME/.ssh:700"
"$HOME/.ssh/authorized_keys:600"
)
echo "Permission Compliance Check:"
for rule in "${COMPLIANCE_RULES[@]}"; do
file="${rule%:*}"
expected="${rule#*:}"
if [ -e "$file" ]; then
actual=$(stat -c "%a" "$file" 2>/dev/null)
if [ "$actual" != "$expected" ]; then
echo "NON-COMPLIANT: $file (expected: $expected, actual: $actual)"
else
echo "COMPLIANT: $file"
fi
fi
done
# 6. Emergency Permission Reset
#!/bin/bash
# Use with caution - resets permissions to safe defaults
echo "Resetting critical permissions..."
chmod 644 /etc/passwd
chmod 600 /etc/shadow
chmod 440 /etc/sudoers
chmod 755 /etc/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Reset web directories
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
echo "Emergency permission reset complete"
Troubleshooting Permission Issues
Common Problems
- Permission Denied: Check file ownership, group membership, and ACLs
- Operation Not Permitted: Verify SELinux/AppArmor, capabilities, and namespace restrictions
- Cannot Delete File: Check directory write permissions and sticky bit settings
Container Issues
- Volume Mount Problems: Match container UID/GID with host file ownership
- Read-only Filesystem: Check container security context and mount options
- Privilege Escalation: Verify --cap-drop settings and runAsNonRoot
Security Issues
- SUID Abuse: Audit SUID binaries regularly, use capabilities instead
- World-writable Files: Identify and secure unnecessarily permissive files
- ACL Complexity: Document complex ACL setups for maintainability
• Follow principle of least privilege for all permissions
• Regularly audit SUID/SGID binaries and world-writable files
• Use ACLs instead of overly permissive basic permissions
• Set restrictive umask values (0027 or 0077)
• Implement security contexts in containers and Kubernetes
• Document permission requirements for applications
• Test permission changes in staging before production
• Monitor for permission changes in critical files
• Use
find -perm for precise permission searches• Combine ACLs with basic permissions for complex scenarios
• Use
getcap/setcap instead of SUID when possible• Implement filesystem monitoring for permission changes
• Use containers with non-root users by default
• Regular permission audits as part of security scanning
• Automate permission compliance checking
Key DevOps Takeaways
Mastering Linux file permissions is crucial for secure and reliable DevOps operations. By understanding basic permissions, special bits, ACLs, and modern container security contexts, you can implement robust access control across your infrastructure. Remember that permissions are a fundamental security layer that should be carefully designed, regularly audited, and properly documented.
Next Step: Explore advanced security topics like SELinux/AppArmor, filesystem capabilities, container security benchmarks, and automated security compliance scanning.