| Permission | Octal | What it means | When to use |
|---|---|---|---|
-rw------- |
600 |
Owner reads and writes. Nobody else touches it. | SSH keys, .env files, anything with passwords |
-rw-r--r-- |
644 |
Owner reads and writes. Everyone else reads only. | HTML files, configs, most regular files |
drwx------ |
700 |
Owner has full access. Nobody else can even list contents. | ~/.ssh/, private home directories |
-rwxr-xr-x |
755 |
Owner has full access. Everyone else can read and execute. | Scripts, executables, web-accessible directories |
-rwxr-x--- |
750 |
Owner has full access. Group can read and execute. Others get nothing. | Shared team directories, group-restricted scripts |
-rwxrwxrwx |
777 |
Everyone can do everything. No restrictions at all. | Never. If you think you need this, you don't. |
Read, Write, Execute
Every file and directory in Linux has three types of permissions:
- Read (r) — You can see what's inside. For files, this means viewing the content. For directories, this means listing the files in it.
- Write (w) — You can modify it. For files, this means editing. For directories, this means creating or deleting files inside it.
- Execute (x) — You can run it. For files, this means running it as a program or
script. For directories, this is a weird one: it means you can "enter" the directory with
cd.
The directory execute permission trips people up. A directory with read but not execute lets you list filenames with ls, but you cannot cd into it or access any file inside it. This has been the behavior since the original Unix in the 1970s and it's not changing.
User, Group, Others
Those three permissions (rwx) are defined separately for three categories:
- Owner (u) — The user who owns the file. Usually whoever created it.
- Group (g) — A group of users. Every file belongs to one group, and all members of that group share these permissions.
- Others (o) — Everyone else on the system who isn't the owner and isn't in the group.
When you run ls -l, you see something like this:
-rw-r--r-- 1 anurag developers 2048 Jan 9 10:30 notes.txt
That -rw-r--r-- means:
- The first character (
-) tells you it's a regular file. If it were a directory, you'd seed. - The next three characters (
rw-) are the owner's permissions: read, write, no execute. - The next three (
r--) are the group's permissions: read only. - The last three (
r--) are everyone else's permissions: also read only.
In this example, anurag (owner) can read and edit the file. Anyone in the "developers" group can read it but not change it. Everyone else on the system can also read it. Fine for a notes file. Not fine for anything containing a password.
Octal Notation
In chmod 755 script.sh, each digit represents the permissions for owner, group, and others — in that order.
Each permission has a value:
- Read = 4
- Write = 2
- Execute = 1
You add them up to get the number. So:
7= 4 + 2 + 1 = read + write + execute (full permissions)6= 4 + 2 = read + write5= 4 + 1 = read + execute4= just read0= nothing
So when you see chmod 755, it means:
- 7 for owner — full access (read, write, execute)
- 5 for group — read and execute, but can't modify
- 5 for others — same, read and execute only
This is perfect for a script you want everyone to be able to run, but only you should edit. And
chmod 644 is standard for regular files: owner can read and write, everyone else can only
read.
Now you understand why chmod 777 is almost always wrong. You're saying "let literally
anyone read, modify, and execute this file." That's rarely what you want.
The chmod 777 Horror Story
The chmod 777 horror story:
A developer on a shared hosting box got a "permission denied" error deploying a PHP app. He ran chmod -R 777 /var/www/ to "fix" it. The web root now had world-readable permissions, including config.php which contained the MySQL root password in plaintext. Anyone on the server — and depending on the Apache config, anyone on the internet — could request that file directly and read the database credentials. The database had 40,000 customer records. It took three hours before someone noticed the config file was being served as plain text. The actual fix was chown www-data:www-data on the upload directory. That's it. One chown command instead of a data exposure incident.
Changing Ownership with chown
Half the time the problem isn't the permission bits — it's ownership. A file owned by root can't be edited by your user regardless of the rwx bits (unless "others" has write, which means you've already 777'd it).
The chown command changes ownership:
# Change owner to anurag
sudo chown anurag myfile.txt
# Change owner AND group
sudo chown anurag:developers myfile.txt
# Recursively change everything in a folder
sudo chown -R anurag:developers /var/www/mysite/
This comes up constantly with web servers. Files uploaded via FTP are owned by the FTP user, but the web server runs as www-data. Wrong ownership means "permission denied" that no amount of chmod will fix. chown is the answer, not 777.
Sticky Bit and Special Permissions
You might notice that the /tmp directory has weird permissions:
drwxrwxrwt 15 root root 4096 Jan 9 10:45 /tmp
💡 To check the exact permissions on a directory: stat /tmp | grep Access
See that t at the end instead of the usual x? That's the sticky bit. It means:
even though everyone can write to this directory, you can only delete files you own. Without it, anyone
could delete anyone else's temp files, which would be chaos.
You set it with:
chmod +t /some/shared/directory
# Or in octal, it's a leading 1
chmod 1777 /some/shared/directory
The other special bits are SUID (setuid) and SGID (setgid). SUID makes a binary run as its owner instead of the user executing it — this is how passwd can write to /etc/shadow even though you're not root. SGID does the same for group ownership, and on directories it forces new files to inherit the directory's group.
SUID is the most dangerous permission bit and you should audit any SUID binary you don't recognize. A SUID binary owned by root is effectively a root shell with extra steps. If an attacker finds one with a vulnerability, they own your system.
Common Permission Patterns
What I actually type day to day:
# Regular files (documents, configs)
chmod 644 filename.txt # Owner can edit, everyone can read
# Scripts I want to run
chmod 755 script.sh # Owner can edit, everyone can run
# Private files (SSH keys, passwords)
chmod 600 id_rsa # Only owner can read/write, nobody else
# Private directories
chmod 700 .ssh/ # Only owner can access at all
# Web server files
chmod 644 index.html # Everyone can read
chmod 755 /var/www/mysite/ # The directory needs execute to enter
Debugging Permission Issues
When something isn't working and you suspect permissions, here's my debugging process:
- Run
ls -laon the file AND its parent directories. You need execute permission on every directory in the path. - Check who the process is running as. A web server runs as
www-data, not as you. Useps aux | grep nginxor similar. - Check if SELinux or AppArmor is blocking you. On CentOS/RHEL, run
getenforce. If it says "Enforcing, " that's a whole other layer of security that might be stopping you even with correct Unix permissions. - Look at the actual error message. "Permission denied" usually means Unix permissions. "Operation not permitted" sometimes means something else is going on.
Homework
Run find / -perm -4000 2>/dev/null and review every binary in that list. That's your homework.
💬 Comments