Linux File Permissions Explained: chmod, chown, and the Permission Calculator

Linux File Permissions Explained: chmod, chown, and the Permission Calculator

“Permission denied.” The two words every Linux user learns to hate. But file permissions are not a barrier — they are the security model that protects everything on a Linux system.

This guide explains how Linux permissions work, how to read them, how to change them, and the common permission sets you will use every day.

Permission Calculator

Octal Permissions Meaning Common Use
755 rwxr-xr-x Owner: full. Group/Others: read+execute Scripts, executables, directories
644 rw-r--r-- Owner: read+write. Group/Others: read Regular files, configs
700 rwx------ Owner: full. Nobody else. Private scripts, .ssh directory
600 rw------- Owner: read+write. Nobody else. SSH keys, secrets, .env files
775 rwxrwxr-x Owner+Group: full. Others: read+execute Shared project directories
664 rw-rw-r-- Owner+Group: read+write. Others: read Shared files in a team
777 rwxrwxrwx Everyone: full access Never use this.

Reading File Permissions

Run ls -la to see permissions:

ls -la
drwxr-xr-x 2 eric eric  4096 Mar 10 09:00 scripts/
-rw-r--r-- 1 eric eric  1234 Mar 10 09:00 config.yml
-rwx------ 1 eric eric   512 Mar 10 09:00 deploy.sh
-rw------- 1 eric eric   401 Mar 10 09:00 .env

The permission string has 10 characters:

d rwx r-x r-x
| |   |   |
| |   |   +-- Others (everyone else)
| |   +------ Group
| +---------- Owner
+------------ Type (d=directory, -=file, l=symlink)

Each position is either the permission letter or a dash:

  • r (read) = can view contents / list directory
  • w (write) = can modify / create files in directory
  • x (execute) = can run as program / enter directory
  • - = permission not granted

Octal (Numeric) Notation

Each permission has a numeric value:

  • r = 4
  • w = 2
  • x = 1

Add them up for each group (owner, group, others):

rwx = 4+2+1 = 7
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
--- = 0+0+0 = 0

So: rwxr-xr-- = 754

To work backwards from an octal number:

755:
  7 = rwx (owner can read, write, execute)
  5 = r-x (group can read and execute)
  5 = r-x (others can read and execute)

Changing Permissions with chmod

Octal Method

# Make a script executable
chmod 755 deploy.sh

# Protect a private key
chmod 600 ~/.ssh/id_ed25519

# Secure a config file
chmod 644 config.yml

# Lock down a directory
chmod 700 ~/.ssh

Symbolic Method

# Add execute permission for owner
chmod u+x script.sh

# Remove write permission from group and others
chmod go-w file.txt

# Add read permission for everyone
chmod a+r readme.txt

# Set exact permissions
chmod u=rwx,g=rx,o=r file.txt

The targets are: u (user/owner), g (group), o (others), a (all).

The operators are: + (add), - (remove), = (set exactly).

Recursive Changes

# Apply to directory and all contents
chmod -R 755 /var/www/html/

# Better: set directories and files separately
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;

Directories need execute permission to be entered. Files generally do not. Using find to set them separately is the correct approach.

Changing Ownership with chown

# Change owner
sudo chown eric file.txt

# Change owner and group
sudo chown eric:developers file.txt

# Change group only
sudo chown :developers file.txt

# Recursive ownership change
sudo chown -R www-data:www-data /var/www/html/

You need sudo to change ownership because only root can give files to other users. This prevents users from bypassing disk quotas by assigning large files to other accounts.

Common Permission Scenarios

Web Server Files

sudo chown -R www-data:www-data /var/www/html/
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;

SSH Keys

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/config

SSH refuses to use keys with overly permissive permissions. If SSH key authentication fails silently, check permissions first.

Docker Bind Mounts

# Common issue: container runs as different UID
sudo chown -R 1000:1000 ./data/
# Or match the container's user
sudo chown -R 33:33 ./nextcloud-data/  # www-data = UID 33

Shared Directory for a Team

sudo mkdir /opt/project
sudo chown root:developers /opt/project
sudo chmod 775 /opt/project
sudo chmod g+s /opt/project  # setgid: new files inherit group

Troubleshooting “Permission Denied”

  1. Check the file permissions: ls -la filename
  2. Check who you are: id (shows your UID and groups)
  3. Check directory permissions: You need x on every directory in the path
  4. Check ownership: ls -la shows owner:group
  5. Check if executable: Scripts need chmod +x
  6. Check SELinux/AppArmor: getenforce (SELinux) or aa-status (AppArmor)

The most common cause: you are not the owner, not in the right group, and the “others” permissions do not include what you need.

Why This Matters

  • Interview favourite — “What does chmod 755 mean?” is asked in almost every Linux sysadmin interview
  • Security audits — overly permissive files (especially 777) are audit findings
  • Container debugging — permission mismatches between host and container are the most common bind mount issue
  • Web server troubleshooting — “403 Forbidden” is almost always a permission problem

Next Steps

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top