- Fixed 4 broken markdown links (bad relative paths in See Also sections) - Corrected n8n port binding to 127.0.0.1:5678 (matches actual deployment) - Updated SnapRAID article with actual majorhome paths (/majorRAID, disk1-3) - Converted 67 Obsidian wikilinks to relative markdown links or plain text - Added YAML frontmatter to 35 articles missing it entirely - Completed frontmatter on 8 articles with missing fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
158 lines
4.8 KiB
Markdown
158 lines
4.8 KiB
Markdown
---
|
|
title: "Linux File Permissions and Ownership"
|
|
domain: linux
|
|
category: files-permissions
|
|
tags: [permissions, chmod, chown, linux, acl, security]
|
|
status: published
|
|
created: 2026-03-08
|
|
updated: 2026-03-08
|
|
---
|
|
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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`.
|
|
|
|
```bash
|
|
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.
|
|
|
|
```bash
|
|
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`.
|
|
|
|
```bash
|
|
chmod +t /shared/directory
|
|
# Shows as 't' in others execute position: drwxrwxrwt
|
|
```
|
|
|
|
## Finding and Fixing Permission Problems
|
|
|
|
```bash
|
|
# 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](../../02-selfhosting/security/linux-server-hardening-checklist.md)
|
|
- [ssh-config-key-management](../networking/ssh-config-key-management.md)
|
|
- [bash-scripting-patterns](../shell-scripting/bash-scripting-patterns.md)
|