chore: link vault wiki to Gitea
This commit is contained in:
157
01-linux/files-permissions/linux-file-permissions.md
Normal file
157
01-linux/files-permissions/linux-file-permissions.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
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]]
|
||||
- [[ssh-config-key-management]]
|
||||
- [[bash-scripting-patterns]]
|
||||
Reference in New Issue
Block a user