Làm chủ Linux Audit System (auditd) trên Fedora: Giám sát tệp nhạy cảm và theo dõi hành vi người dùng theo chuẩn bảo mật

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

Tháng 7 năm ngoái, mình phát hiện file /etc/sudoers trên server staging bị sửa. Không có thông báo, không có email, không có gì cả — chỉ là một buổi chiều deploy bỗng dưng lỗi permission. Mất gần 2 tiếng trace ngược lại mới biết ai đã thay đổi, khi nào, và từ terminal nào. Từ đó mình bắt đầu nghiêm túc với auditd.

Vấn đề thực tế: Khi syslog không đủ để trả lời “Ai đã làm điều đó?”

Mình dùng Fedora làm máy development chính đã 2 năm và khá hài lòng với tốc độ cập nhật package. Nhưng khi đưa Fedora Server lên production, mình nhanh chóng nhận ra journald và syslog không được thiết kế để trả lời các câu hỏi kiểu:

  • File /etc/passwd bị đọc bởi tiến trình nào lúc 3 giờ sáng?
  • Ai đã sudo lệnh gì vào hôm qua?
  • File binary /usr/bin/python3 có bị thay thế không?

Journald ghi log theo service, không theo file. Bạn có thể biết SSH daemon đã kết nối, nhưng không biết người dùng đó sau đó đã cat /etc/shadow hay chưa. Đây là khoảng mù nguy hiểm — đặc biệt khi cần chứng minh compliance theo CIS Benchmark hoặc STIG.

SELinux xử lý kiểm soát truy cập, còn auditd xử lý ghi lại bằng chứng — hai thứ khác nhau hoàn toàn, bổ sung cho nhau chứ không thay thế nhau.

Phân tích nguyên nhân: Tại sao cần audit ở tầng kernel?

Linux Audit System hoạt động qua Linux Audit Framework — một subsystem tích hợp sẵn vào kernel từ phiên bản 2.6. Khác với syslog chỉ ghi những gì ứng dụng chủ động report, audit hook trực tiếp vào các syscall:

  • open(), read(), write() — đọc/ghi file
  • execve() — thực thi lệnh
  • setuid(), setgid() — thay đổi quyền

Vì hook ở mức syscall, không có cách nào bypass — kể cả root cũng không thể thực hiện thao tác mà không để lại dấu vết, miễn là auditd đang chạy và quy tắc cấu hình đúng.

Trên Fedora, auditd thường được cài sẵn. Nếu chưa có:

sudo dnf install audit audit-libs -y
sudo systemctl enable --now auditd

# Kiểm tra trạng thái
sudo auditctl -s

Các cách giải quyết: Từ ad-hoc đến production-grade

Cách 1: Dùng auditctl thêm quy tắc tạm thời

Nếu chỉ cần debug nhanh, auditctl cho phép thêm quy tắc ngay lập tức mà không cần restart service:

# Giám sát mọi thao tác ghi với /etc/passwd
sudo auditctl -w /etc/passwd -p wa -k passwd_watch

# Xem quy tắc đang active
sudo auditctl -l

# Xóa tất cả quy tắc tạm
sudo auditctl -D

Flags -p wa: giám sát write (w) và attribute change (a — chmod, chown). Key -k passwd_watch là label để lọc log sau này.

Giới hạn: Quy tắc mất sau reboot. Chỉ dùng được cho debug, không phù hợp production.

Cách 2: Quy tắc persistent trong /etc/audit/rules.d/

Fedora load quy tắc persistent từ /etc/audit/rules.d/ theo thứ tự alphabetical khi auditd khởi động. Mình chia nhỏ theo chức năng để dễ quản lý:

sudo nano /etc/audit/rules.d/10-identity.rules
## Giám sát các file định danh người dùng
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity

## Giám sát sudoers
-w /etc/sudoers -p wa -k sudoers_change
-w /etc/sudoers.d/ -p wa -k sudoers_change

## SSH config
-w /etc/ssh/sshd_config -p wa -k sshd_config
sudo nano /etc/audit/rules.d/20-priv-commands.rules
## Theo dõi lệnh đặc quyền của user thực (auid >= 1000, loại tiến trình kernel)
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k priv_cmd
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k priv_cmd
-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=4294967295 -k priv_cmd

## Giám sát thay đổi kernel module (dấu hiệu rootkit)
-w /sbin/insmod -p x -k module_insertion
-w /sbin/rmmod -p x -k module_insertion
-w /sbin/modprobe -p x -k module_insertion

Sau khi viết xong, kiểm tra syntax và reload:

sudo augenrules --check
sudo augenrules --load

# Trên Fedora: KHÔNG dùng systemctl restart auditd
# auditd có cách xử lý signal riêng — dùng lệnh này thay thế:
sudo service auditd restart

Cách 3: Dùng preset SCAP/STIG cho compliance

Nếu cần đáp ứng compliance, không cần viết tay từ đầu. Fedora hỗ trợ OpenSCAP:

sudo dnf install openscap-scanner scap-security-guide -y

# Xem danh sách profile
sudo oscap info /usr/share/xml/scap/ssg/content/ssg-fedora-ds.xml | grep profile

# Scan trước (dry-run, không thay đổi hệ thống)
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_ospp \
  --results /tmp/scan-results.xml \
  /usr/share/xml/scap/ssg/content/ssg-fedora-ds.xml

Profile OSPP sẽ sinh ra toàn bộ quy tắc audit theo chuẩn. Nhược điểm: nhiều quy tắc hơn mức cần thiết, có thể làm audit log phình nhanh nếu không điều chỉnh.

Cách tốt nhất: Ruleset tối giản + phân tích log hiệu quả

Sau 6 tháng production, mình thấy cách tiếp cận hiệu quả nhất là: bắt đầu tối giản, mở rộng dựa trên nhu cầu thực tế. Quy tắc quá nhiều → log ngập → không ai đọc → vô nghĩa.

Thêm file base để kiểm soát buffer:

sudo nano /etc/audit/rules.d/00-base.rules
## Xóa quy tắc cũ
-D

## Buffer size (tăng nếu thấy audit: backlog limit exceeded trong dmesg)
-b 8192

## Failure mode: 1=log via printk, 2=kernel panic (dùng 2 chỉ khi strict compliance)
-f 1

Cấu hình rotation trong /etc/audit/auditd.conf để log không ăn hết disk:

max_log_file = 50          # MB mỗi file
num_logs = 10              # Giữ 10 file rotate (~500MB tổng)
max_log_file_action = ROTATE
space_left = 500           # Cảnh báo khi còn 500MB disk
space_left_action = SYSLOG
admin_space_left = 50
admin_space_left_action = SUSPEND  # Dừng audit khi sắp hết disk

Phân tích log với ausearch và aureport

Log thô ở /var/log/audit/audit.log không phải cho người thường đọc. Dùng công cụ đi kèm:

# Tìm tất cả sự kiện liên quan đến key "identity" hôm nay
sudo ausearch -k identity --start today

# Tìm tất cả lệnh sudo của user alice (flag -i để hiện username thay vì UID)
sudo ausearch -k priv_cmd --uid alice -i

# Xem ai đã đọc/ghi /etc/shadow trong tháng này
sudo ausearch -f /etc/shadow --start this-month -i

# Báo cáo tóm tắt toàn bộ
sudo aureport --summary

# Báo cáo authentication (login/logout/sudo)
sudo aureport -au

# Chỉ những lần thất bại
sudo aureport --failed -au

Một trick mình hay dùng khi điều tra: kết hợp ausearch với --raw rồi pipe vào audisp để xem full context của một event:

# Xem event theo event ID cụ thể
sudo ausearch -a 1234567 -i

# Export ra file để phân tích offline
sudo ausearch -k sudoers_change --start last-week > /tmp/sudoers-audit.txt

Những điều học được sau 6 tháng thực tế

Thứ nhất, filter auid!=4294967295 (giá trị unset, nghĩa là tiến trình khởi chạy bởi kernel trước khi user login) rất quan trọng. Nếu không filter, log đầy event từ systemd services không liên quan, khó tìm thứ cần thiết.

Thứ hai, đừng bật -e 2 (immutable mode) cho đến khi chắc chắn ruleset đúng. Chế độ này khóa audit config — chỉ reboot mới gỡ được. Mình đã từng mất 20 phút vì thêm dòng đó quá sớm.

Thứ ba, kết hợp auditd với logwatch hoặc một SIEM đơn giản để nhận daily report qua email. Có log mà không đọc thì cũng như không có. Lệnh này chạy daily qua cron làm được việc tạm:

## Thêm vào crontab: gửi báo cáo audit lúc 7 giờ sáng
0 7 * * * /usr/sbin/aureport --summary | mail -s "[Audit Report] $(hostname) $(date +%F)" [email protected]

Nếu đang quản trị Fedora Server mà chưa cấu hình auditd, đây là thứ nên làm trước khi hardening SSH hay firewall rules — vì không có audit log, bạn sẽ không bao giờ biết liệu các biện pháp bảo mật kia có thực sự hoạt động hay không, và quan trọng hơn, không có bằng chứng để điều tra khi sự cố xảy ra.

Share: