File permissions are Linux's first line of defense. Every file and directory has an owner, a group, and a set of read/write/execute bits. Get them wrong and you either lock out legitimate users or expose sensitive data. This guide covers everything from reading permission strings to setting default permissions with umask.
Reading Permission Strings
Run ls -l and you'll see output like this:
-rwxr-x--- 1 alok www-data 4096 Apr 10 12:00 deploy.sh
drwxr-xr-x 3 root root 4096 Apr 10 11:00 /etc/nginx
Break down the first field:
- Character 1: file type (
-= file,d= directory,l= symlink) - Characters 2-4: owner permissions (r=read, w=write, x=execute)
- Characters 5-7: group permissions
- Characters 8-10: other (everyone else)
So -rwxr-x--- means: owner can read/write/execute, group can read/execute, others have no access.
chmod — Change Permissions
Symbolic Mode
chmod u+x script.sh # Add execute for owner
chmod g-w file.txt # Remove write for group
chmod o=r file.txt # Set others to read-only
chmod a+r file.txt # Add read for all (user, group, other)
chmod u+x,g-w file.txt # Multiple changes at once
Octal (Numeric) Mode
Each permission is a bit: read=4, write=2, execute=1. Sum them for each group:
7= rwx (4+2+1)6= rw- (4+2)5= r-x (4+1)4= r-- (4)0= --- (0)
chmod 755 script.sh # rwxr-xr-x (common for scripts/dirs)
chmod 644 config.txt # rw-r--r-- (common for files)
chmod 600 ~/.ssh/id_rsa # rw------- (private keys)
chmod 640 /etc/app.conf # rw-r----- (owner+group read)
chmod 700 ~/scripts/ # rwx------ (private directory)
chmod -R 755 /var/www/html/ # Recursive
chown — Change Owner and Group
chown alok file.txt # Change owner to alok
chown alok:www-data file.txt # Change owner and group
chown :www-data file.txt # Change group only
chown -R alok:alok /home/alok/ # Recursive change
chown -R www-data:www-data /var/www/html/ # Web files to web user
chgrp — Change Group Only
chgrp developers /opt/project/
chgrp -R www-data /var/www/
Special Permission Bits
Setuid (SUID)
When set on an executable, it runs as the file's owner rather than the invoking user. The classic example is /usr/bin/passwd — it needs root access to edit /etc/shadow but runs as a regular user.
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ...
chmod u+s /usr/bin/myapp # Set SUID
chmod 4755 /usr/bin/myapp # Numeric: leading 4
Setgid (SGID)
On a directory, files created inside inherit the directory's group instead of the creator's primary group — useful for shared project directories.
chmod g+s /opt/project/
chmod 2755 /opt/project/ # Numeric: leading 2
Sticky Bit
When set on a directory, only the file owner (or root) can delete or rename files inside, even if others have write access. Used on /tmp.
ls -ld /tmp
# drwxrwxrwt ... <- the "t" is the sticky bit
chmod +t /shared/
chmod 1777 /shared/ # Numeric: leading 1
umask — Default Permission Mask
When you create a new file or directory, the umask determines the default permissions by subtracting from the maximum:
- Maximum for files: 666 (rw-rw-rw-)
- Maximum for directories: 777 (rwxrwxrwx)
umask # View current umask (typically 0022)
umask 027 # Set restrictive umask: files=640, dirs=750
umask 022 # Standard: files=644, dirs=755
With umask 022: a new file gets 666-022=644 (rw-r--r--), a new directory gets 777-022=755 (rwxr-xr-x).
Set umask permanently in ~/.bashrc or /etc/profile.
Finding Files with Specific Permissions
find / -perm -4000 2>/dev/null # Find all SUID files
find /var/www -perm -o+w 2>/dev/null # World-writable web files (danger)
find /home -name "*.sh" -perm /111 # Executable shell scripts
Summary
Linux permissions protect system integrity and user data. Use chmod to set permission bits, chown to assign ownership, and umask to control defaults. Audit SUID files and world-writable paths regularly on production systems — they are common privilege escalation vectors.