The Permission Model
Every file and directory in Linux has an owner (a user), a group, and a set of permissions for three audiences: the owner, the group, and everyone else (other). This is the foundation of Linux security — get it wrong and services break or become exploitable.
$ ls -la /etc/nginx/nginx.conf -rw-r--r-- 1 root root 2.3K Jan 10 nginx.conf │└──┘└──┘└──┘ │owner grp other │ └── file type: - = file, d = directory, l = symlink rw- → owner can read + write (no execute) r-- → group can read only r-- → everyone else can read only Bits: r = 4 w = 2 x = 1 rwx = 4+2+1 = 7 rw- = 4+2+0 = 6 r-- = 4+0+0 = 4
chmod — Change Permissions
# Numeric (octal) — most common for scripts/configs chmod 755 script.sh → rwxr-xr-x (owner: all, group+other: r+x) chmod 644 config.txt → rw-r--r-- (owner: r+w, rest: read only) chmod 600 private.key → rw------- (owner only, no one else) chmod 700 ~/.ssh → rwx------ (owner only, directory) # Symbolic — easier to remember for quick changes chmod +x script.sh → add execute for everyone chmod g+w file.txt → add write for group chmod o-r secret.txt → remove read from others chmod u=rw,go=r file.txt → set precisely # Recursive (directories) chmod -R 755 /var/www/html
chown & chgrp — Change Ownership
Permissions only matter if ownership is right. A web server running aswww-data can't read files owned byroot with 600 permissions — even if you think it should work.
# Change owner chown michael file.txt chown michael:michael file.txt → owner + group # Change group only chgrp docker /var/run/docker.sock # Recursive chown -R www-data:www-data /var/www/html # Common homelab patterns: chown -R root:root /etc/ → configs: root owns chown -R 1000:1000 /opt/appdata/ → container user (UID 1000) chown root:sudo /usr/local/bin/script.sh → group sudo can run
Finding Permission Problems
Permission issues are a common source of service failures. Here's how to investigate efficiently.
# What user is a service running as? ps aux | grep nginx systemctl show nginx -p User # Can this user read the file? sudo -u www-data cat /etc/nginx/ssl/cert.pem # Find files that are world-writable (security risk) find /etc -type f -perm -o=w 2>/dev/null # Find SUID binaries (privilege escalation risk) find / -perm -4000 -type f 2>/dev/null # Check if a path is accessible namei -l /var/log/nginx/access.log → shows perms at each level
Homelab Reference — Common Permission Patterns
Config files: 644 (root:root) — readable, not writable SSL private keys: 600 (root:root) — owner only, no exceptions Scripts: 755 (root:root) — executable by all SSH authorized_keys: 600 (user:user) ~/.ssh directory: 700 (user:user) Service data dirs: 755 owner:group Docker volumes: check container UID matches host ownership Web root: 755 dir, 644 files (www-data:www-data)
≈·*•—[ A|S ]—•*·≈