Lab lesson · free
Linux file permissions: practise chmod & chown
File permissions decide who may do what – and are one of the most common sources of errors on servers. Those who truly understand <code>chmod</code> and <code>chown</code> avoid both „Permission denied“ and dangerously open files. You practise it concretely here.
Read, write, execute
Every file has three permission groups: owner, group, everyone else – each with read (r), write (w) and execute (x). ls -l shows them. Reading that is the first step.
chmod – change permissions
With chmod you set permissions, either symbolically (chmod u+x file) or numerically (chmod 644 file). The numbers look cryptic but follow a simple logic you internalise quickly with examples.
chown – change owner
With chown you transfer a file to another user or group. On servers, the right combination of owner and permissions is often the difference between „works securely“ and „open to everyone“.
Learning to read the three digits
chmod 640 is three groups: owner, group, everyone else. Each digit is the sum of read (4), write (2) and execute (1). So 6 means read and write, 4 read only, 0 nothing at all. Once you grasp the numbers as a sum you never look them up again – and you see immediately that 777 means „everyone may do everything“.
On directories, x means something else
On a file the execute bit allows running it. On a directory it allows entering it and reaching the files inside. A folder with r but without x lets you see the names and nothing more – a distinction often asked in exams and often overlooked in operation.
umask: why new files are never 777
When you create a file it does not get full permissions but whatever the umask leaves over. With the usual 022, files come out as 644 and directories as 755. The mask subtracts, it does not set. If you wonder why a freshly created file is not group-writable, the answer is here and not in chmod.
Special bits: setuid, setgid and the sticky bit
Beyond the three digits there is a fourth. setgid on a directory makes new files inherit the folder's group – the usual move for shared project directories. The sticky bit on /tmp lets everyone write but only the owner delete. setuid on executables is powerful and correspondingly dangerous.
What usually goes wrong
chmod 777 is the most common wrong reflex: it removes every error message and makes the file writable by every user and process on the system. The second mistake is chmod -R across a directory tree, which also makes every text file executable. The third is changing permissions when ownership was the problem – ls -l shows both side by side, and usually a chown is enough.
Groups are the tool for shared work
Assigning permissions per individual user does not scale. The usual route is one group per task: the directory belongs to the group, members are added with usermod -aG group user, and the setgid bit makes new files inherit the group. The -a in usermod matters: without it the command replaces all of the user's existing groups instead of adding one – a typo with unpleasant consequences that only shows at the next login.
Commands to try
Look at permissions and understand them
$ ls -l /etc/shadow$ stat -c '%a %U:%G %n' /etc/shadow$ idstat shows permissions as a number rather than a letter string – handier when you want to set them with chmod right after. id tells you which groups you are in.
Set permissions and ownership
$ sudo chown www-data:www-data /var/www/app$ sudo chmod 750 /var/www/app$ sudo chmod 640 /var/www/app/config.envThe directory belongs to the service, not to your user. 750 lets the group look inside and nobody else; the config file holding credentials gets no execute bit.
Recursive, but separately for files and folders
$ find /var/www/app -type d -exec chmod 750 {} +$ find /var/www/app -type f -exec chmod 640 {} +chmod -R 750 would give every file the execute bit too. Splitting by type is why these two lines appear in almost every hardening procedure.
Inspect umask and special bits
$ umask$ touch new.txt && ls -l new.txt$ ls -ld /tmp$ sudo chmod g+s /srv/projectThe t in drwxrwxrwt on /tmp is the sticky bit, the s after chmod g+s is setgid – both sit where x would otherwise be.
Common error messages
- -bash: ./start.sh: Permission denied
- Cause: The file lacks the execute bit, or it sits in a directory without
x. - Fix:
chmod +x start.shand check withls -ld .whether the directory itself can be entered. - chown: changing ownership of 'file': Operation not permitted
- Cause: Only
rootmay change a file's owner – even when the file belongs to you. - Fix: Use
sudo chown …. You may change the group withoutsudoas long as you are a member of the target group. - Permissions 0644 for 'id_ed25519' are too open.
- Cause: SSH refuses to use a private key that others may read – on a shared system the file would be compromised.
- Fix:
chmod 600 ~/.ssh/id_ed25519. The private key belongs to nobody but you. - cp: cannot create regular file 'target/file': Permission denied
- Cause: The file is not the problem, the TARGET DIRECTORY is: creating there needs both write AND execute permission.
- Fix: Inspect the folder with
ls -ld target– not the file you want to copy.
In five steps
- 01Read the current state of a file with
ls -landstat -c '%a %U:%G %n'. - 02Use
idto establish which user and group you actually are. - 03Set ownership before permissions –
chownbeforechmod, or you do the work twice. - 04Set directories to
750and files to640; separately viafind … -type dand-type f. - 05Verify from another user's view:
sudo -u www-data cat filemust succeed or fail exactly as intended.
What you practise
Get in Touch
Have a project?
Let's bring your idea to life together. We're happy to advise you with no obligation.
Get in Touch →