Skip to content

Go 主机安全面试:Linux 日志清理与审计痕迹破坏检测

攻击者拿到主机权限后,常见动作不是马上横向移动,而是先清理痕迹:删除 shell 历史、截断日志、篡改登录记录、关闭 auditd、清理 journald。面试官通常会追问:Go Agent 怎么发现“日志被动过”?怎么区分正常 logrotate、运维清理和入侵后的痕迹破坏?如何把日志异常和进程链路关联成可解释告警?

岗位场景

text
Linux 主机
  -> 采集 /var/log、journald、auditd、utmp/wtmp/btmp、shell 历史文件状态
  -> 标准化文件事件、进程执行、服务状态、登录会话和时间线
  -> 识别 truncate、unlink、权限漂移、日志服务停止、异常 vacuum
  -> 关联用户、TTY、父进程、sudo、Web RCE、反弹 Shell 等上下文
  -> 输出“日志清理/审计绕过/痕迹破坏”告警

这类题考的是 Linux 日志体系、文件系统事件、审计链路、攻击后清理手法、误报治理和 Go Agent 的低开销采集能力。

高频面试题

1. 为什么 HIDS/EDR 要检测日志清理行为?

简洁答案:日志清理通常发生在入侵后期,用来破坏溯源证据;它本身不一定等于攻击成功,但和异常登录、提权、Web RCE、反弹 Shell 连在一起时,风险很高。

关键知识点:

  • 攻击者常清理 auth.logsecuremessageswtmpbtmp.bash_history、journald。
  • 痕迹破坏会降低后续取证质量,因此需要尽早告警。
  • 正常系统也会轮转、压缩、过期删除日志,不能把所有删除都判为攻击。
  • 日志清理检测的价值在于“补证据链”,不是孤立地报一个文件删除。

Go 落地思路:

  • 定义统一的 LogTamperEvent,同时表达文件变化、进程、用户、主机角色和相邻安全事件。
  • 文件事件只保留必要字段:路径、操作、旧大小、新大小、inode、mtime、进程、uid、容器。
  • 规则侧按时间窗口关联,例如 10 分钟内“异常登录 -> sudo -> 日志截断”。
go
type LogTamperEvent struct {
    Path      string
    Op        string
    OldSize   int64
    NewSize   int64
    PID       int
    UID       uint32
    Process   string
    Timestamp int64
}

2. 日志清理常见有哪些技术动作?

简洁答案:主要包括删除日志文件、截断文件内容、覆盖关键记录、修改权限、停止日志服务、清理二进制登录记录和调整时间戳。

关键知识点:

动作常见命令或行为检测重点
删除rm /var/log/auth.logunlink、文件消失、非 logrotate 进程
截断> /var/log/securetruncate -s 0文件大小突然变小
覆盖echo "" > file、脚本重写写入进程和内容长度
清理会话修改 wtmpbtmputmp二进制日志大小和 mtime 异常
关闭审计systemctl stop auditd服务状态变化和执行者
清理 journaljournalctl --vacuum-time=1s命令参数和删除规模

Go 落地思路:

  • 不要只匹配命令字符串,优先从文件事件和进程事件两边取证。
  • 对关键路径建立 watch 或周期基线,路径集合要小,避免全盘监控。
  • logrotatesystemd-journald、包管理脚本建立可信上下文,不简单白名单进程名。

3. 怎么区分正常 logrotate 和攻击者清理日志?

简洁答案:看执行主体、时间窗口、配置来源、文件变化形态和相邻行为。正常 logrotate 通常按固定配置、固定时间、固定进程链路执行;攻击清理更常出现在异常登录或提权之后,并由 shell、解释器、Web 子进程触发。

关键知识点:

  • logrotate 会按配置轮转、压缩、创建新文件,通常伴随 .1.gz 文件。
  • 攻击清理常表现为原文件直接归零、删除后不重建、修改权限或清空部分记录。
  • 运维临时清理也可能手工执行,需要结合工单窗口、用户、TTY 和主机角色降噪。
  • 不能只用“是否进程名叫 logrotate”判断可信,攻击者可以伪装进程名。

Go 落地思路:

  • 采集父子进程链:cron -> logrotatesshd -> bash -> truncate 风险完全不同。
  • 对轮转结果做形态校验:旧文件是否被 rename、压缩文件是否出现、新文件权限是否合理。
  • 对同一主机建立日志文件大小和轮转周期基线,异常时间点提高风险分。
text
正常轮转:
  cron/systemd timer -> logrotate -> rename auth.log -> create auth.log

可疑清理:
  sshd -> bash -> truncate -s 0 /var/log/auth.log
  nginx -> sh -> rm -f /var/log/nginx/access.log

4. 主机侧应该采集哪些日志与审计对象?

简洁答案:优先覆盖认证日志、系统日志、审计日志、journald、登录会话记录和 shell 历史文件,再按发行版和客户场景扩展。

关键知识点:

  • Debian/Ubuntu 常见 auth.log,RHEL/CentOS 常见 secure
  • wtmpbtmputmp 记录登录会话和失败登录,是攻击者常清理对象。
  • auditd 记录系统调用和关键文件访问,关闭或规则被删本身就是风险。
  • .bash_history.zsh_history 不是强证据,但能辅助判断交互式痕迹。
  • journald 存储在 /var/log/journal/run/log/journal,需要关注 vacuum 和服务状态。

Go 落地思路:

  • 根据发行版探测路径,不把所有路径写死。
  • 事件模型里保留 source 字段,例如 file_watchauditdjournald_statusprocess_exec
  • 采集 shell 历史时只记录元数据或风险片段,不默认上传全量内容,避免泄露敏感命令。

5. 文件大小变小就一定是日志被清理吗?

简洁答案:不是。日志轮转、服务重启、压缩归档、容器日志截断、磁盘清理工具都可能让文件变小。判断要结合路径、进程、时间、变更幅度和历史模式。

关键知识点:

  • copytruncate 策略会复制后截断原文件,这是合法轮转。
  • 容器运行时可能对 JSON log 做大小限制和轮转。
  • 业务日志可能由应用自行重建,不能和系统安全日志同等处理。
  • 一次大小变化风险有限,连续变化或攻击链邻近事件更有价值。

Go 落地思路:

  • 只对安全关键日志路径给高权重,普通业务日志默认低权重。
  • 文件大小变化规则要有最小阈值和冷却时间,避免高频抖动。
  • 结合进程可信度和时间窗口评分,而不是单条件告警。
go
func suspiciousShrink(oldSize, newSize int64, critical bool) bool {
    if !critical || oldSize < 1024*1024 {
        return false
    }
    return newSize >= 0 && newSize < oldSize/10
}

6. 如何发现 auditd 被关闭或审计规则被删除?

简洁答案:同时看服务状态、进程存活、配置文件变化、规则列表变化和执行命令。auditd 停止、规则被清空、关键 watch 被删除都可能表示审计绕过。

关键知识点:

  • systemctl stop auditdservice auditd stopauditctl -D 都值得关注。
  • /etc/audit/rules.d/ 规则文件变化可能影响重启后的审计能力。
  • auditctl -l 能看到当前生效规则,但 Agent 不宜高频执行外部命令。
  • 客户可能在排障时临时关闭 auditd,需要结合变更窗口和操作者。

Go 落地思路:

  • 进程执行事件中识别 auditctl -Dauditctl -e 0systemctl stop auditd
  • 文件事件中关注 /etc/audit/audit.rules/etc/audit/rules.d/
  • 低频采样服务状态,失败时不要阻塞主采集链路。

7. 日志清理检测怎样降低误报?

简洁答案:先分清“系统自动轮转”“业务日志治理”“人工运维清理”“攻击后痕迹破坏”,再用主机角色、进程链路、变更窗口和相邻安全事件做分级。

关键知识点:

  • 安全关键日志和普通应用日志使用不同规则阈值。
  • 有变更单、固定维护窗口、可信自动化账号时可以降级。
  • 来自 Web 进程、临时目录脚本、异常登录会话的清理动作要升级。
  • 告警解释必须说明为什么不是普通 logrotate。

Go 落地思路:

  • 规则输出 Reason 列表,而不是只输出风险分。
  • 对同类主机学习正常轮转时间,偏离基线再提高置信度。
  • 允许客户配置可信账号、维护窗口和业务日志路径,但不要让配置绕过系统安全日志。

8. 客户反馈日志清理告警误报,你怎么排查?

简洁答案:先拿到告警时间线,再核对执行进程、用户、TTY、父进程、文件变化形态、logrotate 配置、审计服务状态和客户变更窗口。

关键知识点:

  • 误报排查不能只看命中规则,要看完整证据链。
  • 如果是 copytruncate,应能看到归档文件、logrotate 配置和固定调度。
  • 如果是人工命令,要确认登录来源、sudo 记录和操作原因。
  • 如果是攻击清理,常能看到异常登录、Web 子进程、临时目录脚本、外联或提权事件。

Go 落地思路:

  • Agent 提供本地诊断摘要:关键路径状态、最近文件事件、相关进程链、服务状态。
  • 服务端保留规则版本、命中字段和降噪决策,方便复盘。
  • 排障包只导出必要元数据,避免上传整份日志正文。

学习要点

方向需要掌握的内容
Linux 日志体系syslog、journald、auditd、utmp/wtmp/btmp、shell history
文件系统事件unlink、rename、truncate、chmod、chown、mtime、inode
攻击链还原异常登录、sudo、Web RCE、反弹 Shell、日志清理的时间线
Go 工程实现小路径集合 watch、周期基线、事件标准化、规则解释、敏感信息控制
误报治理logrotate、维护窗口、主机角色、可信自动化、客户排障证据

小练习

  1. 设计一个 LogFileState 结构体,能表达路径、大小、inode、mtime、owner、mode 和 hash 摘要。
  2. 写一个函数判断日志文件是否发生异常截断,要求排除小文件和正常轮转窗口。
  3. 设计一条规则:SSH 异常登录后 5 分钟内清空 auth.logsecure,生成高危告警。
  4. 说明为什么 journalctl --vacuum-size 不一定是攻击,但为什么需要记录执行者和参数。
  5. 给出客户误报排查清单,区分 logrotate、人工运维清理和攻击后痕迹破坏。

复盘题

  • 日志清理检测为什么不能只看 rm 命令?
  • 如何用文件大小、进程链路和登录事件还原一次痕迹破坏?
  • copytruncate 对日志清理检测有什么干扰?
  • Go Agent 如何避免把日志正文和敏感命令全量上传?
  • 一条高质量日志清理告警应该包含哪些证据?
最近更新