The Directory Tree

Linux uses a single hierarchical root (/). The Filesystem Hierarchy Standard (FHS) defines common layout:

Path Purpose
/ Root of the filesystem
/home User home directories
/root root user’s home
/etc System configuration
/var Variable data (logs, caches, spool)
/tmp Temporary files (sticky bit; often cleared on reboot)
/usr User programs, libraries, documentation
/opt Optional third-party software
/bin, /sbin Essential binaries (often symlinks to /usr/bin)
/dev Device files
/proc, /sys Kernel and hardware interfaces
  cd /var/log
ls -la
tree -L 2 /etc 2>/dev/null || find /etc -maxdepth 2 -type d
  

Paths and Navigation

  pwd                          # absolute path of cwd
cd /etc/nginx                # absolute
cd ../sites-available        # relative (.. = parent)

readlink -f ./symlink        # resolve canonical path
realpath config.conf         # same, if installed
  

Absolute paths start with /. Relative paths start from the current directory. Use absolute paths in scripts and systemd units to avoid ambiguity.

File Types and Metadata

  ls -lah
# First char: - file, d directory, l symlink, c/b device, p pipe, s socket

file /bin/bash
stat /etc/passwd             # inode, blocks, timestamps
ls -i file.txt               # inode number
  

Timestamps: atime (access), mtime (modification), ctime (metadata change). Use touch -d to set mtime for testing.

Permissions Model

Each file has an owner, group, and mode (rwx for user, group, others):

  ls -l /etc/shadow
# -rw-r----- 1 root shadow  → owner rw, group r, others none
  
Symbol Octal On files On directories
r 4 Read content List directory entries
w 2 Modify content Create/delete files
x 1 Execute Traverse (cd into)
  chmod 644 document.txt       # rw-r--r--
chmod 755 script.sh          # rwxr-xr-x
chmod u+x,g-w script.sh      # symbolic mode
chmod -R g+rX docs/          # X = execute on dirs only

chown alice:developers app/
chown -R www-data:www-data /var/www/html
chgrp deploy /opt/app/config.yml
  

Special Permission Bits

Bit File effect Directory effect
setuid (4) Run as file owner
setgid (2) Run as file group New files inherit group
sticky (1) Only owner deletes own files (/tmp)
  ls -ld /tmp                  # drwxrwxrwt — sticky bit
chmod u+s /usr/bin/passwd    # setuid example
find / -perm -4000 -type f 2>/dev/null   # find setuid binaries
  

Audit setuid binaries regularly — they are privilege escalation targets.

umask

Default permissions for new files and directories:

  umask                        # e.g. 0022
umask 027                    # stricter: group rwx, others none

# New file: 666 - umask; new dir: 777 - umask
# umask 022 → files 644, dirs 755
  

Set umask in /etc/profile, /etc/bash.bashrc, or PAM (/etc/login.defs).

Access Control Lists (ACLs)

When owner/group/others are insufficient:

  # Install ACL tools (Debian/Ubuntu)
sudo apt install acl

getfacl project/shared/
setfacl -m u:bob:rw project/shared/file.txt
setfacl -m g:developers:rwx project/shared/
setfacl -d -m g:developers:rwx project/shared/   # default ACL for new files
  
  ln -s /etc/nginx/nginx.conf ~/nginx.conf   # symbolic (soft) link
ln file hardlink                             # hard link (same inode)

# Find broken symlinks
find /opt -type l ! -exec test -e {} \; -print
  

Hard links cannot cross filesystems or link directories (usually). Symlinks can point anywhere but break if target moves.

Best Practices

Practice Reason
Never chmod 777 in production World-writable = any user can modify
Run services as non-root users Limits blast radius
Use group permissions for shared teams Avoids overly broad “others” access
Separate secrets with mode 600 Only owner reads
  chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
  

Common Mistakes

Mistake Consequence
chmod -R 777 to “fix” permissions Security hole; masks real ownership issues
Running web server as root Remote code execution = full system compromise
Ignoring directory execute bit Cannot cd even with read permission
Editing files as root that should be owned by service user Service cannot write after restart

Troubleshooting

Permission denied despite chmod:

  namei -l /path/to/file       # trace path permissions at each level
# Every directory in path needs execute (x) for traversal
  

Disk full but df shows space:

  # Deleted file still held open by process
lsof +L1
# Truncate or restart process holding deleted file
  

Production Scenario

A deployment user deploy must write to /var/www/app owned by www-data:

  sudo groupadd webteam
sudo usermod -aG webteam deploy
sudo usermod -aG webteam www-data
sudo chgrp -R webteam /var/www/app
sudo chmod -R g+rws /var/www/app   # setgid for group inheritance
  

New files inherit webteam group; both deploy and nginx can read/write without world permissions.

Understanding permissions prevents the most common production mistakes: world-writable configs, services running as root, and broken deployment permissions.