The Ultimate Guide to Linux File Permissions: chmod, chown & More
Linux file permissions define who can read, modify, execute, or access files and directories. They affect everyday server work, including deployments, SSH keys, scripts, uploads, backups, logs, and shared folders.
This guide is for developers, admins, DevOps beginners, website owners, and anyone working with Linux through the terminal. You only need command line access and basic tools such as ls, chmod, chown, chgrp, and find.
If you manage websites, applications, scripts, or databases on a Linux VPS server, understanding file permissions helps you find the real cause of access issues instead of relying on unsafe fixes like chmod 777.
Understanding the Linux Permission Model
Linux permissions are built around three access levels: user, group, and others. The user is the file or directory owner. The group allows several accounts to share controlled access. Others covers everyone else on the system.
This model is simple, but practical for real server work. A deployment user can manage application files, a web server group can read what it needs, and unrelated users can be blocked from changing sensitive data.
Linux also uses three core permission types: read, write, and execute. They look straightforward, but they behave differently for files and directories, which is where many permission mistakes begin.
Users, Groups, and Others, Read, Write, Execute — What Each Permission Does
Every file and directory has an owner and a group. When access is requested, Linux checks permissions in this order: owner first, then group, then others. It uses only the first matching category, so permissions are not combined.
Each category can have read, write, and execute access. For files, read means viewing contents, write means editing, and execute means running the file as a script or program. For directories, read means listing items, write means creating or deleting items, and execute means entering the directory.
This last point matters a lot. Without execute permission on a directory, a user may see its name but still fail to access files inside. That is why permission checks should include the full path, not just the final file.
How to Check File Permissions in Linux
The most common command for checking Linux file permissions is:
ls -l
A typical output line may look like this:
-rwxr-xr-- 1 deploy www-data 2048 May 8 app.sh
The first character shows the file type. A regular file starts with -, while a directory starts with d. The next nine characters show permissions for the owner, group, and others. In this example, rwx belongs to the owner, r-x belongs to the group, and r-- belongs to others.
The owner is deploy, and the group is www-data. This means the deploy user receives the owner permissions, while users in the www-data group receive the group permissions. Everyone else receives the others permissions.
Reading the Output of ls -l, Octal vs Symbolic Notation
The permission string always follows the same structure. The first character identifies the object type. The next three characters belong to the owner. The next three belong to the group. The final three belong to others.
For example:
drwxr-xr-x
This is a directory because it starts with d. The owner can read, write, and enter it. The group can read and enter it. Others can also read and enter it, but they cannot create or delete files inside it.
For a regular file, you may see:
-rw-r--r--
This means the owner can read and write, while the group and others can only read. This is a common permission pattern for public website files, static assets, and documents that should be visible but not editable by everyone.
Linux permissions can be written in symbolic notation or octal notation. Symbolic notation uses letters such as r, w, and x. Octal notation uses numbers, where read equals 4, write equals 2, and execute equals 1.
The numbers are added together for each identity level. Read and write become 6. Read and execute become 5. Read, write, and execute become 7. No permissions become 0. A value such as 755 means the owner gets 7, the group gets 5, and others get 5. In symbolic form, this becomes rwxr-xr-x. A value such as 644 means the owner can read and write, while the group and others can only read.
How to Change File Permissions with chmod
The chmod command changes permissions for files and directories. It supports two formats: symbolic mode and numeric mode.
Symbolic mode is best for small changes, such as adding execute permission to a script without changing anything else. Numeric mode is faster when you already know the exact permission value, such as 755 for directories or 644 for regular files.
Common Permission Values Explained: Symbolic Mode (chmod u+x, chmod go-w), Numeric Mode (chmod 755, chmod 644)
Symbolic mode uses identity letters, operators, and permission letters. The identity letters are u for user, g for group, o for others, and a for all. The operators are + to add a permission, - to remove a permission, and = to set permissions exactly.
For example:
chmod u+x script.sh
This adds execute permission for the owner. It is commonly used when a shell script exists but cannot be run directly.
Another useful command is:
chmod go-w file.txt
This removes write permission from the group and others. It is useful when a file should remain readable but should only be editable by its owner.
Numeric mode sets the full permission value in one command. For example:
chmod 755 script.sh
This allows the owner to read, write, and execute the file, while the group and others can read and execute it.
Another common command is:
chmod 644 index.html
This allows the owner to edit the file, while the group and others can only read it. This is a common setup for website files.
|
Permission value |
Common use |
What it means |
Safety note |
|
755 |
Directories and executable scripts |
The owner can read, write, and execute. Group and others can read and execute |
Good for directories that must be accessible, but not writable by everyone |
|
644 |
Regular website files, documents, public readable files |
The owner can read and write. Group and others can read only |
Good default for many web files and static assets |
|
777 |
Almost never appropriate for production |
Everyone can read, write, and execute |
Dangerous because any user or process can modify the item |
The value 777 deserves a strict warning. It gives complete access to everyone on the system. On a public server, shared environment, or Rocky Linux VPS, this can allow vulnerable scripts, compromised users, or malicious processes to modify files that should be protected. In most cases, chmod 777 does not solve the real problem. It only hides a deeper issue with ownership, group membership, service users, or application configuration.
Changing File Ownership with chown and chgrp
Permissions define what the owner, group, and others can do. Ownership defines who the owner and group actually are. This is why chmod and chown solve different problems.
The basic syntax for changing the owner is:
chown user file
To change both owner and group, use:
chown user:group file
To change only the group, use:
chown :group file
You can also change only the group with:
chgrp group file
For example:
chown deploy:www-data /var/www/example.com
This makes deploy the owner and www-data the group. In a web project, this can allow the deployment user to manage files while giving the web server controlled group access.
Recursive ownership changes are possible with:
chown -R user:group directory
Recursion should be used carefully because it changes ownership for every item inside the target directory. Before running recursive ownership changes, confirm the path with pwd, inspect the target with ls, and make sure you are not applying changes to a broad system directory by mistake.
The practical difference is simple. Use chmod when the correct user owns the file but the access level is wrong. Use chown or chgrp when the wrong user or group owns the file.
Recursive Permission Changes
Recursive permission changes apply a rule to an entire directory tree. They are useful during deployments, migrations, backups, and cleanup tasks, but they are also one of the fastest ways to create permission problems.
A risky command looks like this:
chmod -R 755 /var/www/example.com
This applies 755 to every file and directory. Directories often need execute permission because users and services must enter them, but ordinary files usually do not need execute permission. Applying the same value to everything can make regular files executable without reason.
A safer approach is to use find and apply separate permissions for directories and files:
find /var/www/example.com -type d -exec chmod 755 {} \;
find /var/www/example.com -type f -exec chmod 644 {} \;
This pattern is common for web projects. Directories remain accessible, regular files remain readable, and only the owner can modify content. When applications run on BlueVPS servers, this predictable structure also makes troubleshooting easier because files and directories follow different rules for a clear reason.
Recursive commands should always be reviewed before execution. A small typo in a path can change thousands of files. When working on production systems, it is better to test the target with find path -type f | head or find path -type d | head before applying changes.
Special Permissions: SUID, SGID, and Sticky Bit
Linux also supports special permission bits that change normal access behavior. They are useful in specific cases, but they should be applied carefully, especially on production systems.
SUID lets an executable run with the permissions of the file owner. This can be powerful because the program may perform actions that the current user normally cannot, so SUID should only be used when there is a clear reason.
SGID works with files and directories. On files, it runs an executable with the permissions of the file group. On directories, it makes new files inherit the directory group, which is helpful for shared project folders.
The sticky bit is often used on shared writable directories such as /tmp. It lets users create files but prevents them from deleting files owned by others.
Common examples include:
chmod u+s file
chmod g+s directory
chmod +t directory
Special permissions are not everyday settings for most website files. They are best used when there is a specific access control requirement, especially on production systems.
Troubleshooting Permission Errors
Permission errors are not always caused by the final file. Ownership, parent directories, service users, SSH key rules, filesystem mount options, and security systems such as SELinux or AppArmor can all be involved.
A good troubleshooting process starts with the active user, then checks the target file, then checks every parent directory in the path. This matters because a file can have correct permissions while one parent directory still blocks access.
|
Error or symptom |
Likely cause |
Practical solution |
|
Permission denied |
The active user lacks the required read, write, or execute permission |
Check whoami, run ls -l, then adjust the smallest necessary permission or ownership value |
|
Script does not run |
The file lacks execute permission |
Run chmod u+x script.sh, then execute it with ./script.sh |
|
Cannot enter directory |
The directory lacks execute permission |
Add execute permission for the correct user or group |
|
403 Forbidden in web server |
The web server user cannot access files or parent directories |
Check ownership, group access, and directory permissions across the full path |
|
SSH private key is rejected |
Private key permissions are too open |
Run chmod 600 ~/.ssh/id_rsa and confirm ownership of the .ssh directory |
|
Application cannot upload files |
The service user lacks write access to the upload directory |
Change owner or group for the upload directory, then grant write access only where needed |
|
chmod changes do not help |
Wrong owner, parent directory issue, SELinux, AppArmor, or mount restrictions |
Use namei -l path, check the service user, then inspect security policy if enabled |
On a US-based VPS, this kind of troubleshooting usually happens remotely through SSH, so a careful sequence saves time. Confirm the user, inspect the target file, check parent directories, verify ownership, then apply the narrowest safe change.
Quick Reference — chmod Cheat Sheet
Use this quick reference table when you need a fast command reminder for everyday Linux permission tasks, from checking access rights to fixing ownership and applying safe default values for files and directories.
|
Task |
Command |
|
Show file permissions |
ls -l file |
|
Show permissions across a full path |
namei -l /path/to/file |
|
Make a script executable for the owner |
chmod u+x script.sh |
|
Remove write access from group and others |
chmod go-w file |
|
Set standard file permissions |
chmod 644 file |
|
Set standard directory permissions |
chmod 755 directory |
|
Lock a private SSH key |
chmod 600 ~/.ssh/id_rsa |
|
Change file owner |
chown user file |
|
Change owner and group |
chown user:group file |
|
Change only group |
chgrp group file |
|
Apply 755 only to directories |
find path -type d -exec chmod 755 {} \; |
|
Apply 644 only to files |
find path -type f -exec chmod 644 {} \; |
|
Add sticky bit to a shared directory |
chmod +t directory |
|
Add SGID to a shared project directory |
chmod g+s directory |
FAQ
Is chmod 777 dangerous?
Yes. chmod 777 gives everyone full access, so it can expose files to unwanted changes, deletion, or attacks. Use it only for short testing, never as a permanent fix.
How do I make a file executable in Linux?
Use chmod u+x filename. For scripts, check the interpreter line, such as #!/bin/bash, then run it with ./filename.
What is the difference between chmod and chown?
chmod changes permissions. chown changes ownership. If the owner or group is wrong, chmod alone may not fix access.
What does chmod 755 mean?
chmod 755 gives the owner full access, while the group and others can read and execute. It is common for directories and scripts.
What does chmod 644 mean?
chmod 644 lets the owner read and edit, while the group and others can only read. It is common for website files and documents.
Why do I get Permission denied after changing permissions?
The issue may be ownership, parent directories, the service user, SELinux, or AppArmor. Check with whoami, ls -l, and namei -l.
Should files and directories have the same permissions?
Usually no. A safe web pattern is 755 for directories, 644 for files, and 600 for private keys.
Blog