Hệ điều hành · 02/10/2026

Linux Audit thực chiến: Truy vết thay đổi file nhạy cảm với auditd

Một file cấu hình bị sửa lúc 02:13, dịch vụ khởi động lại rồi sự cố mới xuất hiện. Ai đã sửa, qua phiên đăng nhập nào, tiến trình nào thực hiện và file nào thực sự bị chạm? Timestamp của file hay shell history thường không đủ trả lời. Linux Audit kết hợp hook trong kernel, rule lọc và daemon auditd để ghi lại sự kiện có thể liên kết theo syscall, đường dẫn và danh tính đăng nhập.

Linux Audit thực chiến: Truy vết thay đổi file nhạy cảm với auditd

Một file cấu hình bị sửa lúc 02:13, dịch vụ khởi động lại rồi sự cố mới xuất hiện. Ai đã sửa, qua phiên đăng nhập nào, tiến trình nào thực hiện và file nào thực sự bị chạm? Timestamp của file hay shell history thường không đủ trả lời. Linux Audit kết hợp hook trong kernel, rule lọc và daemon auditd để ghi lại sự kiện có thể liên kết theo syscall, đường dẫn và danh tính đăng nhập.

Bài này xây dựng một cấu hình audit thực dụng cho file nhạy cảm: dùng rule bền vững trong /etc/audit/rules.d/, hiểu uid và auid, truy vấn bằng ausearch/aureport, kiểm soát log storm và bảo vệ bằng chứng điều tra. Cú pháp và hành vi được đối chiếu với Linux Audit userspace upstream, auditctl(8) và ausearch(8).

1. Linux Audit ghi nhận điều gì?

Luồng cơ bản gồm kernel audit subsystem → hàng đợi sự kiện → auditd → log cục bộ hoặc plugin chuyển tiếp. Một hành động như mở rồi ghi file có thể tạo một event gồm nhiều record:

  • SYSCALL: syscall, trạng thái thành công, PID, UID và executable.
  • PATH: đường dẫn/inode liên quan; một event có thể có nhiều PATH.
  • CWD: thư mục làm việc tại thời điểm gọi.
  • PROCTITLE: command line được mã hóa để tránh ký tự điều khiển phá log.

Các record thuộc cùng event chia sẻ timestamp và serial trong chuỗi như msg=audit(1790907180.412:8421). Đừng đọc từng dòng rời rồi kết luận; phải ghép toàn event theo ID.

Audit là telemetry điều tra, không phải cơ chế ngăn thay đổi. Quyền file, SELinux/AppArmor và least privilege mới quyết định hành động có được phép hay không.

2. Kiểm tra dịch vụ và trạng thái kernel

# Debian/Ubuntu
sudo apt install auditd audispd-plugins

# RHEL/Rocky/AlmaLinux
sudo dnf install audit

sudo systemctl enable --now auditd
sudo auditctl -s
sudo auditctl -l

auditctl -s cho biết audit có bật không, backlog hiện tại và số event lost. Nếu lost tăng, bằng chứng đã bị rơi trước khi daemon xử lý; cần xem lại backlog, tốc độ sinh sự kiện, I/O log và policy.

Nếu rule đúng mà không bắt sự kiện, kiểm tra auditctl -l có rule never,task đứng trước hay không. Theo tài liệu upstream, rule engine dùng chiến lược first match wins nên thứ tự rule có ý nghĩa.

3. Rule tạm thời và rule bền vững

Lệnh thêm trực tiếp bằng auditctl có hiệu lực ngay nhưng mất sau reboot. Nó phù hợp để thử cú pháp:

sudo auditctl -a always,exit \
  -F arch=b64 \
  -F path=/etc/ssh/sshd_config \
  -F perm=wa \
  -k ssh_config_change

Với production, tạo file có thứ tự rõ ràng:

# /etc/audit/rules.d/70-local-integrity.rules
-a always,exit -F arch=b64 -F path=/etc/ssh/sshd_config -F perm=wa -k ssh_config_change
-a always,exit -F arch=b64 -F path=/etc/sudoers -F perm=wa -k privilege_policy
-a always,exit -F arch=b64 -F dir=/etc/sudoers.d/ -F perm=wa -k privilege_policy
-a always,exit -F arch=b64 -F path=/etc/passwd -F perm=wa -k identity_change
-a always,exit -F arch=b64 -F path=/etc/shadow -F perm=wa -k identity_change
sudo augenrules --check
sudo augenrules --load
sudo auditctl -l

augenrules ghép các file *.rules theo natural sort vào /etc/audit/audit.rules. Tên bắt đầu bằng số giúp kiểm soát thứ tự: base config trước, rule nghiệp vụ sau và rule khóa policy cuối cùng.

4. Hiểu path, dir, perm và key

Thành phầnÝ nghĩaLưu ý
path=/fileTheo dõi một file cụ thểFile thường phải tồn tại khi nạp rule; kiểm tra lại quy trình replace/rename của ứng dụng
dir=/tree/Theo dõi cây thư mụcKhông tự đi xuyên sang mount point khác
perm=rReadDễ tạo lượng log rất lớn
perm=wWriteBắt các syscall có quyền ghi liên quan
perm=xExecuteHữu ích cho binary/script nhạy cảm
perm=aAttribute changeMode, owner và metadata tương tự
-k keyNhãn điều traDùng cùng key cho nhóm rule cùng mục tiêu

Cú pháp cũ -w /path -p wa -k key vẫn tồn tại để tương thích, nhưng tài liệu audit.rules khuyến nghị syscall-form với -a always,exit, arch, path/dir và perm để lọc hiệu quả hơn.

5. uid, euid và auid không giống nhau

Khi quản trị viên đăng nhập bằng tài khoản alice rồi chạy sudo vim /etc/ssh/sshd_config, tiến trình có thể mang effective UID 0. Nếu chỉ nhìn uid=0 hoặc euid=0, ta biết quyền thực thi nhưng chưa biết người khởi tạo phiên.

auid, còn gọi là login UID, được gán lúc đăng nhập và thường đi theo tiến trình qua sudo. Đây là trường quan trọng để quy hành động về phiên người dùng:

-a always,exit -F arch=b64 -F dir=/etc/ssh/ \
  -F perm=wa -F auid>=1000 -F auid!=unset \
  -k human_ssh_change

Ngưỡng tài khoản người dùng khác nhau theo hệ thống; xác nhận UID_MIN trong /etc/login.defs. Không thêm filter auid>=1000 nếu mục tiêu là bắt cả daemon, configuration management hoặc tiến trình hệ thống.

6. Chọn phạm vi theo câu hỏi điều tra

Rule tốt bắt đầu từ câu hỏi cụ thể, không phải “log mọi thứ”. Một baseline nhỏ có thể bao gồm:

  • Identity: /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow.
  • Privilege: /etc/sudoers và /etc/sudoers.d/.
  • Remote access: /etc/ssh/sshd_config và drop-in directory.
  • Service quan trọng: đúng file unit/drop-in và cấu hình ứng dụng, không quét toàn /etc theo read.
  • Binary nội bộ: execute hoặc write/attribute trên một cây triển khai xác định.

Hãy theo dõi wa trước. Chỉ thêm r khi việc đọc chính là sự kiện bảo mật cần phát hiện, vì thư viện, agent và backup có thể đọc file liên tục.

7. Kiểm thử một rule từ đầu đến cuối

# Xác nhận rule đã được kernel nạp
sudo auditctl -l | grep ssh_config_change

# Tạo một thay đổi có kiểm soát trong cửa sổ bảo trì
sudo touch /etc/ssh/sshd_config

# Tìm toàn event theo key, diễn giải UID/syscall
sudo ausearch -k ssh_config_change -ts recent -i

# Tóm tắt key nào phát sinh nhiều sự kiện
sudo aureport -k --summary -ts today

ausearch kết hợp các tùy chọn tìm kiếm theo logic AND, ngoại trừ một số trường hợp được tài liệu nêu rõ. Tùy chọn -i diễn giải ID và syscall cho dễ đọc, nhưng hãy giữ raw log khi điều tra để không mất giá trị nguyên bản.

Test cả ghi nội dung, chmod/chown, atomic replace bằng temp file + rename, xóa và tạo lại. Nhiều editor hoặc deploy tool không ghi trực tiếp vào inode cũ; chỉ test echo >> có thể bỏ sót đường thực tế.

8. Đọc một event nhiều record

sudo ausearch -k privilege_policy -ts today -i
sudo ausearch -a 8421 -i
sudo ausearch -k privilege_policy --start 02:00 --end 03:00 -i

Khi đọc kết quả, trả lời lần lượt:

  1. success=yes/no: syscall thành công hay bị từ chối?
  2. auid: phiên đăng nhập gốc thuộc ai?
  3. uid/euid: tiến trình đang chạy với quyền nào?
  4. exe, comm, proctitle: công cụ nào thực hiện?
  5. PATH, name, inode: object nào liên quan?
  6. ses, PID/PPID: có thể liên hệ với phiên và cây tiến trình nào?

Không đồng nhất comm với command line đầy đủ, và không tin một trường đơn lẻ tuyệt đối. Ghép event với authentication log, sudo log, deployment record và timeline dịch vụ.

9. Rule cho syscall cần xét kiến trúc

Trên máy hỗ trợ cả binary 64-bit và 32-bit, syscall number khác nhau theo ABI. Một rule audit failed open thường cần hai bản:

-a always,exit -F arch=b64 -S open,openat,openat2 \
  -F exit=-EACCES -k denied_access
-a always,exit -F arch=b32 -S open,openat,openat2 \
  -F exit=-EACCES -k denied_access

Chỉ thêm b32 nếu hệ thống thực sự chạy 32-bit userspace. Gom nhiều syscall vào một rule thường hiệu quả hơn nhiều rule giống filter. Kiểm tra tên syscall được kernel/audit userspace trên distribution hỗ trợ trước khi load.

10. Tránh log storm và mất sự kiện

Audit chạy trên đường syscall nên rule quá rộng có chi phí thật. Các lỗi phổ biến là theo dõi read trên cả cây lớn, audit mọi syscall, hoặc dùng nhiều rule trùng điều kiện.

sudo auditctl -s
sudo journalctl -u auditd --since today
sudo du -sh /var/log/audit
sudo grep -E '^(max_log_file|num_logs|space_left_action|admin_space_left_action|disk_full_action)' \
  /etc/audit/auditd.conf

Theo dõi lost, backlog, tốc độ event, dung lượng và thời gian truy vấn. Cấu hình rotation cùng hành động khi gần hết đĩa; lựa chọn notify, suspend hay hành động mạnh hơn phải phù hợp risk tolerance. Một policy “fail closed” thiếu kiểm thử có thể tự làm server ngừng phục vụ.

11. Rule ordering và immutable mode

Vì first match wins, một rule never đứng trước có thể triệt tiêu rule always phía sau. Dùng prefix file và review output cuối từ auditctl -l, không chỉ review từng file nguồn.

# /etc/audit/rules.d/99-finalize.rules
-e 2

-e 2 khóa cấu hình audit đến lần reboot tiếp theo. Đây là biện pháp hardening mạnh nhưng chỉ nên bật sau khi test đầy đủ: reload tiếp theo sẽ bị từ chối, kể cả khi cần sửa rule khẩn cấp. Đặt nó ở file cuối, có runbook reboot và xác minh boot loader/kernel audit settings theo yêu cầu tuân thủ.

12. Container và namespace cần diễn giải cẩn thận

Audit subsystem thuộc kernel host. Trên node container, event có thể chứa PID/UID và path theo góc nhìn khiến việc ánh xạ về pod/container khó hơn log ứng dụng. Agent bên trong container thường không có capability hoặc không nên điều khiển global audit policy.

Triển khai ở host, rồi enrich event bằng metadata runtime dựa trên thời điểm, cgroup/container ID và workload inventory. Test overlay filesystem, bind mount, volume mount và container restart; đừng giả định một path trong container xuất hiện y hệt trong PATH record của host.

13. Bảo vệ và chuyển tiếp audit log

Log chỉ hữu ích nếu còn nguyên sau sự cố. Giới hạn quyền đọc, rotation và retention hợp lý; đồng bộ thời gian; chuyển tiếp sang hệ thống khác qua cơ chế được hỗ trợ và giám sát delivery failure. Root trên một máy đã bị chiếm hoàn toàn có khả năng can thiệp dữ liệu cục bộ, nên bản sao ngoài máy làm tăng giá trị bằng chứng.

  • Không gửi raw audit log chứa dữ liệu nhạy cảm tới nơi không được phép.
  • Mã hóa đường truyền và kiểm soát quyền trên collector.
  • Giám sát khoảng trống sequence, event lost và queue của plugin.
  • Định nghĩa retention theo điều tra, pháp lý và dung lượng.
  • Kiểm thử truy xuất bản lưu trữ, không chỉ kiểm tra “đã forward”.

14. Quy trình điều tra thay đổi file

  1. Ghi nhận phạm vi thời gian, timezone, hostname và file bị ảnh hưởng.
  2. Dùng key và time window hẹp để lấy event; lưu cả raw output.
  3. Nhóm record theo audit event ID.
  4. Xác định success, auid, quyền hiệu lực, executable, PID/PPID và PATH.
  5. Đối chiếu SSH/sudo, CI/CD, configuration management và service log.
  6. Kiểm tra rule có được nạp suốt khoảng thời gian đó và lost có bằng 0 không.
  7. Bảo quản log, checksum và chuỗi bàn giao theo quy trình incident response.

Sự vắng mặt của event không tự chứng minh file không bị sửa. Rule có thể chưa tồn tại, daemon/kernel audit bị tắt, queue bị tràn, path không khớp workflow hoặc log đã hết retention.

15. Checklist triển khai production

  • Mỗi rule gắn với một câu hỏi điều tra và có key dễ tìm.
  • Dùng syscall-form với arch, path/dir và permission tối thiểu.
  • Đã xác định cần bắt người dùng, tiến trình hệ thống hay cả hai trước khi lọc auid.
  • Rule nằm trong /etc/audit/rules.d/*.rules, load thành công và hiện trong auditctl -l.
  • Đã test write, attribute, rename/replace, delete/recreate và rollback.
  • Không có rule never che khuất rule cần thiết.
  • Backlog, lost, disk action, rotation và retention được giám sát.
  • Immutable mode chỉ bật sau test và có kế hoạch reboot để thay đổi.
  • Log được chuyển tiếp/bảo vệ và có thể truy xuất khi diễn tập sự cố.
  • Dashboard/cảnh báo theo key tập trung vào tín hiệu có thể hành động.

Một policy audit tốt không phải policy dài nhất. Hãy bắt đầu từ vài file có giá trị điều tra cao, gắn key theo mục tiêu, kiểm thử đúng workflow ghi file và chứng minh hệ thống không làm rơi event. Khi đó Linux Audit mới trả lời được “ai làm gì, bằng tiến trình nào, lúc nào” thay vì chỉ tạo thêm một kho log lớn.

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.