Correct permissions are the backbone of Linux security. Misconfigured bits can expose secrets, break deployments, or allow privilege escalation. This guide demystifies permission modes, shows how to set secure defaults, and offers checklists you can apply to servers, containers, and developer laptops.
1. Why permissions matter
Permissions protect confidentiality (who can read), integrity (who can modify), and availability (who can execute). A leaked .env, a world-writable script, or an executable log file can all turn into incidents.
2. The permission model
- Users: owner, group, others
- Actions: read (r), write (w), execute (x)
- Numeric modes: r=4, w=2, x=1; summed per class (e.g., 754 → owner rwx, group r-x, others r--)
-
Symbolic modes:
u/g/o/awith+/-/=(e.g.,chmod g-w)
3. Understanding common modes
-
755: Directories and executable scripts; owner can write, everyone can execute/read. -
750: Private executables for team members in the group. -
644: Text files; owner writes, others read. -
600: Secrets like SSH keys or.envfiles. -
700: Private directories (e.g.,~/.ssh).
4. Special bits (setuid, setgid, sticky)
-
setuid (4xxx): Run as file owner (e.g.,
/usr/bin/passwd). Use sparingly; audit regularly. - setgid (2xxx): New files inherit group; useful for shared project dirs.
-
sticky bit (1xxx): On shared dirs (e.g.,
/tmp) prevents deleting others’ files. Example:chmod 2775 shared/keeps group ownership consistent.
5. chown and groups
-
chown user:group filesets ownership; avoid running as root unnecessarily. - Group strategy: create project groups, add collaborators, set dirs to
2775so files inherit the group. - Verify with
ls -landstatto ensure ownership matches expectations.
6. Secure defaults for apps and servers
- App configs/logs:
640with service user ownership - Private keys:
600, directory700 - Web roots: files
644, dirs755; write access only to deploy user - Cron scripts:
700with least privilege - Temp dirs: ensure
sticky biton shared locations
7. Permissions in Git and Docker
- Git tracks the executable bit but not owners; set modes in CI deploy scripts.
- In Docker images, switch to non-root users (
USER app), set700for secrets,755/644for app code, and avoid world-writable paths.
8. Troubleshooting common issues
- Permission denied: Check path execute bit on directories; ensure group membership.
-
Command works with sudo only: Ownership likely wrong; fix with
chown -R user:group pathand tighten modes. -
Scripts not executing: Ensure executable bit set (
chmod +x script.sh) and correct shebang.
9. Auditing and automation
- Use
findto locate risky files:find . -perm -o=w -type ffor world-writable files. - Regularly scan for setuid/setgid binaries you did not intend:
find / -perm -4000 -type f. - Codify desired states with Ansible/Chef or container build steps to prevent drift.
10. Quick reference table
- Code files:
644 - Executable scripts:
755(or750inside team dirs) - Secrets/keys:
600 - Shared project dirs:
2775 - User home private dirs:
700
Related tool: chmod-calculator
Use the chmod-calculator to translate between numeric and symbolic modes, visualize permission bits, and avoid risky defaults when deploying code or sharing directories.
Frequently Asked Questions
What does chmod 755 mean?
755 means: Owner can read/write/execute (7), Group can read/execute (5), Others can read/execute (5). This is the standard permission for directories and executable scripts where the owner needs write access but others only need read/execute.
What's the difference between 755 and 644?
- 755: Owner can read/write/execute, group and others can read/execute. Used for directories and executable scripts.
- 644: Owner can read/write, group and others can only read. Used for regular files like text documents, config files, and code files.
What permissions should I use for secret files?
Use 600 for secret files like SSH keys, .env files, or API keys. This gives only the owner read/write access—no group or others access. The directory containing secrets should be 700 (owner-only access).
What is the sticky bit?
The sticky bit (1xxx) on directories prevents users from deleting files they don't own, even if they have write permission to the directory. Common use: /tmp directory where users can create files but can't delete others' files.
What's the difference between setuid and setgid?
-
setuid (4xxx): File executes as the file owner, not the user running it. Example:
/usr/bin/passwdruns as root to modify password files. - setgid (2xxx): New files inherit the directory's group. Useful for shared project directories where all files should belong to the project group.
How do I change file ownership?
Use chown user:group filename to change ownership. Example: chown www-data:www-data /var/www/html sets web files to the web server user. Use -R flag for recursive changes on directories.
Why do I get "Permission denied" even with correct permissions?
Check that all parent directories have execute permission (x). To access a file, you need execute permission on every directory in the path. Also verify you're in the correct group if using group permissions.
Originally published at padawanabhi.de
Top comments (0)