chmod, chown, file permission bits, special permissions, and ACLs
Every file has permissions for user (owner), group, and other
-rwxr-xr--
│└──┘└──┘└──┘
│ u g o
│
└ file type: - file, d dir, l symlink
r = read (4)
w = write (2)
x = execute (1)Interpret the permission string from ls -l output
-rw-r--r-- 1 alice staff 1024 Jan 1 12:00 file.txt
-rw-r--r--
│└─┘└─┘└─┘
│ u g o
│
└ - = regular file
rw- = user: read+write
r-- = group: read only
r-- = other: read onlyPermissions expressed as sum of read(4)+write(2)+execute(1)
644 → rw-r--r-- (files: owner RW, others R)
755 → rwxr-xr-x (dirs/scripts: owner RWX, others RX)
700 → rwx------ (private: owner only)
600 → rw------- (private files: SSH keys)
777 → rwxrwxrwx (everyone everything — avoid!)
775 → rwxrwxr-x (group-writable)
664 → rw-rw-r-- (group-writable files)Use u/g/o/a with +/-/= to modify permissions
chmod u+x script.sh # add execute for user
chmod go-w file.txt # remove write from group+other
chmod a+r file.txt # add read for all
chmod u=rwx,go=rx dir/ # set exact permissions
chmod o= file.txt # remove all other permissionsSet permissions with octal numbers directly
chmod 644 file.txt # standard file permissions
chmod 755 script.sh # executable script
chmod 700 ~/.ssh # private SSH directory
chmod 600 ~/.ssh/id_rsa # private SSH key
chmod -R 755 /var/www/ # recursive (-R flag)Change file owner and/or group
chown alice file.txt # change owner
chown alice:staff file.txt # owner and group
chown :staff file.txt # group only
chown -R alice:staff /var/www/ # recursiveChange the group of a file
chgrp staff file.txt
chgrp -R developers /var/www/Execute file with owner's privileges (dangerous)
chmod u+s /usr/bin/program # set SUID
chmod 4755 /usr/bin/program # numeric
# ls shows: rwsr-xr-x (s in user x position)Files in directory inherit the directory's group
chmod g+s /shared/dir # set SGID on directory
chmod 2775 /shared/dir # numeric
# ls shows: rwxrwsr-x (s in group x position)Only file owner can delete files in directory (e.g. /tmp)
chmod +t /tmp # set sticky bit
chmod 1777 /tmp # numeric
# ls shows: rwxrwxrwt (t in other x position)Default permission mask subtracted from new files
umask # show current mask (e.g. 0022)
umask 0027 # set mask: files=640, dirs=750
# Common masks:
# 022 → files 644, dirs 755 (typical)
# 027 → files 640, dirs 750 (more secure)
# 077 → files 600, dirs 700 (most secure)Create and set permissions for a shell script
#!/bin/bash
# Create script
cat > deploy.sh << 'EOF'
#!/bin/bash
echo "Deploying..."
EOF
# Make executable (owner only can run)
chmod 700 deploy.sh
# Or executable by everyone
chmod 755 deploy.sh
# Check result
ls -la deploy.sh
# -rwxr-xr-x 1 alice staff 42 Jan 1 deploy.shSecure permissions for a web application directory
# Typical web application setup
# Owner: www-data (web server user), Group: developers
# Set ownership
chown -R www-data:developers /var/www/myapp
# Directories: rwxr-xr-x (755)
find /var/www/myapp -type d -exec chmod 755 {} \;
# Files: rw-r--r-- (644)
find /var/www/myapp -type f -exec chmod 644 {} \;
# Writable upload directory: rwxrwxr-x (775)
chmod 775 /var/www/myapp/uploads
# Config files (sensitive): rw------- (600)
chmod 600 /var/www/myapp/.envRequired permissions for SSH key files
# SSH directory must be 700
chmod 700 ~/.ssh
# Private key must be 600 (owner read/write only)
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
# Public key can be 644
chmod 644 ~/.ssh/id_rsa.pub
# authorized_keys must be 600
chmod 600 ~/.ssh/authorized_keys
# known_hosts
chmod 644 ~/.ssh/known_hosts
# Check: SSH will refuse to use keys with wrong permissions
ssh -i ~/.ssh/id_rsa user@host
# WARNING: UNPROTECTED PRIVATE KEY FILE! → fix with chmod 600Never use chmod 777 in production — it grants full access to everyone on the system
Use 644 for regular files and 755 for directories as a baseline
Store sensitive credentials with 600 permissions so only the owner can read them
Use sudo sparingly — prefer group membership (chgrp, SGID) for shared access
Use find with -perm to audit files with unexpected permissions