Permissions (chmod / chown)
Unix permissions are three triplets (owner, group, other) of read / write / execute. chmod sets them; chown changes ownership. ACLs and capabilities go further when triplets aren’t enough.
chmod, chown, ACLs, special bits
EXAMPLE
# 1) Read the mode ls -l file.txt # -rw-r--r-- 1 ada developers 1234 Jun 8 14:33 file.txt # │└─owner: rw # │ └─group: r # │ └─other: r # └─file type: regular file (d for dir, l for link) stat -c '%A %U %G %s' file.txt # -rw-r--r-- ada developers 1234 # 2) chmod — symbolic chmod u+x script.sh # add execute for user chmod g-w file # remove write for group chmod o= file # clear other entirely chmod ugo+r,o-w file # mix chmod a+x script.sh # all (u+g+o) # 3) chmod — numeric (octal) chmod 644 file # rw-r--r-- chmod 755 dir # rwxr-xr-x chmod 600 secret # rw------- chmod 700 ~/.ssh # rwx------ (ssh refuses otherwise) chmod 644 ~/.ssh/authorized_keys chmod 400 ~/.ssh/id_rsa # private key — read-only owner # 4) Recursive chmod -R 755 public/ chmod -R u+rwX,go+rX,go-w app/ # X = execute only for dirs / already-x files # 5) Ownership chown ada:developers file chown -R www-data:www-data /var/www/ chgrp developers file # group only chown :developers file # group only (alt syntax) # 6) Default modes — umask umask # 022 (typical) # new files start at 0666 - umask = 0644 # new dirs start at 0777 - umask = 0755 umask 027 # tighter — group can read, other nothing # 7) Special bits # setuid (4xxx) — run as the file's owner; classic example: /usr/bin/passwd # setgid (2xxx) — on dirs: new files inherit the directory's group # sticky (1xxx) — on dirs: only the file's owner can delete (think /tmp) ls -ld /tmp # drwxrwxrwt — `t` = sticky chmod 1777 /tmp # sticky chmod 2755 /shared/data # setgid dir chmod g+s /shared/data # same in symbolic # 8) ACLs — when triplets aren't enough getfacl file.txt setfacl -m u:bob:rw file.txt # give bob rw (without changing owner/group) setfacl -m g:dev:rx file.txt setfacl -d -m u:bob:rwx dir/ # default ACL — applies to new files in dir setfacl -x u:bob file.txt # remove bob's entry setfacl -b file.txt # clear all extended ACLs # Filesystems must be mounted with `acl` (usually default on ext4) # 9) Capabilities — fine-grained for binaries (replace setuid) getcap /usr/bin/ping sudo setcap cap_net_raw+ep /usr/local/bin/myping # Lets myping open raw sockets WITHOUT being setuid root. # 10) Common patterns # Web app: # /var/www/app: www-data:www-data 755 # storage/: www-data:www-data 775 (group+w for log writes) # .env: www-data:www-data 600 # SSH: # ~/.ssh: 700 # ~/.ssh/id_rsa: 400 or 600 # ~/.ssh/id_rsa.pub: 644 # ~/.ssh/authorized_keys: 600 # ~/.ssh/known_hosts: 644 # Scripts: # chmod +x deploy.sh # First line: #!/usr/bin/env bash # 11) Find files with bad perms — security audit sudo find / -type f -perm -4000 2>/dev/null # setuid (review!) sudo find / -type f -perm -2 ! -type l 2>/dev/null # world-writable files sudo find /etc -type f \\( -perm -002 -o -perm -020 \\) 2>/dev/null # writable by group/other # 12) Beware # chmod 777 fixes nothing securely — it's the equivalent of disabling security # chown -R * on the wrong directory can take an hour to undo. Always type the path first. # On macOS, use APFS-aware tools; permissions work the same as Linux but extended attrs (xattr) differ
Why it matters
700 on ~/.ssh, 600 on private keys, 644 on public ones — memorise the SSH triplet. chmod 777 is never the right fix.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Exercise
Make a script executable for all.
chmod
script.sh
Two characters.
Discussion
Loading…