Linux File Permissions Explained: chmod, chown and umask
Linux permission errors (Permission denied) all come back to three things: who owns the file, which group it belongs to, and which bits are set. Once you can read ls -l, you can fix almost anything.
Reading ls -l
ls -l
-rwxr-xr-- 1 alice developers 4096 Oct 16 12:00 deploy.sh
Break the first column into four parts:
- rwx r-x r--
β β β βββ others (everyone else)
β β ββββββββ group (developers)
β βββββββββββββ owner (alice)
βββββββββββββββββ type: - file, d directory, l symlink
Each triplet is read, write, execute. For a directory, x means "can enter it" and r means "can list it". You need x on every directory along a path to reach a file inside.
Numeric (octal) notation
Each permission has a value: r = 4, w = 2, x = 1. Add them per class.
| Number | Bits | Meaning |
|---|---|---|
7 |
rwx |
read, write, execute |
6 |
rw- |
read, write |
5 |
r-x |
read, execute |
4 |
r-- |
read only |
0 |
--- |
nothing |
So chmod 754 deploy.sh = owner rwx, group r-x, others r--.
chmod
chmod 644 file.txt # owner rw, everyone else read
chmod 755 script.sh # owner rwx, everyone else r-x
chmod 600 ~/.ssh/id_ed25519 # private: owner only
chmod +x script.sh # make executable
chmod g+w shared.txt # add write for the group
chmod o-rwx secret.txt # remove everything for others
chmod -R u=rwX,g=rX,o= dir/ # recursive, X sets execute only on dirs
Symbolic form: u user/owner, g group, o others, a all, with +, - or =.
chown and chgrp
sudo chown alice file.txt # change owner
sudo chown alice:developers file.txt # owner and group
sudo chown -R www-data: /var/www/site # recursive, group = user's login group
sudo chgrp developers file.txt # group only
Only root can change a file's owner.
Typical values to remember
| What | Mode |
|---|---|
| Regular files (web content, configs) | 644 |
| Directories | 755 |
| Scripts / binaries | 755 |
SSH private key, authorized_keys |
600 |
~/.ssh directory |
700 |
| Secrets/config with passwords | 640 (owner + a group) or 600 |
For web servers, a safe pattern is owner root, group www-data, with chmod -R g+rX,o-rwx so the server can read but not write, and the world can't read at all.
Don't
chmod 777. It lets any user or process on the machine modify the file. If something only works with 777, the owner or group is wrong; fix that instead.
Special bits
| Bit | Number | On a directory it means |
|---|---|---|
| setgid | 2 |
New files inherit the directory's group, good for shared folders |
| sticky | 1 |
Only the owner can delete their files, as in /tmp |
| setuid | 4 |
(on a file) runs as the file's owner. Be careful |
sudo chmod 2775 /srv/shared # setgid + rwxrwxr-x
sudo chmod 1777 /srv/dropbox # sticky, like /tmp
umask: the default for new files
umask # 0022 on most systems
New files start at 666 - umask and new directories at 777 - umask. With 0022 you get 644 and 755. With 0077 only the owner has any access.
Debugging "Permission denied"
namei -l /var/www/site/public/index.php # shows permissions of EVERY directory in the path
id # your user and groups
ls -ld /path/to/dir # permissions of the directory itself
namei -l is the single most useful command here. The culprit is often a parent directory missing the x bit. Also remember: after sudo usermod -aG group user, you must log out and in again for the new group to apply.
On systems with SELinux (RHEL, Rocky) or AppArmor (Ubuntu), a denial can come from the security module even when the normal permissions are right. Check sudo ausearch -m avc -ts recent or journalctl -k | grep -i apparmor.