




















Created: 2/10/2026 13:40
Updated: 2/10/2026 15:52
Exported: 2/10/2026 15:55
linux上的审计系统audit 能记录一个用户执行的完整命令么,比如我赋予一个普通用户sudo docker的能力,我想知道他执行的完整sudo docker run 或者什么的,或者说,能监控所有用户执行docker和docker-compose这两个命令的使用情况,因为有些用户加入了docker组,不是用sudo执行的
是的,Linux 的 auditd 系统可以记录用户执行的完整命令(包括参数),而且可以同时覆盖两种情况:
最推荐且最干净的方式是监控 execve 系统调用,并针对 docker 相关可执行文件做过滤。
把下面这些规则加到 /etc/audit/rules.d/ 下的某个 .rules 文件(例如 docker-audit.rules),然后重启 auditd 或用 auditctl -R 加载。
# 监控所有 execve 系统调用,但只记录真正执行 docker 或 docker-compose 的
# ───────────────────────────────────────────────────────────────
# 方式1:直接针对路径(最精准,推荐)
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker -k docker-exec
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker-compose -k docker-exec
-a always,exit -F arch=b64 -S execve -F exe=/usr/local/bin/docker-compose -k docker-exec # 有的人装在这个路径
# 如果你的系统还有这些 symlink / 别名,也建议加
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker.io -k docker-exec
-a always,exit -F arch=b64 -S execve -F exe=/snap/bin/docker -k docker-exec # snap 安装的情况
# 方式2:针对所有以 docker 开头的命令(比较广,但噪音多)
-a always,exit -F arch=b64 -S execve -F path=/usr/bin/docker -k docker-exec
-a always,exit -F arch=b64 -S execve -F dir=/usr/bin -F path_1=/docker -k docker-exec # 不常用
# 如果你还想同时监控 sudo docker 的情况(其实方式1已经包含了)
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F a0=docker -k sudo-docker
32 位系统(现在很少见)再补上 arch=b32 的对应规则。
which docker
which docker-compose
readlink -f $(which docker)
通常是 /usr/bin/docker 和 /usr/bin/docker-compose 或 /usr/local/bin/docker-compose。
cat > /etc/audit/rules.d/99-docker-exec.rules << 'EOF'
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker -k docker-exec
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker-compose -k docker-exec
# 如有需要再加 sudo docker 的显式规则
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F a0=docker -k sudo-docker
EOF
auditctl -R /etc/audit/rules.d/99-docker-exec.rules
# 或直接重启服务(比较保险)
systemctl restart auditd
# 看最近的 docker 相关记录
ausearch -k docker-exec -ts recent | aureport -x --summary
ausearch -k docker-exec --format text | less
# 看某个用户的全部 docker 操作(假设 uid=1001)
ausearch -k docker-exec -ua 1001
# 看完整的命令行(最重要的一行是 EXECVE)
ausearch -k docker-exec -i # -i 会把 hex 转成可读字符串
# 例子输出大概长这样:
type=EXECVE msg=audit(...): argc=5 a0="docker" a1="run" a2="-d" a3="--name" a4="nginx" a5="nginx:latest"
type=SYSCALL msg=audit(...): exe="/usr/bin/docker" ... auid=1001 uid=0 ... key="docker-exec"
| 需求 | 推荐规则写法 | 说明 |
|---|---|---|
| 只看真正跑容器的命令 | -F exe=/usr/bin/docker -F a1=run | 只记录 docker run |
| 监控所有 docker 子命令 | 只用 -F exe=/usr/bin/docker | 会包含 run, ps, exec, logs... |
| 也想看 docker-compose | 同时加 docker-compose 的 exe 规则 | 同上 |
| 特别关注特权容器 | -F exe=/usr/bin/docker -F a1=run -F a2~="--privileged" | 模糊匹配参数(audit 支持 ~) |
| 减少噪音 | 加 -F auid>=1000 -F auid!=unset | 排除系统用户(auid=-1) |
这样设置后,无论是 sudo docker run ... 还是普通用户直接 docker run ...、docker-compose up -d,完整命令(含所有参数)都会被记录在 audit 日志里,且带有原始登录用户(auid)。
你把上面的谈话总结下,完整输出audit的安装,规则,什么的,然后python脚本,还有最后的这个监控shell脚本,全部完整输出一遍
以下是我們整個對話的完整總結,重點是關於 Linux auditd 監控 docker / docker-compose 相關命令的完整方案。
我會按照邏輯順序重新整理一次,並提供目前最穩定的版本(基於對話後期的結論):
# 安裝 auditd
sudo apt update
sudo apt install -y auditd audispd-plugins
# 啟動並設定開機啟動
sudo systemctl enable auditd
sudo systemctl start auditd
# 檢查狀態
sudo systemctl status auditd
auditctl -s
建立規則檔案,例如:
sudo nano /etc/audit/rules.d/99-docker-exec.rules
內容(64位系統為主):
# 監控 docker 客戶端執行
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker -k docker-exec
# 如果有 docker-compose(常見路徑)
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker-compose -k docker-exec
-a always,exit -F arch=b64 -S execve -F exe=/usr/local/bin/docker-compose -k docker-exec
# 可選:明確監控 sudo docker 的情況(通常不需要,因為上面已包含)
# -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/sudo -F a0=docker -k sudo-docker
# 可選:過濾掉系統用戶(減少噪音)
# -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/docker -F auid>=1000 -F auid!=unset -k docker-exec
載入規則:
sudo augenrules --load
# 或直接
sudo auditctl -R /etc/audit/rules.d/99-docker-exec.rules
# 確認規則已載入
sudo auditctl -l | grep docker-exec
這個版本已加入 auid / uid 的 fallback 邏輯(當 auid 被錯誤設為 root 時用 uid)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
解析 ausearch -k docker-exec -i 的輸出
輸出格式:時間|用戶|命令|工作目录|執行文件
當 auid 異常為 root 時,fallback 使用 uid
"""
import re
import sys
from datetime import datetime
def parse_audit_block(block):
result = {
'time': None,
'auid': None,
'uid': None,
'command': None,
'cwd': None,
'exe': None,
}
lines = block.strip().splitlines()
for line in lines:
line = line.strip()
if not line:
continue
# 時間
if 'msg=audit(' in line and result['time'] is None:
m = re.search(r'msg=audit\((\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\.\d{3}:\d+)\)', line)
if m:
timestr = m.group(1).split(':', 1)[0]
try:
dt = datetime.strptime(timestr, '%m/%d/%Y %H:%M:%S.%f')
result['time'] = dt.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
except ValueError:
result['time'] = timestr
# auid
if 'auid=' in line:
m = re.search(r'auid=(\S+)', line)
if m:
result['auid'] = m.group(1)
# uid
if 'uid=' in line and result['uid'] is None:
m = re.search(r'uid=(\S+)', line)
if m:
result['uid'] = m.group(1)
# cwd
if line.startswith('type=CWD'):
m = re.search(r'cwd="([^"]+)"', line)
if m:
result['cwd'] = m.group(1)
# exe
if 'exe=' in line:
m = re.search(r'exe="([^"]+)"', line)
if m:
result['exe'] = m.group(1)
# 命令 (EXECVE)
if line.startswith('type=EXECVE'):
parts = []
m_argc = re.search(r'argc=(\d+)', line)
if m_argc:
argc = int(m_argc.group(1))
for i in range(argc):
m_arg = re.search(rf'a{i}=("[^"]*"|\S+)', line)
if m_arg:
arg = m_arg.group(1)
if arg.startswith('"') and arg.endswith('"'):
arg = arg[1:-1]
parts.append(arg)
if parts:
result['command'] = ' '.join(parts)
return result
def get_user(auid, uid):
bad_auid = {'root', '0', '-1', 'unset', '4294967295'}
if auid and auid not in bad_auid:
return auid
if uid and uid not in {'unset', '4294967295'}:
return uid
return auid or uid or '未知'
def main():
if len(sys.argv) > 1 and sys.argv[1] != '-':
with open(sys.argv[1], 'r', encoding='utf-8') as f:
text = f.read()
else:
text = sys.stdin.read()
if not text.strip():
return
blocks = [b.strip() for b in re.split(r'-{4,}', text) if b.strip()]
print("時間|用戶|命令|工作目录|執行文件")
for block in blocks:
info = parse_audit_block(block)
if not info['time'] or not info['command']:
continue
time_str = info['time']
user = get_user(info['auid'], info['uid'])
cmd = info['command'].replace('|', '\\|')
cwd = (info['cwd'] or '(未記錄)').replace('|', '\\|')
exe = (info['exe'] or '(未知)').replace('|', '\\|')
print(f"{time_str}|{user}|{cmd}|{cwd}|{exe}")
if __name__ == '__main__':
main()
使用方式:
ausearch -k docker-exec -i -ts today | python3 audit-show.py
#!/usr/bin/env bash
# 名稱建議:docker-audit-monitor.sh
# 放在 /usr/local/bin/ 或你喜歡的位置
PARSED_LOG="/var/log/docker-audit-parsed.log"
ERROR_LOG="/var/log/docker-audit-error.log"
PYTHON_SCRIPT="/data/ubuntu/audit-show.py" # ← 請改成你實際的 python 腳本完整路徑
# 確保目錄與檔案存在
mkdir -p "$(dirname "$PARSED_LOG")" "$(dirname "$ERROR_LOG")"
touch "$PARSED_LOG" "$ERROR_LOG"
chmod 644 "$PARSED_LOG" "$ERROR_LOG"
echo "開始持續監控 docker 命令執行記錄..."
echo "輸出檔案:$PARSED_LOG"
echo "錯誤檔案:$ERROR_LOG"
echo "使用 ausearch --start recent,每 5 秒檢查一次"
echo "建議使用 screen 或 tmux 背景執行"
while true; do
TMP_RAW="/tmp/docker-audit-raw-$$.txt"
# 使用 recent 只抓最近的事件,避免重複舊記錄
ausearch --start recent -k docker-exec -i > "$TMP_RAW" 2>>"$ERROR_LOG"
if [[ -s "$TMP_RAW" ]]; then
cat "$TMP_RAW" | python3 "$PYTHON_SCRIPT" >> "$PARSED_LOG" 2>>"$ERROR_LOG"
# 可選:去重(如果還是偶爾重複)
sort -u "$PARSED_LOG" -o "$PARSED_LOG"
fi
rm -f "$TMP_RAW"
sleep 5 # 可調整為 10 或 15 秒,視需求
done
執行方式(推薦使用 screen 或 tmux):
chmod +x /data/ubuntu/docker-audit-monitor.sh
# 使用 screen 背景執行
screen -S docker-audit
# 在 screen 裡執行:
/data/ubuntu/docker-audit-monitor.sh
# 之後按 Ctrl+A D 離開 screen
# 回來看:screen -r docker-audit
查看即時結果:
tail -f /var/log/docker-audit-parsed.log
如果未來你發現還有重複、延遲或格式問題,再提供最新 log 片段,我可以繼續幫你微調。
解釋 auditd 日誌輪替監控 Kubernetes 命令總結更簡潔
Powered by Grok Exporter
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。