In this lesson: Read and set file permissions, and explain why services run as their own user.
On a Linux server every file has an owner, a group, and a set of rules about who may read, write or run it. Most "permission denied" errors, and a good share of security breaches, come down to someone not understanding this page.
Reading the output of ls -l
$ ls -l
-rw-r--r-- 1 eric www-data 1240 Sep 6 09:14 index.html
drwxr-xr-x 2 eric www-data 4096 Sep 6 09:10 uploads
-rwx------ 1 eric eric 220 Sep 6 09:12 deploy.sh
Take the first column apart. -rw-r--r-- is ten characters: one for the type, then three groups of three.
| Part | Means |
|---|---|
- or d | A regular file, or a directory. |
rw- | What the owner may do: read, write, not execute. |
r-- | What members of the group may do: read only. |
r-- | What everyone else may do: read only. |
So index.html is owned by eric, belongs to the group www-data, and can be read by anyone but changed only by Eric. deploy.sh is rwx------: Eric can read, change and run it, and nobody else can even look at it.
The numbers
Each permission has a value: read is 4, write is 2, execute is 1. Add them up per group and you get the three-digit numbers you will see everywhere.
| Number | Letters | Typical use |
|---|---|---|
| 644 | rw-r--r-- | A normal file: owner edits, others read. |
| 755 | rwxr-xr-x | A directory, or a script others may run. |
| 600 | rw------- | A secret: a private key, an .env file. |
| 777 | rwxrwxrwx | Anyone may do anything. Almost always a mistake. |
Changing owner and permissions
chmod 644 index.html # set permissions by number
chmod +x deploy.sh # make a script runnable
chmod -R 755 /var/www/html # apply down a whole directory tree
chown eric index.html # change the owner
chown eric:www-data index.html # change owner and group
chown -R www-data:www-data /var/www # the usual fix for a web directory
Directories are different
On a directory the three letters mean something you would not guess:
- r — you may list what is inside.
- w — you may create and delete entries inside.
- x — you may enter it, and reach things by name.
A directory with r but no x lets you see the names of files you cannot open. One with x but no r lets you open a file if you already know its name, but not browse. And note that deleting a file depends on the permissions of the directory, not the file — which is why you can sometimes delete a file you cannot edit.
root, and why you should not live there
root is the administrator account. It ignores every permission rule on the system. That is occasionally necessary and permanently dangerous: a typo as root is not an error message, it is an outage.
sudo apt update # run one command as root
sudo -u www-data ls /var/www # run one command as a different user
whoami # who am I right now?
Use sudo for the one command that needs it and stay in your own account the rest of the time. Avoid sudo -i, which drops you into a root shell where every subsequent command is unprotected and your history no longer records who did what.
www-data, your database as mysql, your application as its own account. This is not bureaucracy — it is damage control. If an attacker finds a hole in your web application, they get whatever that user can reach. If that user is www-data with access to one directory, you have a problem. If it is root, you have lost the whole machine.
Try it yourself
Create a file, look at its permissions with ls -l, then set it to 600 and try to read it as another user with sudo -u nobody cat. Set it to 644 and try again. You have just proved to yourself what the middle and last groups of letters actually control.