linux定时任务需结合auditd监控execve系统调用与脚本内嵌日志实现完整审计:添加auditd规则捕获执行轨迹,脚本头尾记录uid、auid、cmd及退出码,并核查cron配置、systemd timer等所有触发源。

Linux 定时任务本身不自带执行日志,cron 只记录调度是否触发,不记录脚本是否成功、执行了什么、谁调用、参数是什么。要真正还原脚本的“执行历史轨迹”,必须组合系统级审计与应用层记录,不能只靠 crontab -l 或 /var/log/cron。
抓核心:监控 execve 系统调用(auditd)
所有定时任务最终都通过内核 execve() 执行命令(包括 /bin/bash /path/to/script.sh)。这是最可靠、不可绕过的审计入口。
- 添加持久化规则到
/etc/audit/rules.d/cron-script.rules:
-a always,exit -F arch=b64 -S execve -F path=/path/to/your/script.sh -F key=cron_script_deploy
- 如果脚本由不同解释器运行(如 Python/Perl),可加多条规则,或放宽为
-F exe=/usr/bin/python3 - 执行
sudo augenrules --load激活,重启后仍生效 - 查执行轨迹:
sudo ausearch -k cron_script_deploy --start today | aureport -f -i,输出含:真实用户 UID、工作目录cwd、完整命令行cmd、是否成功success=yes/no
补上下文:在脚本内嵌日志头信息
auditd 记录的是“谁在何时调用了这个程序”,但不包含脚本内部逻辑细节。建议在脚本开头统一打点:
- 第一行加入:
echo "[$(date '+%Y-%m-%d %H:%M:%S')] UID=$(id -u) AUID=$(cat /proc/$$/loginuid 2>/dev/null || echo 'N/A') CMD=$0 $* STARTED" >> /var/log/script_audit.log - 结尾加:
echo "[$(date '+%Y-%m-%d %H:%M:%S')] EXIT_CODE=$? FINISHED" >> /var/log/script_audit.log - 这样每条日志带时间戳、原始登录用户(
AUID)、实际执行者(UID)、完整命令行和退出码,和 auditd 日志可交叉验证
盯源头:确认 cron 调用链是否可信
cron 本身可能被篡改。需定期检查三类配置来源:
-
crontab -u username -l(用户级任务,存于/var/spool/cron/username) -
cat /etc/crontab(系统级任务,含指定用户字段) -
ls /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/(片段式任务,常被忽略) - 重点看执行命令是否绝对路径、是否带可疑环境变量(如
PATH=被重置)、是否用sudo或su -c隐藏真实 UID
防遗漏:覆盖非标准触发方式
很多“定时脚本”其实不是 cron 触发的,比如:
- systemd timer(
systemctl list-timers查看)→ 对应 unit 文件中ExecStart=行也要加 audit 规则 - at 命令一次性任务 → 同样走 execve,已有 auditd 规则可覆盖
- 由其他服务(如 Jenkins、Ansible)远程触发 → 这类需额外在调用端开启 SSH 日志(
LogLevel VERBOSE)或 API 审计
不复杂但容易忽略:auditd 是唯一能跨 shell 类型、跨用户切换、跨交互模式统一捕获执行动作的机制;单纯改 PROMPT_COMMAND 或 HISTFILE 对 cron 完全无效。











