File Permissions
Understand and control who can read, write, and execute files with chmod and chown
Knowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
Linux controls access to every file and directory through a permissions system. Understanding it is essential for running servers securely — wrong permissions are a common cause of both security vulnerabilities and "permission denied" errors.
Reading permissions with ls -l:
-rwxr-xr-- 1 bill developers 1234 Jun 27 deploy.sh ^ ^ ^ ^ | | | +--- other: r-- (read only) | | +----- group: r-x (read + execute) | +------- owner: rwx (all) +---------- file type (- = file, d = directory, l = symlink)
The three permission sets:
| Who | Symbol | Meaning | |-----|--------|---------| | Owner (user) | u | The user who owns the file | | Group | g | Users in the file's group | | Others | o | Everyone else | | All | a | shorthand for ugo |
The three permissions:
| Permission | On a file | On a directory | |------------|-----------|----------------| | r (read) | View content | List files inside | | w (write) | Modify content | Create/delete files inside | | x (execute) | Run as program | Enter the directory (cd) |
chmod — change permissions:
bash # Symbolic mode (easier to read) chmod u+x script.sh # add execute for owner chmod go-w sensitive.txt # remove write for group and others chmod a+r readme.txt # add read for everyone # Numeric (octal) mode — each digit is r(4)+w(2)+x(1) chmod 755 deploy.sh # rwxr-xr-x (owner: all, group+others: read+execute) chmod 644 config.txt # rw-r--r-- (owner: read+write, others: read only) chmod 600 id_rsa # rw------- (owner only — SSH key must be this) chmod 700 ~/.ssh # rwx------ (only owner can enter)
Common permission patterns:
| Octal | Symbolic | Use case | |-------|----------|----------| | 755 | rwxr-xr-x | Scripts, directories, binaries | | 644 | rw-r--r-- | Config files, web files | | 600 | rw------- | SSH private keys, .env files | | 777 | rwxrwxrwx | Avoid — everyone can modify |
chown — change ownership:
bash chown bill file.txt # change owner to bill chown bill:developers file.txt # change owner and group chown -R bill:www-data /var/www/ # recursive (entire directory tree)
sudo — run as superuser:
bash sudo apt install nginx # install software (requires root) sudo systemctl restart nginx sudo -i # open a root shell (use carefully)
Examples
Making a script executable and locking down secrets
SSH will refuse to connect and show "bad permissions" if your private key is readable by others — chmod 600 fixes it every time.
# Create a deploy script
touch deploy.sh
# Currently no execute permission — cannot run it
ls -la deploy.sh
# -rw-r--r-- 1 bill bill 512 Jun 27 deploy.sh
# Add execute for owner
chmod u+x deploy.sh
ls -la deploy.sh
# -rwxr--r-- 1 bill bill 512 Jun 27 deploy.sh
./deploy.sh # now works
# Lock down a .env file — only owner should read it
chmod 600 .env
ls -la .env
# -rw------- 1 bill bill 204 Jun 27 .env
# SSH private key must be 600 or SSH refuses to use it
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh # directory: owner can enter, others cannotWeb server ownership — a common real-world pattern
Web server file permissions: your user owns the files, the web server is in the group, others get nothing.
# Web server runs as www-data user
# Your app files are owned by bill
ls -la /var/www/myapp/
# -rw-r--r-- bill bill index.html — nginx can read (r for others)
# -rw------- bill bill secrets.env — nginx cannot read (no perms for others)
# Fix: make nginx group owner, give group read
sudo chown -R bill:www-data /var/www/myapp/
sudo chmod -R 750 /var/www/myapp/
# rwxr-x--- owner(bill): full, group(www-data): read+enter, others: nothing
# Uploaded files should not be executable — prevent script injection
find /var/www/uploads/ -type f -exec chmod 644 {} \;
# -rw-r--r-- for all files (no execute bit)How well did you understand this?
Next in Linux & Command Line
Processes & Jobs