配置文件MD5飘移审计是定期比对关键配置文件当前MD5值与人工生成的带签名基线快照是否一致,不一致即告警并留痕;核心为纯Shell实现的采集基线、去噪校验、阻断告警、日志留存四步闭环。

什么是配置文件MD5飘移审计
配置文件MD5飘移审计,本质是定期比对关键配置文件(如/etc/nginx/nginx.conf、/opt/app/config.yml等)当前MD5值与“基线快照”是否一致。一旦发现不一致,说明文件被意外或未授权修改——这在生产环境中可能预示配置漂移、人为误操作甚至入侵行为。
核心实现思路
不依赖外部工具链,纯Shell完成:采集基线 → 定期校验 → 差异告警 → 日志留存。重点在于基线可信、校验可靠、结果可追溯。
- 基线生成必须人工触发且带签名:上线前或重大变更后,由运维手动运行一次初始化脚本,生成含时间戳和操作人信息的baseline.md5,并写入校验注释行(如# baseline@2024-06-15T14:22:01Z by ops-admin)
- 校验时跳过临时/动态内容:对.conf、.yml等文本类配置,用sed过滤掉注释行和空行再计算MD5,避免因注释增删或空格调整导致误报
- 校验失败必须阻断+留痕:检测到MD5不匹配时,立即记录完整上下文(文件路径、旧/新MD5、时间、主机名),同时向企业微信/钉钉Webhook推送告警,并可选暂停后续巡检任务
最小可行脚本结构
以下为精简但生产可用的核心逻辑(保存为audit-config-md5.sh):
#!/bin/bash
CONFIG_LIST=( "/etc/nginx/nginx.conf" "/opt/app/config.yml" )
BASELINE_FILE="/var/log/config-audit/baseline.md5"
LOG_DIR="/var/log/config-audit"
# 初始化基线(仅首次或手动调用)
if [[ "" == "init" ]]; then
mkdir -p "$LOG_DIR"
echo "# baseline@$(date -u +%Y-%m-%dT%H:%M:%SZ) by $(whoami)" > "$BASELINE_FILE"
for f in "${CONFIG_LIST[@]}"; do
if [[ -f "$f" ]]; then
md5sum "$f" | cut -d' ' -f1 | sed 's/^/ /' >> "$BASELINE_FILE"
fi
done
echo "✅ Baseline saved to $BASELINE_FILE"
exit 0
fi
# 执行校验
failed=0
for i in "${!CONFIG_LIST[@]}"; do
f="${CONFIG_LIST[$i]}"
if [[ ! -f "$f" ]]; then continue; fi
# 对文本配置去噪后计算MD5
if [[ "$f" =~ \.(conf|ini|yml|yaml|json|properties)$ ]]; then
current_md5=$(sed '/^[[:space:]]*#/d;/^[[:space:]]*$/d' "$f" | md5sum | cut -d' ' -f1)
else
current_md5=$(md5sum "$f" | cut -d' ' -f1)
fi
expected_md5=$(sed -n "$((i+2))p" "$BASELINE_FILE" | sed 's/^[[:space:]]*//')
if [[ "$current_md5" != "$expected_md5" ]]; then
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) ⚠️ MISMATCH: $f" >> "$LOG_DIR/audit.log"
echo " expected: $expected_md5 | current: $current_md5" >> "$LOG_DIR/audit.log"
failed=1
fi
done
if [[ $failed -eq 1 ]]; then
curl -X POST -H 'Content-Type: application/json' \
-d '{"msgtype":"text","text":{"content":"[ALERT] Config MD5 drift detected on $(hostname)"}' \
https://qyapi.weixin.qq.com/your-webhook-url &>/dev/null
fi
集成进生产周期性调度
使用cron而非systemd timer更轻量、兼容性强:
- 每日凌晨2:15执行校验:15 2 * * * /bin/bash /opt/scripts/audit-config-md5.sh >> /var/log/config-audit/cron.log 2>&1
- 每月1日零点重新生成基线(需人工确认后解注释):# 0 0 1 * * /opt/scripts/audit-config-md5.sh init
- 配合logrotate管理日志,保留90天:/var/log/config-audit/*.log { daily rotate 90 ... }
不复杂但容易忽略











