Search tools

Developer guides

Linux file permissions explained: chmod numbers, chown and permission denied

What rwx really means, how numbers like 755 and 644 are built, when to reach for chown instead of chmod, and how to fix permission denied without resorting to 777.

Linux permissions look cryptic the first time you meet them, but the whole system fits on one page: three kinds of access, three kinds of people, and one owner and one group for every file.

Reading the output of ls

Run ls -l and every line starts with ten characters followed, a little later, by two names:

$ ls -l
-rw-r--r-- 1 deploy www-data  4096 Jan  1 09:00 index.html
drwxr-xr-x 2 deploy www-data  4096 Jan  1 09:00 uploads

The first character is the type: - for a file, d for a directory, l for a symbolic link. The next nine are three groups of three: permissions for the owner, for the group, and for everyone else. The two names are the owner (deploy) and the group (www-data).

Each group of three is always in the same order: r for read, w for write and x for execute, with a dash in place of any permission that is missing.

What read, write and execute mean

For a file, the meaning is what you would expect: read the contents, change them, run the file as a program.

For a directory it is less obvious:

  • Read lets you list the names inside it.
  • Write lets you create, rename and delete files inside it, even files you do not own, unless the sticky bit is set.
  • Execute lets you enter the directory and open the files in it by name.

That last point explains a lot of confusing errors. Without execute on a directory, and on every directory above it, nothing inside can be opened, whatever the file’s own permissions say.

The numbers: 755, 644 and friends

Each permission has a value: read is 4, write is 2 and execute is 1. Add them up for each group of three and you get one digit per group:

Digit Letters Meaning
7 rwx Read, write and execute
6 rw- Read and write
5 r-x Read and execute
4 r-- Read only
0 --- No access

So 755 is rwxr-xr-x: the owner can do everything, while the group and everyone else can read and execute. 644 is rw-r--r--: the owner can read and write, and everyone else can only read. The chmod calculator converts any combination in both directions and says in plain English who can do what.

The two you will use most are the defaults most systems create:

  • 755 for directories, and for scripts other people need to run
  • 644 for ordinary files

Private material needs tighter settings: 700 for private directories and 600 for files that hold secrets.

chmod versus chown

These two are easy to mix up, because they fix the same kind of error.

  • chmod changes what the owner, the group and everyone else are allowed to do.
  • chown changes who the owner and the group are.
chmod 644 index.html                    # set the permissions
sudo chown deploy:www-data index.html   # set the owner and the group

When a web server cannot write to a folder, the right fix is almost always ownership: give the web server’s user or group ownership and keep the permissions tight. Opening the folder with chmod 777 makes the error go away by letting every user and process on the machine write there, which is the kind of fix that turns into a security incident later.

Fixing permission denied

“Permission denied” means the user running a command lacks one specific permission. Work out which one:

  1. Who is running it? Your own user, root, or a service user such as www-data or nginx? Run whoami, or check the service’s configuration.
  2. Who owns the file, and what is its mode? Run ls -l on the file.
  3. Can that user reach it? namei -l /full/path/to/file lists the permissions of every directory on the way. A missing execute bit on any parent directory blocks everything below it.
  4. Running a script? It needs the execute bit: chmod +x script.sh.

Then change the smallest thing that fixes it: add the user to the right group, change the owner, or add a single permission. Reaching for 777 skips the diagnosis and leaves the hole open.

A sensible layout for a web project

For a typical site deployed by one user and served by a web server’s group:

sudo chown -R deploy:www-data /srv/site
find /srv/site -type d -exec chmod 755 {} \;
find /srv/site -type f -exec chmod 644 {} \;
chmod 775 /srv/site/uploads    # the one folder the server writes to
chmod 640 /srv/site/.env       # secrets: the owner writes, the server group reads

Directories need execute to be entered, which is why they get 755 while files get 644. A single recursive chmod on everything either gives every file the execute bit, which is untidy and occasionally risky, or takes it away from the directories, which breaks the site.

The special bits

A fourth digit in front sets setuid (4), setgid (2) and the sticky bit (1). You rarely set them by hand, but two are worth recognizing. /tmp is 1777: anyone can create files there, but the sticky bit stops people deleting each other’s. A shared project directory with setgid, such as 2775, makes every new file inherit the directory’s group, which saves a lot of chgrp.

Read next