Convert Unix permissions between 755, rwxr-xr-x and checkboxes, including setuid, setgid and the sticky bit. Get the exact chmod and find commands, see what a umask produces, and find out what each permission lets an attacker do.
-rwxr-xr-x
u=rwx,g=rx,o=rx
| Read (4) | Write (2) | Execute (1) | Special | |
|---|---|---|---|---|
| Owner | ||||
| Group | ||||
| Others |
umask
umask removes permissions from 666 (files) and 777 (directories). 022 is the usual default, 027 keeps everything private to your group, and 077 private to you.
Never use 777 on a web server: any script on the box can rewrite your files. If something "only works with 777", the real fix is the file's owner (chown) or group, not more permissions.
Unix permissions are nine bits and three special flags, and somehow they've confused every sysadmin who ever lived at least once. Usually at the exact moment a server returns 403 Forbidden. Click the boxes, read the number. Or type the number and read the boxes.
How to use it
Tick read, write and execute for owner, group and others. The octal (755), symbolic (rwxr-xr-x) and the exact chmod command update live, and you can type into any of them to drive the others. Toggle setuid, setgid and the sticky bit for the fourth digit. There's also a umask mode that shows what new files and directories will get, and a stat/ls -l decoder: paste -rwsr-xr-x and it tells you what you're looking at.
The numbers you'll actually use
644(rw-r--r--): regular files: HTML, CSS, images, PHP.755(rwxr-xr-x): directories, and CGI scripts that need to execute.600(rw-------): secrets:wp-config.phpon a single-user box, SSH keys,.env.640(rw-r-----): config the web server's group must read but the world must not.777: never. If something only works at 777, the owner is wrong, not the mode.
Each octal digit is just a sum: read = 4, write = 2, execute = 1. 7 = 4+2+1, 5 = 4+1. That's the whole trick.
Fix a whole web root in one shot
find /var/www/site -type d -exec chmod 755 {} +
find /var/www/site -type f -exec chmod 644 {} +
chmod 600 /var/www/site/wp-config.php
chown -R deploy:www-data /var/www/site
Or the elegant one: chmod -R u=rwX,go=rX /var/www/site. Capital X adds execute only to directories and files that are already executable.
What execute means on a directory
On a directory, r lists names, x lets you enter it and reach files inside. Apache needs x on every directory in the path, all the way up from /. A directory at 644 is the classic hidden cause of 403 Forbidden with "search permissions are missing" in the error log.
The special bits
- setuid (4xxx): run as the file's owner. How
passwdwrites/etc/shadow. A setuid root binary you didn't install is a compromise. - setgid (2xxx): on a directory, new files inherit its group. Perfect for shared deploy dirs.
- sticky (1xxx): in a shared dir, only owners can delete their files. That's why
/tmpis1777.
# hunt for setuid/setgid files: know every one of these find / -xdev -perm /6000 -type f -ls 2>/dev/null
FAQ
Why do my uploads get the wrong permissions?
The process umask. With umask 022, files land at 644 and directories at 755. Use umask mode above to see the effect of yours.
Should PHP files be executable?
No. PHP files are read by PHP-FPM or mod_php, not executed by the kernel. 644 is right. Only CGI scripts run directly need x.
What about .htaccess?
644. Apache has to read it; nobody but you should write it. Want to know what to put in it? The .htaccess generator has you covered.