深色模式
日志防篡改:集中存储与只读留存
摘要:攻击者拿下主机后第一件事往往是清日志。本文从"实时集中、本地只读、远端 WORM、完整性校验"四个手段构建防篡改日志体系,并给出留存周期设计。
适用环境
bash
cat /etc/os-release
systemctl is-active rsyslog auditd
command -v chattr && chattr --version 2>/dev/null | head -1
df -h /var/log
command -v openssl && openssl version1
2
3
4
5
2
3
4
5
操作步骤
1. 第一原则:日志必须尽快离开本机
bash
cat >/etc/rsyslog.d/60-forward.conf <<'EOF'
# 使用 @@ 表示 TCP;队列保证断网时不丢
*.* @@logcenter.internal:514
$ActionQueueFileName fwdRule
$ActionQueueMaxDiskSpace 2g
$ActionQueueSaveOnShutdown on
$ActionQueueType LinkedList
$ActionResumeRetryCount -1
EOF
systemctl restart rsyslog
ss -tnp | grep 5141
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
明文 syslog 可被伪造和篡改
启用 TLS 传输(rsyslog gtls 驱动)或使用带认证的日志管道(Vector/Fluent Bit → Kafka)。
2. 日志中心:对本机只开写权限
bash
# 日志中心开启接收
cat >/etc/rsyslog.d/10-receive.conf <<'EOF'
module(load="imtcp")
input(type="imtcp" port="514")
$template Remote,"/var/log/remote/%HOSTNAME%/%$YEAR%-%$MONTH%-%$DAY%.log"
*.* ?Remote
EOF
systemctl restart rsyslog
# 采集账号无登录 shell、无读权限
useradd -r -s /sbin/nologin logwriter
chown -R logwriter:logwriter /var/log/remote 2>/dev/null
chmod 750 /var/log/remote1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
审计人员通过独立只读账号/平台查询,采集账号不能读历史日志。
3. 本地只追加:chattr +a
bash
for f in /var/log/secure /var/log/messages /var/log/audit/audit.log /var/log/sudo.log; do
[ -f "$f" ] && chattr +a "$f" && echo "locked: $f"
done
lsattr /var/log/audit/audit.log1
2
3
4
2
3
4
+a 表示只能追加不能删除/修改(root 也受限,需先 chattr -a)。
chattr +a 后 logrotate 会失败
必须在 rotate 脚本里先 chattr -a 再轮转,或用 copytruncate 之外的方式并配合 prerotate/postrotate 处理。
bash
cat >/etc/logrotate.d/secure-hardened <<'EOF'
/var/log/secure {
weekly
rotate 26
missingok
notifempty
compress
prerotate
chattr -a /var/log/secure 2>/dev/null || true
endscript
postrotate
/usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
touch /var/log/secure && chattr +a /var/log/secure
endscript
}
EOF
logrotate -d /etc/logrotate.d/secure-hardened # -d 为调试模式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
4. 用 auditd 监控"删日志"这个动作
bash
cat >/etc/audit/rules.d/97-log-protect.rules <<'EOF'
-w /var/log/ -p wa -k log_tamper
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -S truncate -k log_delete
-w /etc/rsyslog.conf -p wa -k log_config
-w /etc/rsyslog.d/ -p wa -k log_config
-w /etc/logrotate.d/ -p wa -k log_config
EOF
augenrules --load
ausearch -k log_delete --start today1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
5. 远端 WORM / 对象存储锁
对象存储(S3 Object Lock、OSS 合规保留策略)可设"保留期内不可删除",是留存要求的首选落地方式。
bash
# 每日把归档日志上传到开启保留策略的桶
aws s3 cp /var/log/remote/archive/ s3://audit-log-bucket/$(hostname)/ \
--recursive --sse aws:kms1
2
3
2
3
本地/自研方案至少要做到:日志目录独立挂载、采集服务账号无删除权限、删除操作需双人审批。
6. 完整性校验:哈希链
bash
cat >/usr/local/bin/log-digest.sh <<'EOF'
#!/bin/bash
# 每天为前一天的日志生成哈希,哈希再上传远端,形成可校验的链条
D=$(date -d yesterday +%F)
DIR=/var/log/remote/$(hostname)
[ -d "$DIR" ] || exit 0
sha256sum "$DIR/$D.log" 2>/dev/null >> /var/log/log-digests.txt
chattr +a /var/log/log-digests.txt 2>/dev/null || true
EOF
chmod +x /usr/local/bin/log-digest.sh1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
校验:
bash
sha256sum -c /var/log/log-digests.txt 2>/dev/null | grep -v OK | head1
7. 留存周期与容量规划
bash
# 估算:日增量 × 留存天数 × 压缩比
du -sh /var/log/remote/*/ | tail -5
find /var/log/remote -name "*.gz" -mtime +180 | wc -l1
2
3
2
3
留存周期先按制度要求确定(常见 6 个月以上),再反推容量;容量不足时扩容而不是缩短周期。
验证
bash
# 1) 本地删日志会被拦
cp /var/log/secure /tmp/bak && chattr +a /var/log/secure
echo "" > /var/log/secure 2>&1 | head -1 # 应报权限不足
chattr -a /var/log/secure && cp /tmp/bak /var/log/secure
# 2) 删除动作被 audit 记录
ausearch -k log_delete --start today | tail -3
# 3) 远端已收到
ssh logcenter "ls -l /var/log/remote/$(hostname)/ | tail -3"
# 4) 哈希链可校验
sha256sum -c /var/log/log-digests.txt 2>/dev/null | tail -31
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
判定标准:本地无法静默删改;删除动作有审计;日志在秒级到达远端;留存期内不可被单人删除。
常见坑
只在本地做防篡改,主机被拿下即失效
本地 chattr +a 挡不住拿到 root 的攻击者执行 chattr -a。必须依赖远端留存。
chattr +a 导致 logrotate 静默失败
轮转失败会让日志撑爆磁盘。上线前必须用 logrotate -d 调试并观察至少一个周期。
日志中心权限没分离
采集账号同时能删历史日志,等于防了个寂寞。读写角色必须分离。
留存周期与容量冲突时私自缩短周期
应先扩容或做冷热分层(近期热存储、历史归档到对象存储)。
忘记校验时钟
跨主机关联依赖准确时间。NTP 异常会让整个追溯链条失效。