在多用戶共享的 Linux 服務器上,事後追溯「誰在什麼時間、從哪個 IP、執行了什麼命令」是安全合規與故障定位的剛需。本文提供一種**零依賴、零侵入、全覆蓋**的方案:修改 /etc/profile 注入審計邏輯,自動將每個登錄會話的歷史命令寫入獨立文件,文件名包含用戶名、客戶端 IP、登錄時間戳,配合 HISTSIZE/HISTTIMEFORMAT 實現完整審計軌跡。
/etc/profile:所有交互式登錄 Shell (SSH、Console、su -) **必讀**的全局啟動腳本。HISTFILE:指定歷史命令保存文件路徑。動態設置為含 IP/時間戳的唯一路徑,實現**會話級隔離**。who -u am i:獲取**當前會話**的客戶端 IP (遠程) 或主機名 (本地)。PROMPT_COMMAND:每次命令執行前追加寫入歷史 (可選,增強實時性)。
# ===== 用戶操作審計開始 =====
# 僅對交互式 Shell 生效 (排除 scp/sftp/非登錄腳本)
if [ -n "$PS1" ] && [ -z "$AUDIT_INITIALIZED" ]; then
export AUDIT_INITIALIZED=1 # 防止嵌套 Shell 重複初始化
# 1. 解析客戶端 IP / 主機名
USER_IP=$(who -u am i 2>/dev/null | awk '{print $NF}' | sed -e 's/[()]//g')
if [ -z "$USER_IP" ]; then
USER_IP=$(hostname) # 本地 Console 登錄無 IP,用主機名
fi
# 2. 構建審計目錄結構:/var/log/user_audit//
AUDIT_BASE_DIR="/var/log/user_audit"
AUDIT_USER_DIR="${AUDIT_BASE_DIR}/${LOGNAME}"
if [ ! -d "$AUDIT_USER_DIR" ]; then
mkdir -p "$AUDIT_USER_DIR"
chmod 700 "$AUDIT_USER_DIR" # 僅用戶可讀寫,防止橫向竊取
fi
# 3. 生成唯一審計文件名:IP_用戶名_YYYYMMDD_HHMMSS.hist
TIMESTAMP=$(date "+%Y%m%d_%H%M%S")
AUDIT_FILE="${AUDIT_USER_DIR}/${USER_IP}_${LOGNAME}_${TIMESTAMP}.hist"
# 4. 設置歷史參數
export HISTSIZE=10000 # 內存中保留命令數
export HISTFILESIZE=100000 # 文件最大行數
export HISTTIMEFORMAT="%F %T " # 歷史命令前綴時間戳 (history 顯示)
export HISTCONTROL=ignoredups:erasedups # 去重
export HISTIGNORE="history*:pwd:ls:cd:clear:exit" # 忽略高頻無價值命令 (可選)
export HISTFILE="$AUDIT_FILE" # **核心:指定專屬審計文件**
# 5. 確保文件存在並權限正確
touch "$AUDIT_FILE"
chmod 600 "$AUDIT_FILE"
# 6. 可選:實時追加模式 (每條命令即時寫入,防止異常退出丟失)
# 注意:高頻交互會增加磁盤 IO,權衡啟用
# export PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}"
# 7. 登錄審計記錄 (可選,寫入系統日志或專用審計日志)
logger -t USER_AUDIT "LOGIN user=${LOGNAME} ip=${USER_IP} tty=$(tty) pid=$$ audit_file=${AUDIT_FILE}"
fi
# ===== 用戶操作審計結束 =====
| 配置項 | 作用 | 推薦值/說明 |
|---|---|---|
AUDIT_INITIALIZED | 防止 su - user、bash 嵌套時重複初始化、覆蓋 HISTFILE | 導出變量標記 |
who -u am i | 精確獲取**當前會話**來源,排除 who 列出的其他會話 | awk '{print $NF}' 取最後一欄 (IP:port 或 :0),sed 去括號 |
/var/log/user_audit | 集中存儲,便於備份、日志收集 (Filebeat/Logstash/Fluentd) | 權限 root:root 755,子目錄 user:user 700 |
HISTTIMEFORMAT | 賦予 history 命令輸出時間戳,格式含空格結尾 | %F %T (ISO 日期時間 + 兩空格) |
HISTCONTROL | ignoredups 忽略連續重複,erasedups 刪除歷史中所有重複 | 減少噪音 |
PROMPT_COMMAND | 每次提示符前執行 history -a 追加寫入文件 | 高安全場景啟用,一般場景可不啟用 (Shell 正常退出自動寫入) |
# 1. 創建基礎目錄並設置權限 (root 執行)
mkdir -p /var/log/user_audit
chown root:root /var/log/user_audit
chmod 755 /var/log/user_audit
# 2. 編輯 /etc/profile (在文件末尾添加上述代碼段)
vim /etc/profile
# 3. 立即生效 (新登錄會話自動生效,當前會話需 source)
source /etc/profile
# 4. 可選:限制用戶刪除/篡改審計文件 (chattr +a 追加-only,極高安全)
# 注意:chattr +a 後 root 也無法刪除,需 chattr -a 才能清理
# chattr +a /var/log/user_audit/*/*.hist
cat /var/log/user_audit/zhangsan/192.168.1.50_zhangsan_20240630_143000.hist
# 輸出示例:
# 1001 2024-06-30 14:30:05 cd /var/www/html
# 1002 2024-06-30 14:30:12 vim index.php
# 1003 2024-06-30 14:35:47 systemctl restart nginx
grep -r "rm -rf" /var/log/user_audit/
grep -r "chmod 777" /var/log/user_audit/
ls -1 /var/log/user_audit/zhangsan/ | wc -l
ls -1 /var/log/user_audit/zhangsan/ | cut -d'_' -f1 | sort | uniq -c | sort -nr
paths: ["/var/log/user_audit/*/*.hist"],multiline.pattern: '^\s+\d+' 合併多行命令。user, ip, timestamp, command,構建審計儀表板。| 局限 | 補充方案 |
|---|---|
用戶可修改 HISTFILE/unset HISTFILE 繞過 | 系統級審計:auditd 監控 execve 系統調用,內核級不可繞過;或 sysdig/falco 容器運行時安全。 |
| 非交互式腳本/自動化任務不記錄 | 在腳本中手動 logger -t AUTO_TASK "cmd=..." 或使用 process accounting (acct)。 |
| 歷史文件僅記錄命令字符串,無環境變量/參數展開/退出碼 | 結合 auditd 記錄 argv/envp/exit code。 |
| 用戶刪除文件 (權限 600 僅防橫向,不防縱向) | chattr +a 追加鎖定;定時備份到異地存儲 (S3/NFS/日志平台)。 |
# 1. 安裝 auditd
yum install -y audit audit-libs
# 2. 添加規則 (監控所有用戶 execve)
auditctl -a always,exit -F arch=b64 -S execve -k user_commands
auditctl -a always,exit -F arch=b32 -S execve -k user_commands
# 3. 持久化
echo "-a always,exit -F arch=b64 -S execve -k user_commands" >> /etc/audit/rules.d/audit.rules
echo "-a always,exit -F arch=b32 -S execve -k user_commands" >> /etc/audit/rules.d/audit.rules
# 4. 查詢
ausearch -k user_commands -ts today | aureport -f -i
# 或使用 auparse 庫程序化解析
auditd 開銷較大 (每進程啟動記錄完整 argv/envp),高併發服務器需評估性能影響。/etc/profile方案輕量、無性能損耗,適合常規合規審計;auditd適合高安全、合規強制 (等保三級、PCI-DSS) 場景。
通過修改 /etc/profile 動態設置 HISTFILE,結合 who -u am i 獲取客戶端 IP、時間戳命名文件,**零成本實現會話級、用戶級、IP 級的完整命令審計**。配合 HISTTIMEFORMAT、HISTCONTROL、日志平台對接,滿足絕多數運維安全合規需求。高安全場景請疊加 auditd 內核級審計,構建纵深防禦體系。