Skip to content

Linux File Permissions and Ownership

File permissions are how Linux controls who can read, write, and execute files. Misunderstanding them is responsible for a lot of broken setups — both "why can't I access this" and "why is this insecure." This is the reference I'd want when something permission-related goes wrong.

The Short Answer

# Change permissions
chmod 755 /path/to/file
chmod +x script.sh        # add execute for all
chmod u+w file            # add write for owner
chmod o-r file            # remove read for others

# Change ownership
chown user file
chown user:group file
chown -R user:group /directory/   # recursive

Reading Permission Bits

When you run ls -la, you see something like:

-rwxr-xr-- 1 major wheel 4096 Mar 8 10:00 myscript.sh
drwxr-xr-x 2 root  root  4096 Mar 8 10:00 mydir/

The first column breaks down as:

- rwx r-x r--
│ │   │   └── Others: read only
│ │   └────── Group: read + execute
│ └────────── Owner: read + write + execute
└──────────── Type: - = file, d = directory, l = symlink

Permission bits:

Symbol Octal Meaning
r 4 Read
w 2 Write
x 1 Execute (or traverse for directories)
- 0 No permission

Common permission patterns:

Octal Symbolic Common use
755 rwxr-xr-x Executables, directories
644 rw-r--r-- Regular files
600 rw------- Private files (SSH keys, config with credentials)
700 rwx------ Private directories (e.g., ~/.ssh)
777 rwxrwxrwx Everyone can do everything — almost never use this

chmod

# Symbolic mode
chmod u+x file        # add execute for user (owner)
chmod g-w file        # remove write from group
chmod o=r file        # set others to read-only exactly
chmod a+r file        # add read for all (user, group, other)
chmod ug=rw file      # set user and group to read+write

# Octal mode
chmod 755 file        # rwxr-xr-x
chmod 644 file        # rw-r--r--
chmod 600 file        # rw-------

# Recursive
chmod -R 755 /var/www/html/

chown

# Change owner
chown major file

# Change owner and group
chown major:wheel file

# Change group only
chown :wheel file
# or
chgrp wheel file

# Recursive
chown -R major:major /home/major/

Special Permissions

Setuid (SUID): Execute as the file owner, not the caller. Used by system tools like sudo.

chmod u+s /path/to/executable
# Shows as 's' in owner execute position: rwsr-xr-x

Setgid (SGID): Files created in a directory inherit the directory's group. Useful for shared directories.

chmod g+s /shared/directory
# Shows as 's' in group execute position

Sticky bit: Only the file owner can delete files in the directory. Used on /tmp.

chmod +t /shared/directory
# Shows as 't' in others execute position: drwxrwxrwt

Finding and Fixing Permission Problems

# Find files writable by everyone
find /path -perm -o+w -type f

# Find SUID files (security audit)
find / -perm -4000 -type f 2>/dev/null

# Find files owned by a user
find /path -user major

# Fix common web server permissions (files 644, dirs 755)
find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;

Gotchas & Notes

  • Directories need execute to traverse. You can't cd into a directory without execute permission, even if you have read. This catches people off guard — chmod 644 on a directory locks you out of it.
  • SSH is strict about permissions. ~/.ssh must be 700, ~/.ssh/authorized_keys must be 600, and private keys must be 600. SSH silently ignores keys with wrong permissions.
  • chmod -R 777 is almost never the right answer. If something isn't working because of permissions, find the actual issue. Blanket 777 creates security holes and usually breaks setuid/setgid behavior.
  • umask controls default permissions. New files are created with 0666 & ~umask, new directories with 0777 & ~umask. The default umask is usually 022, giving files 644 and directories 755.
  • ACLs for more complex needs. When standard user/group/other isn't enough (e.g., multiple users need different access to the same file), look at setfacl and getfacl.

See Also

  • [[linux-server-hardening-checklist]]
  • [[ssh-config-key-management]]
  • [[bash-scripting-patterns]]