Linux File Permissions Guide: chmod, chown & Security Best Practices

· ~13 min read

The Linux file permission system is the foundation of OS security. Whether you're deploying web applications, managing servers, or writing automation scripts, understanding commands like chmod and chown is essential. This guide systematically covers the Linux permission model, common commands, and security best practices.

Understanding the Linux Permission Model

Every Linux file and directory has three groups of permissions, each corresponding to a class of user:

User ClassDescriptionAbbreviation
Owner (User)File creator or current owneru
GroupUser group associated with the fileg
OthersAll other users on the systemo
AllAll three classes abovea

Each class has three types of permissions:

rwx
PermissionFor FilesFor DirectoriesValue
r ReadView file contentsList directory contents (ls)4
w WriteModify file contentsCreate/delete files in directory2
x ExecuteRun executable fileEnter directory (cd)1
- None0

When you run ls -la, a permission string like -rwxr-xr-- means:

- rwx r-x r--
│ │││ │││ │││
│ │││ │││ └└└── Others: r--
│ │││ └└└────── Group: r-x
│ └└└─────────── Owner: rwx
└──────────────── File type (- = regular, d = directory, l = link)

chmod Command Deep Dive

chmod (change mode) modifies file permissions. It supports two syntaxes: numeric mode and symbolic mode.

Numeric Mode (Most Common)

Each permission bit maps to a number: r=4, w=2, x=1. Combine the three user classes into a three-digit number:

ValueMeaningBinaryUse Case
755rwxr-xr-x111 101 101Executable files, directories
644rw-r--r--110 100 100Regular files, config files
600rw-------110 000 000Private keys, sensitive files
700rwx------111 000 000Private scripts
777rwxrwxrwx111 111 111⚠️ Avoid using
# Set file permissions to 644
chmod 644 config.yaml

# Set directory permissions to 755
chmod 755 /var/www/html

# Recursively modify directory and all contents
chmod -R 755 /var/www/html

Symbolic Mode

Symbolic mode uses letter combinations to add or remove permissions:

# Syntax: chmod [user class][operator][permission] file
# Operators: + add, - remove, = set

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

# Remove write permission for others
chmod o-w file.txt

# Set group to read-only
chmod g=r file.txt

# Multiple operations combined
chmod u+x,g+w,o-r file.txt

# Add read permission for all
chmod a+r README.md

chown and chgrp Commands

chown (change owner) modifies a file's owner and group. chgrp modifies the group only.

# Change owner
chown alice file.txt

# Change owner and group simultaneously
chown alice:developers file.txt

# Change group only (equivalent to chgrp)
chown :developers file.txt
chgrp developers file.txt

# Recursive changes
chown -R www-data:www-data /var/www/html

Special Permission Bits

SUID (Set User ID)

When a SUID-enabled executable is run, the process executes as the file's owner rather than the user who launched it. The classic example is /usr/bin/passwd:

ls -la /usr/bin/passwd
-rwsr-xr-x 1 root root ...

# Set SUID (add 4 before the numeric value)
chmod 4755 program

# Symbolic mode
chmod u+s program

SGID (Set Group ID)

For executables: the process runs as the file's group. For directories: newly created files inherit the directory's group (instead of the creator's default group):

# Set SGID on a directory (common for shared folders)
chmod 2775 /opt/shared
chgrp developers /opt/shared

# New files automatically inherit the developers group

Sticky Bit

In a directory with the Sticky Bit set, files can only be deleted by their owner or root. The classic example is /tmp:

ls -la /
drwxrwxrwt 10 root root ... /tmp

# Set Sticky Bit
chmod 1777 /opt/upload
chmod o+t /opt/upload

UMASK Explained

UMASK determines the default permissions for newly created files. It's not a "set" value but a "mask"—subtracting UMASK from the maximum permissions gives the actual permissions:

# Check current UMASK
umask
# Output: 0022

# File max 666 - 022 = 644 (rw-r--r--)
# Directory max 777 - 022 = 755 (rwxr-xr-x)

# Set stricter UMASK
umask 0027
# File: 666 - 027 = 640 (rw-r-----)
# Directory: 777 - 027 = 750 (rwxr-x---)

# Make permanent (add to ~/.bashrc)
echo "umask 0027" >> ~/.bashrc

Security Best Practices

Security Warning: Never use chmod 777 in production. It grants full read/write/execute permissions to everyone—a serious security vulnerability.

1. Principle of Least Privilege

# ✅ Correct: config file read-only
chmod 644 /etc/nginx/nginx.conf
chown root:root /etc/nginx/nginx.conf

# ✅ Correct: SSH private key owner-only
chmod 600 ~/.ssh/id_rsa

# ✅ Correct: Web directory
chown -R www-data:www-data /var/www
find /var/www -type d -exec chmod 750 {} \;
find /var/www -type f -exec chmod 640 {} \;

# ❌ Wrong: overly permissive
chmod 777 /var/www
chmod 666 /etc/passwd

2. Protecting Sensitive Files

# SSH keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

# Database config (contains passwords)
chmod 600 .env
chown app-user:app-user .env

# SSL certificate private key
chmod 600 /etc/ssl/private/key.pem
chown root:root /etc/ssl/private/key.pem

3. Web Application Permission Template

# Standard web app permission setup
APP_DIR=/var/www/myapp
WEB_USER=www-data

# Owner = deploy user, group = web server user
chown -R deploy:$WEB_USER $APP_DIR

# Directories: 750 (owner full access, group read+enter)
find $APP_DIR -type d -exec chmod 750 {} \;

# Files: 640 (owner read/write, group read-only)
find $APP_DIR -type f -exec chmod 640 {} \;

# Executable files: 750
find $APP_DIR -name "*.sh" -exec chmod 750 {} \;

# Storage directories: group needs write access
chmod 770 $APP_DIR/storage $APP_DIR/uploads

FAQ

What do chmod 755 and 644 mean?

chmod 755 maps to rwxr-xr-x: the owner can read, write, and execute (7=4+2+1); group and others can read and execute (5=4+1) but not write. Commonly used for directories and executable files. chmod 644 maps to rw-r--r--: the owner can read and write (6=4+2); others can only read (4). Commonly used for regular files and configuration files.

What are SUID and SGID?

SUID (Set User ID) makes an executable run with the file owner's permissions instead of the current user's. For example, /usr/bin/passwd has SUID set so regular users temporarily gain root privileges to change their password. SGID works similarly for groups on files; on directories, it makes new files inherit the directory's group. Use chmod 4755 (SUID) and chmod 2755 (SGID) to set them.

How do I quickly calculate chmod permission values?

Use the RiseTop online chmod calculator—check permissions visually or enter numeric values directly, with real-time display of the corresponding permission string and chmod command, including SUID/SGID/Sticky Bit special permission bits.

Visually calculate file permissions—no more manual conversion

Open the chmod Permission Calculator →