Audit lệnh người dùng chạy trên server bằng cách nào?
Shell history không phải audit trail. So sánh sudo logging, session recording, shell hook và auditd execve, rồi chuyển log ra ngoài server trước khi bị sửa.
Điều gì thực sự ghi lại các lệnh người dùng đã chạy trên server
Để audit các lệnh người dùng đã chạy trên server, bạn cần một bản ghi mà người dùng không thể chỉnh sửa. Shell history không phải bản ghi đó. Đây chỉ là một file tiện ích, thuộc về account đã ghi nó, và bất kỳ ai có thể nhập lệnh vào shell đó đều có thể tắt hoặc xóa file.
Có 4 lớp thực sự lưu bản ghi, và mỗi lớp đều có chi phí riêng. sudo ghi một dòng cho mỗi lệnh vào syslog. sudo I/O logging ghi lại toàn bộ session của một account. Một shell hook như PROMPT_COMMAND ghi lại những gì người dùng bash tương tác đã nhập. Kernel audit subsystem ghi lại chính syscall execve, nên đây là lớp duy nhất nhìn thấy mọi process. Hướng dẫn này lần lượt đi qua các lớp đó, nêu rõ giới hạn của từng lớp, rồi kết thúc bằng yếu tố quyết định giá trị của toàn bộ cơ chế: đưa các bản ghi ra khỏi máy trước khi người bị audit có thể truy cập chúng.
Trước khi bắt đầu, cần lưu ý một điểm. Audit subsystem hoạt động trong kernel, nên không thể kiểm thử các cơ chế này bên trong container dùng chung kernel của host. Hãy chạy các lệnh này trên KVM VPS có kernel do bạn quản lý.
Vì sao shell history không phải là audit trail
~/.bash_history không đủ giá trị làm bằng chứng vì bốn lý do thông thường, và không lý do nào đòi hỏi attacker phải quá tinh vi.
Nó thuộc về user. File có mode 600 và thuộc sở hữu của account đó, nên rm ~/.bash_history hoàn toàn không cần privilege. Mở file bằng editor rồi xóa 20 dòng quan trọng cũng không cần privilege.
Nó được ghi khi shell thoát. Một session kết thúc bằng kill -9 $$ hoặc do mất kết nối sẽ không ghi gì. Chạy history -c trước exit cũng cho kết quả tương tự và khiến log trông như chưa có gì xảy ra.
Chỉ cần một từ là có thể tắt. unset HISTFILE ngăn file được ghi trong session đó. set +o history dừng việc ghi ngay lập tức. HISTCONTROL=ignorespace ẩn mọi command được nhập với một dấu cách ở đầu. Tất cả tùy chọn này nằm trong man bash vì chúng được thiết kế để user tự kiểm soát.
Nó ghi lại nội dung đã nhập, không phải nội dung đã chạy. Alias hoặc shell function có thể khiến text trong file khác với program mà kernel thực thi.
Nó cũng không có timestamp, trừ khi HISTTIMEFORMAT được thiết lập trong lúc ghi entry, vì bash chỉ ghi các dòng marker #1755043200 khi biến đó được thiết lập.
Trên một login dùng chung, nó cũng không cho biết ai đã thực hiện thao tác. Ba người dùng chung một account deploy sẽ tạo ra một file bị trộn lẫn dưới cùng một uid. Không logging layer nào có thể quy hành động cho một người cụ thể khi hai người dùng chung một uid. Đây là lý do thực tế để mỗi người dùng một account không có privilege thay vì dùng chung một login.
Shell history phù hợp với công việc thực sự của nó: giúp bạn nhập lại command của ngày hôm qua. Hãy dùng nó như một gợi ý. Không bao giờ dùng nó làm bằng chứng.
sudo ghi log gì và log dừng ở đâu
sudo ghi một dòng cho mỗi lệnh mà nó chạy vào syslog facility authpriv.
sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5Mỗi dòng ghi user, terminal, thư mục làm việc, user đích và lệnh:
sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt updateNếu /var/log/auth.log không tồn tại, rsyslog chưa được cài trên image đó và các bản ghi tương tự chỉ có trong journal. Kiểm tra journal không ở chế độ volatile trước khi dựa vào nó:
journalctl --list-bootsChỉ có boot hiện tại được liệt kê nghĩa là /var/log/journal không tồn tại, nên journal nằm trong /run và mọi dòng log sẽ mất sau lần reboot tiếp theo. Bật lưu trữ persistent:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journaldTiếp theo là giới hạn. sudo ghi log lệnh mà nó được yêu cầu chạy. Nó không ghi log những gì lệnh đó thực hiện sau đó. Vì vậy, một dòng sẽ chấm dứt dấu vết:
sudo -iLog chỉ có một bản ghi cho shell. Mọi lệnh được nhập bên trong root shell đó đều không xuất hiện trong log của sudo, vì sudo không còn nằm trên đường thực thi. sudo su -, sudo bash và sudo vim /etc/shadow tiếp theo là :!bash đều có cùng dạng này. Một rule trong sudoers cho phép bất kỳ program nào có shell escape, chẳng hạn vim hoặc find, thực chất là rule cấp root không được log. Hãy đọc xem account thực sự có thể truy cập đến đâu trước khi tin vào các dòng log của nó:
sudo -l -U aliceGhi lại toàn bộ phiên làm việc của một tài khoản
Trước tiên, hãy xác định bạn đang dùng sudo nào, vì tính năng này không tồn tại trong bản viết lại bằng Rust:
sudo --version | head -1Nếu kết quả hiển thị sudo-rs, hãy bỏ qua phần này và dùng audit subsystem. Tài liệu chính thức của Ubuntu cho các bản phát hành 25.10 và 26.04 liệt kê việc ghi log I/O và sudoreplay là chưa được hỗ trợ; đến tháng 8 năm 2026 điều này vẫn không thay đổi. Điều này quan trọng vì sudo-rs là sudo mặc định trên các bản phát hành đó, nên một lần nâng cấp có thể loại bỏ một cơ chế kiểm soát mà bạn tưởng là vẫn có. Danh sách đầy đủ các thay đổi về hành vi của sudo-rs đáng đọc trước khi bạn lập kế hoạch ghi log dựa trên sudo.
Với sudo gốc, phiên bản vẫn được Ubuntu 24.04 LTS cung cấp, hãy bật ghi log I/O cho một tài khoản:
sudo visudo -f /etc/sudoers.d/iologDefaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_outputHãy dùng visudo thay vì editor, vì lệnh này không cho lưu file nếu nội dung không parse được. File sudoers bị hỏng sẽ khiến mọi người không thể dùng sudo. Sau đó, phát lại một phiên:
sudo sudoreplay -l user=deploy
sudo sudoreplay 000001sudoreplay -l liệt kê các phiên cùng ID của chúng và không in gì nếu log_output chưa từng được áp dụng cho người dùng đó. Chi phí là mọi byte đi qua terminal đều được lưu trong /var/log/sudo-io, nên một phiên có nhiều output sẽ tạo ra file lớn. Dòng sudoers thứ hai ngăn việc phát lại phiên tự ghi lại chính nó. Chi phí thực sự nằm ở secret, vì I/O log chứa mọi thứ đã được nhập và in ra, bao gồm cả password được nhập vào prompt bên trong phiên. Vì vậy, file này cần được bảo vệ như password store. Phạm vi ghi log cũng hẹp. Nó chỉ thấy các lệnh chạy qua sudo. Người đăng nhập và làm việc hoàn toàn với tài khoản của chính mình sẽ không được ghi lại.
Shell hook và chính xác cách chúng bị bypass
Cách thiết lập thường được truyền tay để “ghi log mọi lệnh” là đặt một hook PROMPT_COMMAND vào /etc/profile.d/:
# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'bash chạy PROMPT_COMMAND trước khi hiển thị mỗi prompt, nên dòng lệnh được ghi vào syslog ngay khi người dùng nhập thay vì chờ đến lúc thoát shell. logger ghi thông qua system log daemon, nên quyền trên file của chính người dùng không ảnh hưởng đến việc này. Mở một login shell mới rồi kiểm tra bằng sudo tail -f /var/log/syslog, hoặc dùng journalctl -t cmdlog -f trên image không có rsyslog.
Sau đó cơ chế này sẽ ngừng hoạt động theo 5 cách sau. Bạn có thể tự tái hiện từng cách trong vòng 1 phút.
- Shell không tương tác không hiển thị prompt.
ssh you@server 'id'chạy lệnh rồi thoát, nên không có gì được ghi log vìPROMPT_COMMANDchưa bao giờ được đánh giá. - Đây là một biến.
unset PROMPT_COMMANDsẽ vô hiệu hóa nó trong phần còn lại của session và không cần privilege. - File này được login shell đọc.
bash --noprofile --norchoàn toàn không source/etc/profile.d/. - Cơ chế này chỉ dành riêng cho bash.
zsh,sh,python3 -c 'import os; os.system("id")'và:!idbên trongvimđều chạy các chương trình mà không hook prompt nào của bash có thể nhìn thấy. - Nó ghi lại dòng lệnh người dùng đã nhập, nên alias hoặc function vẫn che khuất lệnh thực sự được chạy.
Hãy dùng shell hook như một tiện ích. Nó có thể trả lời câu hỏi “Thứ Ba tuần trước tôi đã chạy lệnh gì” với những người dùng hợp tác. Đừng để một checklist xem nó là một biện pháp kiểm soát.
The kernel audit subsystem sees every execve
The Linux audit subsystem, driven by the auditd daemon, is the only layer here that a user cannot step around, because the record is made inside the kernel at the moment the syscall runs. If a process executes a program, there is an event. The shell, the language and the presence of a terminal make no difference.
sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -sauditctl -s prints the daemon state. enabled 1 with a non-zero pid means it is running, and lost 0 means no records have been dropped yet. Remember that lost counter, it comes back later.
auid is the field that makes audit worth the trouble. PAM sets a login uid when a session starts, and the kernel carries it on every child process from then on. Check yours:
cat /proc/self/loginuidAn interactive SSH session prints your uid, because /etc/pam.d/sshd includes pam_loginuid.so. A value of 4294967295 means the loginuid was never set, which is normal for a process started by a system daemon at boot. The important part is that sudo -i does not change it: a root shell opened by alice still carries auid 1000, so every command inside it is attributable to alice. That is exactly the gap sudo leaves open. Changing a loginuid once set needs CAP_AUDIT_CONTROL, which ordinary users do not have, and sudo auditctl --loginuid-immutable closes it for root as well until the next reboot.
Check that /etc/pam.d/sshd, /etc/pam.d/login and /etc/pam.d/cron each include pam_loginuid.so, or events will arrive with nobody attached to them. That is the same file list you touch when hardening SSH access on a VPS, so do the two jobs together.
Bộ rule khởi đầu cho auditd
Các rule nằm trong /etc/audit/rules.d/*.rules. augenrules nối chúng theo thứ tự tên file thành một danh sách duy nhất. Thứ tự quyết định hành vi vì kernel dừng ở rule khớp đầu tiên. Hãy đọc các rule hiện có trước khi thêm gì, vì một -D trong file đứng sau sẽ xóa mọi thứ đã được nạp trước đó.
ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rulesSau đó tạo /etc/audit/rules.d/50-exec.rules:
## Suppressions first: the kernel takes the first matching rule.
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-deb
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-query
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-split
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-trigger
## Every program started by a logged-in human.
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
-a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
## Changes to who may become root.
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
## Changes to the audit configuration itself.
-w /etc/audit/ -p wa -k auditconfigNạp rule và xác nhận:
sudo augenrules --load
sudo auditctl -lauditctl -l in lại các rule nghĩa là chúng đã hoạt động. No rules nghĩa là quá trình nạp thất bại. journalctl -u auditd -n 20 cho biết file và dòng mà parser từ chối. audit userspace cũ không hiểu keyword unset. Nếu loader báo lỗi với trường đó, hãy viết -F auid!=4294967295, đây là cùng giá trị nhưng được viết đầy đủ.
Bây giờ đọc lại các event:
sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i-i chuyển uid và số syscall thành tên. Trong thực tế, tùy chọn này không thể bỏ qua. -ts recent lấy các event trong 10 phút gần nhất. Mỗi lần thực thi tạo thành một nhóm record: record SYSCALL chứa uid, auid, exit status và key; record EXECVE chứa đầy đủ danh sách đối số; cùng với các record CWD và PATH cung cấp context.
Có một giới hạn cần nói rõ vì nó thường gây nhầm lẫn. audit ghi lại syscall, còn shell builtin không tự tạo syscall nào. cd /root không chạy chương trình nào. echo evil >> /etc/passwd được nhập tại bash prompt cũng không chạy chương trình nào, vì cả echo và thao tác redirect đều diễn ra bên trong shell process đang chạy. Vì vậy, các rule execve theo dõi chương trình, còn các rule -w theo dõi thao tác ghi. Không rule nào đủ nếu chỉ dùng riêng.
Cuối cùng, khóa cấu hình:
## /etc/audit/rules.d/99-finalize.rules
-e 2-e 2 khiến bộ rule trở thành immutable cho đến lần reboot tiếp theo. Sau khi nạp, auditctl -s trả về enabled 2, và mọi nỗ lực thêm hoặc xóa rule đều thất bại với Operation not permitted, kể cả khi chạy bằng root. Hãy thêm file này sau cùng và luôn dự kiến phải reboot mỗi khi muốn thay đổi rule. Đó chính là mục đích của đánh đổi này: một bộ rule mà bất kỳ ai cũng có thể âm thầm tắt không thể dùng làm bằng chứng.
Một audit log không ai đọc chỉ là hiện vật để đối phó compliance
auditd không thất bại vì bỏ sót sự kiện. Vấn đề là nó ghi quá nhiều đến mức không ai xem, rồi log chỉ còn tồn tại để đáp ứng checklist thay vì trả lời một câu hỏi cụ thể.
Hãy tự tính trên máy của bạn trước khi tinh chỉnh bất cứ thứ gì:
sudo aureport -k --summary -i
sudo du -sh /var/log/auditMột sudo apt upgrade duy nhất chạy hàng nghìn process có vòng đời ngắn, và mỗi process đều mang theo auid của bạn. Vì vậy, một lần cập nhật package có thể tạo ra nhiều log hơn cả một tuần thao tác thủ công. Đó là lý do các quy tắc suppress ở trên nêu rõ dpkg và các helper của nó. Hãy suppress theo executable, không theo user: exclusion cho /usr/bin/dpkg là một lỗ hổng mà bạn có thể mô tả trong một câu, còn exclusion cho một account là lỗ hổng có hình dạng đúng bằng thứ bạn đang cố phát hiện.
Key -k trên mỗi rule giúp log có thể tìm kiếm được sau một tháng. ausearch -k sudoers là một câu hỏi có câu trả lời. ausearch không có filter chỉ là một bức tường văn bản khiến bạn dần ngừng đọc. Nếu collector của bạn cần JSON thay vì format native, laurel là một plugin auditd chuyển mỗi event thành một JSON object với các argument đã được giải mã. Plugin này được đăng ký trong /etc/audit/plugins.d/ như mọi plugin khác, và auditd sẽ nhận các thay đổi plugin khi sudo pkill -HUP auditd.
Chi phí thực tế của auditd
Mỗi syscall khớp với rule sẽ trở thành một record mà kernel định dạng rồi chuyển cho userspace. Chi phí phát sinh ở 2 nơi. Bạn có thể đo cả 2 trên workload của chính mình, thay vì đoán từ một con số do người khác công bố.
- CPU và độ trễ. Máy thường xuyên fork, build host hoặc CI runner sẽ tạo một record cho mỗi lần exec. Khi backlog của kernel đầy,
--backlog_wait_timekhiến kernel tạm dừng process tạo ra event cho đến khi có chỗ trống. Vì vậy audit có thể biểu hiện thành build chậm, thay vì một tỷ lệ CPU cụ thể. Hãy theo dõibacklogvàlosttrongsudo auditctl -skhi hệ thống đang chịu tải thực tế.losttăng nghĩa là record đã bị drop. Một log có những khoảng trống không được báo hiệu còn tệ hơn không có log, vì bạn vẫn sẽ tin vào nó. - Disk. Đọc
/etc/audit/auditd.confvà chủ động quyết định điều gì xảy ra khi disk đầy, vì các giá trị mặc định đi kèm chỉ là các lựa chọn có sẵn.max_log_file,num_logsvàmax_log_file_actionkiểm soát việc rotation.space_left_action,admin_space_left_actionvàdisk_full_actionkiểm soát tình huống khẩn cấp. Một số action có sẵn, trong đó cóhaltvàsingle, sẽ tắt máy thay vì làm mất một record.
Dòng -f trong /etc/audit/rules.d/audit.rules thể hiện chính quyết định đó ở cấp kernel: -f 1 báo lỗi audit cho syslog, còn -f 2 làm kernel panic. Chỉ chọn 2 nếu bạn thực sự muốn mất cả server hơn là mất một record. Với VPS đang chạy dịch vụ mà người khác phụ thuộc vào, hãy dùng rotation và chuyển việc xử lý disk sang một hệ thống khác.
Đẩy log ra khỏi máy, gần như theo thời gian thực
Đây là điểm mà các báo cáo xử lý sự cố liên tục chứng minh. Log nằm trên host đã bị xâm nhập có thể bị kẻ xâm nhập chỉnh sửa. root có thể ghi đè /var/log/auth.log, xóa /var/log/audit/audit.log và dừng daemon. -e 2 ngăn các rule bị unload. Nó không bảo vệ rm. Mọi lớp phía trên chỉ tạo ra bằng chứng nếu trước tiên có một bản sao rời khỏi máy.
Cơ chế transport riêng của audit là plugin audisp-remote từ audispd-plugins. Bật plugin này trong /etc/audit/plugins.d/au-remote.conf:
active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = stringKiểm tra path với command -v audisp-remote trước khi reload, vì sai path sẽ không tạo ra gì ngoài một dòng trong journal. Đặt remote_server và port trong /etc/audit/audisp-remote.conf, đồng thời trên collector đặt tcp_listen_port = 60 trong auditd.conf riêng của nó. Reload bằng sudo pkill -HUP auditd. Trên nhiều image, systemctl restart auditd bị từ chối vì unit file đặt RefuseManualStop=yes, nên signal là cách đáng tin cậy.
Tùy chọn còn lại đưa audit vào luồng syslog mà bạn đã forward sẵn. /etc/audit/plugins.d/syslog.conf đi kèm active = no. Đặt thành yes rồi reload; các event audit sẽ được ghi chung với các dòng của sudo và mọi nội dung khác. Sau đó forward toàn bộ bằng rsyslog qua TLS (transport layer security); cách này cần package rsyslog-gnutls:
# /etc/rsyslog.d/60-forward.conf
*.* action(type="omfwd"
target="logs.example.net" port="6514" protocol="tcp"
StreamDriver="gtls" StreamDriverMode="1"
StreamDriverAuthMode="x509/name"
StreamDriverPermittedPeers="logs.example.net"
action.resumeRetryCount="-1"
queue.type="linkedList" queue.filename="fwd" queue.saveOnShutdown="on")Phần đáng chú ý là các thiết lập queue. action.resumeRetryCount="-1" retry vô hạn. Disk-assisted queue với queue.saveOnShutdown="on" giữ các record khi collector không thể truy cập, rồi gửi lại khi collector hoạt động. Nếu thiếu hai thiết lập này, collector reboot sẽ tạo ra một khoảng trống trong bằng chứng và không có gì cho bạn biết khoảng trống đó tồn tại. Áp dụng bằng sudo systemctl restart rsyslog, rồi xác nhận record thực sự đến collector trước khi tin cậy toàn bộ cấu hình.
Còn một vòng cần khép lại: collector phải là máy mà những người bị audit không thể đăng nhập. Nếu cùng một nhóm admin có root trên log server, bạn chỉ sao chép file chứ chưa bảo vệ nó. Dùng credential riêng, key riêng và tốt nhất là account riêng của provider. Đây cũng là lý do xây dựng cách quản lý tập trung nhiều máy chủ Linux đáng làm trước khi cần đến, đồng thời tạo ra khác biệt giữa một giờ đầu hữu ích và vô ích khi xử lý một VPS đã bị xâm nhập.
Kiểm tra rằng user thông thường không thể sửa bản ghi
Hãy kiểm tra khẳng định này thay vì mặc định tin rằng nó đúng. Từ một account thông thường, không dùng sudo:
echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nGKết quả mong đợi theo thứ tự: Permission denied, vì auth.log thuộc sở hữu của syslog, có group adm và mode 640; tiếp theo là Permission denied, vì audit log có mode 600 và thuộc sở hữu của root; một lỗi từ chối chạy, vì thay đổi audit rule cần CAP_AUDIT_CONTROL; và danh sách group không chứa adm hoặc systemd-journal.
Đây là bước cuối cùng mà nhiều người kiểm tra không đúng. Membership của adm cấp quyền đọc /var/log/auth.log, còn membership của systemd-journal cấp quyền đọc toàn bộ journal. Không group nào cấp quyền ghi, nên không group nào cho phép sửa log. Cả hai đều cho phép người dùng đọc mọi dòng xác thực trên máy. Đây phải là một quyết định có chủ đích, không phải thứ được sao chép từ một dòng usermod -aG trong câu trả lời trên forum.
Cuối cùng, xác nhận hai điều phải được giữ lại sau khi reboot:
sudo auditctl -s
systemctl is-enabled auditdenabled 2 có nghĩa là bộ rule bị khóa cho đến lần boot tiếp theo. enabled từ lệnh thứ hai cho biết auditd sẽ khởi động lại sau lần boot đó. Một bộ rule chỉ tồn tại đến lần kernel update tiếp theo cũng không phải là audit trail.
FAQ
Làm thế nào để xem mọi lệnh mà một user cụ thể đã chạy?
Tìm uid của user đó bằng id -u alice, rồi tìm trong audit log theo login uid: sudo ausearch -ul 1000 -ts today -i. Thêm -k exec để giới hạn kết quả vào rule execve. Login uid được thiết lập khi đăng nhập và giữ nguyên qua su và sudo -i, nên cách này bắt được cả các lệnh chạy bên trong root shell mà user đó đã mở. Cách này chỉ hoạt động với các lệnh được thực thi sau khi rule được nạp, vì audit không lưu lịch sử của những event mà nó chưa được cấu hình để ghi lại. sudo aureport -k --summary -i cung cấp số lượng theo từng rule nếu bạn muốn xem trước cấu trúc dữ liệu.
User có thể xóa bash history để che giấu các lệnh đã chạy không?
Có, và không cần privilege. ~/.bash_history thuộc sở hữu của user đó với mode 600, nên user có thể sửa, truncate hoặc xóa file này. User cũng có thể ngăn file được ghi bằng unset HISTFILE, dừng việc ghi giữa session bằng set +o history, hoặc ẩn từng lệnh bằng cách thêm một khoảng trắng ở đầu lệnh khi HISTCONTROL=ignorespace được thiết lập. Bash ghi file khi shell thoát, nên một session bị kill bằng kill -9 $$ sẽ không ghi lại gì. Hãy xem shell history là manh mối, không phải bằng chứng.
sudo có log những gì xảy ra bên trong sudo -i không?
Không. sudo log lệnh mà nó được yêu cầu chạy, nên sudo -i chỉ tạo một dòng log cho shell và không ghi gì sau đó. Mọi lệnh được nhập trong root shell đó đều không xuất hiện trong sudo, vì sudo không còn tham gia vào quá trình này. sudo su -, sudo bash và mọi program được cho phép có shell escape cũng hoạt động như vậy. Có 2 cách để khắc phục khoảng trống này: đặt audit rule trên execve để ghi lại mọi program cùng login uid ban đầu, và dùng rule trong sudoers không cấp shell ngay từ đầu.
auditd có làm server chậm đi không?
Điều đó hoàn toàn phụ thuộc vào số lượng process mà workload của bạn khởi chạy, nên hãy đo thay vì tin vào một con số cố định. Một server chủ yếu xử lý request sẽ thực thi rất ít process và hầu như không nhận thấy ảnh hưởng. Build host hoặc CI runner thường xuyên thực thi process nên có thể bị ảnh hưởng đáng kể, vì khi audit backlog của kernel đầy, process tạo ra event sẽ bị tạm dừng cho đến khi có chỗ trống. Chạy sudo auditctl -s dưới tải thực tế và theo dõi backlog cùng lost. Bất kỳ lost nào lớn hơn 0 đều có nghĩa là record đã bị mất. Đây là kết quả nghiêm trọng nhất vì log lúc này có những khoảng trống không thể nhìn thấy.
Nên lưu audit log ở đâu?
Trên một máy khác, với độ trễ tính bằng giây. Bất kỳ ai có được root trên host đang được audit đều có thể xóa /var/log/audit/audit.log và sửa lại /var/log/auth.log, nên bản sao local chỉ trả lời được các câu hỏi về những incident mà không ai cố che giấu. Hãy forward bằng plugin audisp-remote đến một auditd tập trung, hoặc bật audit syslog plugin rồi forward toàn bộ syslog stream bằng rsyslog qua TLS. Cấp credential riêng cho collector và bảo đảm các account đang được audit không có quyền truy cập vào collector.