Sau bài này bạn làm được: SSH vào máy chưa từng thấy và trong vài phút trả lời: cấu hình dịch vụ X nằm đâu, log nằm đâu, binary do package nào cài; hiểu vì sao /bin trỏ tới /usr/bin trên nhiều hệ thống hiện đại; không còn “đoán” đường dẫn dựa trên cảm tính từ distro khác.
FHS là gì — và vì sao nó vẫn “đúng” dù đời thực có hỗn loạn
Filesystem Hierarchy Standard (FHS) mô tả ý định của từng thư mục gốc: /etc cho cấu hình tĩnh, /var cho dữ liệu thay đổi, /usr cho phần mềm read-only (lý tưởng), /opt cho phần mềm bên thứ ba tự chứa…
Distro không bắt buộc tuân FHS từng milimet, nhưng độ lệch có chi phí: tài liệu Stack Overflow, playbook Ansible, và bộ não của bạn đều được huấn luyện trên mô hình “gần đúng FHS”. Khi một vendor đặt config vào /srv/weird, bạn ghi chú lại — đó là nợ kỹ thuật định hướng.
Bản đồ tối thiểu cho người vận hành
| Thư mục | Ý định FHS | Ops quan tâm vì… |
|---|---|---|
/ | root filesystem | Đầy = máy không boot được hoặc service fail toàn cục |
/boot | kernel, initramfs | Đầy khi kernel cũ chưa prune; Secure Boot / EFI |
/etc | cấu hình host-specific | Đây là “source of truth” cho hành vi máy |
/usr | program read-only | Package manager đặt binary & lib ở đây |
/var | dữ liệu thay đổi | Log, spool, cache package, DB data (tuỳ cài đặt) |
/tmp, /var/tmp | temp | Disk đầy / tmp race; tmpfs vs disk |
/run | runtime state (tmpfs) | PID file, socket của daemon đương đại |
/dev, /proc, /sys | kernel interfaces | Debug: cmdline, mounts, cgroup hiện tại |
# Xem mount — biết /var/log có phải tmpfs không, / có tách riêng không
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
Mẹo: trên server cloud, / đôi khi là một partition duy nhất; log phình có thể giết cả rootfs. Bài 7 đi sâu disk/inode — ở đây chỉ cần cảnh giác: /var và / chung ổ là mặc định nguy hiểm nếu không rotate log.
/etc: không chỉ là “file text”
/etc là nơi admin và package ghi chính sách:
passwd,group,shadow— identity (bài 4).ssh/sshd_config— biên remote (bài 10).systemd/system/*.conf— override unit (bài 5).apt/sources.list.d/,dnf.repos.d/— nguồn patch (bài 8).
.d directories: pattern “file nhỏ override” (foo.conf + foo.d/*.conf) giúp package thêm snippet mà không sửa file gốc của distro. Khi debug, đừng chỉ đọc một file — hãy grep -R trong thư mục .d tương ứng.
# Ví dụ: tìm mọi chỗ set LogLevel cho sshd
grep -Rni loglevel /etc/ssh/sshd_config /etc/ssh/sshd_config.d 2>/dev/null
/var: nơi “thời gian” để lại dấu vết
| Đường dẫn | Thường chứa |
|---|---|
/var/log | journal file (nếu persistent), syslog, app log |
/var/lib | state của dịch vụ: Docker images, package DB (dpkg), DB data nếu default |
/var/cache | cache download apt/dnf |
/var/spool | mail queue, cron output (tuỳ cấu hình) |
Journald: mặc định nhiều distro lưu journal dưới /var/log/journal/ nếu bật persistent logging. Nếu chỉ RAM (Storage=volatile), reboot là mất log — trade-off rõ ràng cho disk nhỏ.
/usr merge và symlink: đừng hoảng khi thấy /bin → /usr/bin
Nhiều distro hiện đại dùng usr merge: /bin, /sbin, /lib là symlink tới /usr/*. Lợi ích: một filesystem root nhỏ hơn, snapshot đơn giản hơn; nhược điểm: tài liệu cũ vẫn nói “binary trong /bin” trong khi thực tế là cùng inode với /usr/bin.
ls -l /bin /sbin /lib 2>/dev/null | head
readlink -f /bin/sh
Tìm “ai đã cài file này” — không đoán mò
Debian/Ubuntu:
# File này thuộc package nào
dpkg -S /usr/bin/nginx 2>/dev/null || true
# Liệt kê file của một package
dpkg -L nginx | head
# Tìm package chứa pattern path
dpkg -S '*journald.conf*' 2>/dev/null | head
RHEL / Fedora / Rocky / Alma:
rpm -qf /usr/sbin/sshd
rpm -ql openssh-server | grep etc | head
Nếu không chắc họ distro:
command -v rpm dpkg 2>/dev/null
cat /etc/os-release
PATH và “lệnh không tìm thấy” trên server
Server thường không có PATH “đầy màu” như laptop dev. Cron, systemd Environment=, và script non-interactive có thể thiếu /usr/local/bin.
# Xem PATH của shell hiện tại
echo "$PATH"
# Xem PATH của một service cụ thể (systemd)
systemctl show ssh.service -p Environment --no-pager
Quy tắc script: dùng đường dẫn tuyệt đối cho binary quan trọng (/usr/bin/rsync) hoặc command -v ở đầu script.
/opt vs /usr/local
/usr/local: thường cho admin build tay hoặc script cài ngoài package manager./opt/vendor: pattern “một thư mục self-contained” cho phần mềm thương mại.
Cả hai đều dễ thành snowflake nếu không có playbook ghi lại phiên bản và cách nâng cấp.
Liên hệ bài trước / sau
Câu hỏi hay gặp
1. “Tôi nên đặt file cấu hình app ở /srv hay /etc?”
Nếu app là package distro hoặc có convention rõ: theo package. Nếu là app nội bộ: /etc/<app>/ cho config, /var/lib/<app>/ cho state; /srv hợp lý cho nội dung (website tree) hơn là secret.
2. “/proc có an toàn để đọc không?”
Đọc metadata (PID, argv) là bình thường; ghi vào một số sysctl qua /proc/sys thay đổi hành vi kernel — cần quyền và hiểu tác động. Đừng echo mù vào sysctl trong production.
3. “Tôi thấy /etc/rc.local — có nên dùng?”
Đây là di sản SysV. Trên systemd, hãy ưu tiên unit hoặc timer — dễ quan sát dependency, restart, và log hơn.
Bài tiếp theo trong loạt
→ Phần 3: Shell và script ops an toàn — biến kinh nghiệm “chạy được” thành script không làm sập pipeline vì một biến rỗng.