Linux file permissions look intimidating until you understand the three triads. After that, chmod and chown become two of the simplest commands you will ever learn — and two of the most common sources of "why won't this work" outages.
Prerequisites
- Any Linux distro with a shell.
sudofor any system file ownership change.
Step 1: Read a permission line
ls -l /etc/passwd
# -rw-r--r-- 1 root root 2845 May 27 10:30 /etc/passwd
Break it apart:
- rw- r-- r-- 1 root root 2845 May 27 10:30 /etc/passwd
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ └ name
│ │ │ │ │ │ │ │ └ mtime
│ │ │ │ │ │ │ └ bytes
│ │ │ │ │ │ └ group
│ │ │ │ │ └ owner
│ │ │ │ └ link count
│ │ │ └ "others" — everyone else
│ │ └ "group" — anyone in the group
│ └ "owner" — the user listed as owner
└ type — `-` file, `d` dir, `l` symlink, `c` char dev, `b` block dev
Each triad is r w x — read, write, execute. A - means denied.
Step 2: Numeric (octal) mode
Each triad becomes a single digit, sum of:
4= read2= write1= execute
So rwxr-xr-x = 755, rw-r--r-- = 644, rwx------ = 700.
Step 3: chmod
chmod 644 /var/www/html/index.html
chmod 755 /usr/local/bin/myscript
chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
# Recursive
chmod -R 755 /var/www/html
Symbolic mode is often clearer:
chmod u+x deploy.sh # add execute for owner
chmod u-w /etc/critical # remove write for owner
chmod g+w /var/log/myapp # add write for group
chmod o-r /etc/secret # remove read for others
chmod a+r /var/www/public # add read for all (a = ugo)
Step 4: chown and chgrp
chown www-data /var/www/html/index.html
chown www-data:www-data /var/www/html/index.html # owner + group
chown -R www-data:www-data /var/www/html # recursive
chgrp developers /srv/shared
A common production pattern: web files owned by your deploy user, group www-data, group-readable:
chown -R deploy:www-data /var/www/example.sa
find /var/www/example.sa -type d -exec chmod 750 {} \;
find /var/www/example.sa -type f -exec chmod 640 {} \;
chmod -R u+rw,g+r /var/www/example.sa/storage
Step 5: The three special bits
# setuid (4xxx) — execute as the file owner
ls -l /usr/bin/passwd
# -rwsr-xr-x root root ... /usr/bin/passwd
chmod u+s /usr/local/bin/myrestricted
# setgid (2xxx) — execute as group OR (on dirs) new files inherit group
chmod g+s /srv/shared
# sticky (1xxx) — on a dir, only owner can delete their own files
ls -ld /tmp
# drwxrwxrwt ...
chmod +t /shared/upload
setuid on a shell script is ignored by Linux on purpose — wrap in a C binary if you really need it.
Step 6: ACLs for cases octal can't express
When you need "user A read, user B write, group C execute, others nothing":
sudo apt install -y acl # if not already present
setfacl -m u:userA:r-- /srv/file
setfacl -m u:userB:rw- /srv/file
setfacl -m g:groupC:--x /srv/file
getfacl /srv/file
ACLs survive chmod. Use sparingly — ls -l shows a trailing + indicating they exist, but you must getfacl to see them.
Verify
ls -la
stat /etc/passwd # full metadata
namei -l /var/www/html/index.html # walk the path showing perms at each level
namei -l is invaluable when "the file is readable but my web server still 403s" — it shows you the directory along the path that is blocking traversal.
Conclusion
644/755/700 cover 90 percent of cases. chown user:group -R covers most of the rest. The owner-group-others mental model is the only thing you need to remember to navigate a typical Linux box.
Next steps
- Audit who can ssh in with SSH on macOS (same flags on Linux).
- Manage services that need specific file permissions via systemd services.
- Search files by permission with Use grep effectively and
find -perm.
Comments
0 total · 0 threads