Linux Gotchas
Permission Traps
chmod 777fixes nothing, breaks everything — find the actual owner/group issueSetuid on scripts is ignored for security — only works on binaries
chown -Rfollows symlinks outside target directory — use--no-dereferenceDefault umask 022 makes files world-readable — set 077 for sensitive systems
ACLs override traditional permissions silently — check with
getfacl
Process Gotchas
killsends SIGTERM by default, not SIGKILL — process can ignore itnohupdoesn't work if process already running — usedisowninsteadBackground job with
&still dies on terminal close withoutdisownornohupZombie processes can't be killed — parent must call wait() or be killed
kill -9skips cleanup handlers — data loss possible, use SIGTERM first
Filesystem Traps
Deleting open file doesn't free space until process closes it — check
lsof +L1rm -rf /path /with accidental space = disaster — userm -rf /path/trailing slashInodes exhausted while disk shows space free — many small files problem
Symlink loops cause infinite recursion —
find -Lfollows them/tmpcleared on reboot — don't store persistent data there
Disk Space Mysteries
Deleted files held open by processes —
lsof +L1shows them, restart process to freeReserved blocks (5% default) only for root —
tune2fs -m 1to reduceJournal eating space —
journalctl --vacuum-size=500MDocker overlay eating space —
docker system prune -aSnapshots consuming space — check LVM, ZFS, or cloud provider snapshots
Networking
localhostand127.0.0.1may resolve differently — check/etc/hostsFirewall rules flushed on reboot unless saved —
iptables-saveor use firewalld/ufw persistencenetstatdeprecated — usessinsteadPort below 1024 requires root — use
setcapfor capability insteadTCP TIME_WAIT exhaustion under load — tune
net.ipv4.tcp_tw_reuse
SSH Traps
Wrong permissions on ~/.ssh = silent auth failure — 700 for dir, 600 for keys
Agent forwarding exposes your keys to remote admins — avoid on untrusted servers
Known hosts hash doesn't match after server rebuild — remove old entry with
ssh-keygen -RSSH config Host blocks: first match wins — put specific hosts before wildcards
Connection timeout on idle — add
ServerAliveInterval 60to config
Systemd
systemctl enabledoesn't start service — also needstartrestartvsreload: restart drops connections, reload doesn't (if supported)Journal logs lost on reboot by default — set
Storage=persistentin journald.confFailed service doesn't retry by default — add
Restart=on-failureto unitDependency on network:
After=network.targetisn't enough — usenetwork-online.target
Cron Pitfalls
Cron has minimal PATH — use absolute paths or set PATH in crontab
Output goes to mail by default — redirect to file or
/dev/nullCron uses system timezone, not user's — set TZ in crontab if needed
Crontab lost if edited incorrectly —
crontab -l > backupbefore editing@reboot runs on daemon restart too, not just system reboot
Memory and OOM
OOM killer picks "best" victim, often not the offender — check dmesg for kills
Swap thrashing worse than OOM — monitor with
vmstatMemory usage in
freeincludes cache — "available" is what mattersProcess memory in
/proc/[pid]/status— VmRSS is actual usagecgroups limit respected before system OOM — containers die first
Commands That Lie
dfshows filesystem capacity, not physical disk — check underlying devicedudoesn't count sparse files correctly — file appears smaller than disk usageps auxmemory percentage can exceed 100% (shared memory counted multiple times)uptimeload average includes uninterruptible I/O wait — not just CPUtopCPU percentage is per-core — 400% means 4 cores maxed