Master Linux Permissions: From chmod Basics to Advanced ACL, SELinux & Containers

This comprehensive guide walks you through Linux's multi‑layered permission system—covering basic UGO rwx bits, numeric and symbolic modes, special bits, ACLs, SELinux/AppArmor, capabilities, chattr attributes, and container‑level controls such as SecurityContext and Pod Security Standards—so you can design a robust, least‑privilege security model for servers and cloud workloads.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Master Linux Permissions: From chmod Basics to Advanced ACL, SELinux & Containers

Overview

Mis‑configured permissions can cause services to fail or expose data. Linux’s permission system is the first line of defense, but it extends far beyond the simple rwx and 755 notation. This article walks through every layer—from traditional DAC to ACL, MAC, container security contexts, and file‑system attributes—providing a practical methodology for secure permission management.

1. Permission Model Basics

1.1 UGO Model

Linux defines permissions for three identities (User, Group, Other) and three actions (Read, Write, Execute). Example output of ls -l /etc/nginx/nginx.conf shows -rw-r--r-- where the first three characters are the owner’s rights, the next three the group’s, and the last three others.

$ ls -l /etc/nginx/nginx.conf
-rw-r--r-- 1 root root 2847 Jan 15 10:30 /etc/nginx/nginx.conf

File‑type identifiers (e.g., - for regular file, d for directory) are also shown.

1.2 Numeric and Symbolic Modes

Each permission maps to a value (r=4, w=2, x=1). Three octal digits represent User, Group, Other. Common examples:

chmod 755 script.sh   # rwxr-xr-x
chmod 644 config.yml  # rw-r--r--
chmod 600 id_rsa       # rw-------
chmod 700 .ssh/       # rwx------

Symbolic mode ( chmod u+x file, chmod o-w file) is useful for incremental changes, especially with the X flag that only adds execute to directories or already‑executable files.

1.3 Special Permission Bits

Four‑digit octal values add SUID (4), SGID (2), and Sticky (1). These affect executable files and directories:

SUID : Process runs with file owner’s UID (e.g., /usr/bin/passwd).

SGID : For executables, process runs with file group’s GID; for directories, new files inherit the directory’s group.

Sticky : In directories, only the file owner, directory owner, or root can delete files (e.g., /tmp).

# Set SUID on a binary
chmod 4755 /usr/local/bin/special_tool
# Set SGID on a directory
chmod 2775 /data/team_project
# Set Sticky Bit on a shared upload dir
chmod 1777 /data/shared_upload

2. Access Control Lists (ACL)

POSIX ACLs overcome the UGO limitation by allowing per‑user and per‑group entries. Use getfacl to view and setfacl to modify.

# View ACL
getfacl /data/project/config.yml
# Add user alice read/write
setfacl -m u:alice:rw /data/project/config.yml
# Set default ACL on a directory (inherited by new files)
setfacl -d -m u:alice:rw /data/project/

The ACL mask ( mask::) limits the effective permissions of all non‑owner entries; changing a file’s mode with chmod also changes the mask, which can unintentionally restrict ACL users.

3. Mandatory Access Control (MAC)

3.1 SELinux

Used on RHEL‑based distributions. Each file and process has a security context ( user:role:type:level). Policies enforce which types may access which.

# Show SELinux status
getenforce
# Show file context
ls -Z /var/www/html/index.html
# Change context
chcon -t httpd_sys_content_t /var/www/html/custom_page.html
# Restore default context
restorecon -Rv /var/www/html/

3.2 AppArmor

Used on Ubuntu/Debian. Profiles are path‑based and easier to read.

# Check status
aa-status
# Example profile snippet (usr.sbin.nginx)
/usr/sbin/nginx {
  /etc/nginx/** r,
  /var/www/html/** r,
  /var/log/nginx/** w,
  network inet stream,
}

Both SELinux and AppArmor should remain enabled; use permissive/complain modes for debugging rather than disabling them.

4. Container‑Level Permission Controls

4.1 User Namespace Mapping

Map container root (UID 0) to a non‑root UID on the host to mitigate escape risks.

# Enable user‑ns remap in Docker daemon
dockerd --userns-remap=default

4.2 Kubernetes SecurityContext

Declarative security settings for Pods and containers.

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 2000
    seLinuxOptions:
      level: "s0:c123,c456"
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
        add: ["NET_BIND_SERVICE"]
      volumeMounts:
      - name: tmp
        mountPath: /tmp
      - name: data
        mountPath: /data
  volumes:
  - name: tmp
    emptyDir: {}
  - name: data
    persistentVolumeClaim:
      claimName: app-data

4.3 Pod Security Standards (PSS)

Apply the restricted level via namespace labels to enforce non‑root, dropped capabilities, read‑only root FS, and no privileged containers.

# Label a namespace for restricted policy
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

5. File‑System Attribute Protection

5.1 chattr / lsattr

Immutable ( +i) and append‑only ( +a) attributes protect critical files even from root.

# Make /etc/passwd immutable
chattr +i /etc/passwd
# Make log files append‑only
chattr +a /var/log/auth.log
# Verify attributes
lsattr /etc/passwd

5.2 Production‑grade Script

#!/bin/bash
# Protect critical system files
chattr +i /etc/passwd /etc/shadow /etc/sudoers
# Protect SSH config
chattr +i /etc/ssh/sshd_config
# Make important logs append‑only
chattr +a /var/log/auth.log /var/log/syslog /var/log/kern.log

5.3 Linux Capabilities

Fine‑grained replacement for SUID. Example: allow nginx to bind low ports without root.

# Grant capability to binary
setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx
# Verify
getcap /usr/sbin/nginx

6. Best‑Practice Checklist

Apply the principle of least privilege to users, services, and containers.

Layer defenses: UGO/ACL → SELinux/AppArmor → chattr → capabilities → container SecurityContext → auditd.

Regularly audit world‑writable files, SUID/SGID binaries, and ACL mask settings.

Use auditd to monitor permission changes and privileged command execution.

# Example audit rules
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -a always,exit -F arch=b64 -S chmod,chown -k permission_changes

7. Decision Tree for Permission Issues

1. Can UGO solve it? → chmod/chown
2. Need per‑user/group rules? → ACL (setfacl)
3. Need to restrict root/process? → SELinux/AppArmor + capabilities
4. Need tamper‑proof files? → chattr +i/+a
5. Running in containers? → SecurityContext + PSS + non‑root images

8. References

Linux man pages – chmod(1), acl(5)

SELinux Project Wiki

AppArmor Wiki

Kubernetes Pod Security Standards

Linux Capabilities – capabilities(7)

CIS Benchmarks

DockersecurityACLPermissionsSELinux
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.