Misconfigured file permissions are behind a surprising number of “why isn’t this working” moments in a homelab — a web server that can’t read its own files, a Docker volume owned by the wrong user, an SSH key rejected for being too permissive. Mastering Linux file permissions with chmod and chown resolves most of these issues immediately, once the underlying logic actually clicks.
The Permission Model Basics
Every file and directory on a Linux system has three permission categories, each controlling a different level of access:
- Owner – the specific user who owns the file
- Group – a specific group of users who share access
- Others – everyone else on the system
Each category has three possible permissions: read (r), write (w), and execute (x), which behave slightly differently for files versus directories.
Reading Permission Output
Running ls -l shows permissions in a format like:
-rwxr-xr-- 1 user group 4096 Jan 1 12:00 script.sh
Breaking down rwxr-xr--:
- First
rwx– owner can read, write, and execute - Next
r-x– group can read and execute, but not write - Final
r--– others can only read
What Permissions Actually Mean for Files vs Directories
For files: read lets you view content, write lets you modify it, execute lets you run it as a program or script.
For directories: read lets you list its contents, write lets you create or delete files within it, execute lets you actually enter (cd into) the directory — meaning a directory without execute permission is effectively inaccessible even if you can technically “see” it listed elsewhere.
Using chmod to Change Permissions
chmod modifies permissions using either symbolic or numeric notation.
Symbolic notation:
chmod u+x script.sh
chmod g-w file.txt
chmod o=r document.txt
Numeric (octal) notation, where read=4, write=2, execute=1, summed per category:
chmod 755 script.sh
This sets owner to rwx (4+2+1=7), group to r-x (4+0+1=5), and others to r-x (4+0+1=5) — a common pattern for executable scripts meant to be run by others but only modified by the owner.
Common Permission Patterns
- 644 – standard for regular files (owner read/write, everyone else read-only)
- 755 – standard for directories and executable scripts (owner full access, everyone else read/execute)
- 600 – private files only the owner should access, common for SSH private keys and sensitive configuration
- 700 – private directories only the owner should enter
Using chown to Change Ownership
chown changes which user and group own a file:
sudo chown www-data:www-data /var/www/html/index.php
This is especially relevant in Docker setups , where a container’s internal user ID needs to match the host file’s ownership for the container to actually read or write it correctly.
Applying Changes Recursively
Both commands support recursive application to an entire directory tree with the -R flag:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
Use recursive changes carefully — applying overly permissive settings recursively across an entire directory can unintentionally weaken security on files that should have remained more restricted.
Why SSH Rejects Overly Permissive Keys
A common frustration: SSH refusing to use a private key file, with an error about permissions being “too open.” SSH specifically requires private keys to be readable only by their owner:
chmod 600 ~/.ssh/id_ed25519
Anything more permissive is rejected as a security precaution, since a private key readable by other users defeats much of its purpose.
The Special Permission Bits
Beyond the basic read/write/execute model, Linux supports additional special permissions:
- SUID – lets a program run with the file owner’s permissions rather than the executing user’s, used carefully for specific system utilities
- SGID – on directories, causes new files created within to inherit the directory’s group rather than the creating user’s default group
- Sticky bit – commonly seen on
/tmp, preventing users from deleting files they don’t own even if the directory itself is otherwise writable by everyone
Final Thoughts
Understanding Linux file permissions with chmod and chown resolves a huge share of the confusing “permission denied” errors that come up constantly while running a homelab, from Docker volume ownership mismatches to SSH key rejections. Once the owner/group/others and read/write/execute model actually clicks, most permission-related troubleshooting becomes a quick, confident fix rather than trial-and-error guessing.

Leave a Reply