Debian系统的完整性校验,最直接的工具就藏在base-files这个基础包推荐的debsums里。它不像AIDE那样需要复杂的初始化和数据库维护,也不像tripwire那样配置繁琐。debsums的思路极其朴素:把当前系统中已安装文件包的MD5哈希值,与软件包维护者在构建时生成的原始清单进行比对。任何偏差,要么是配置文件的合法修改,要么就是文件损坏、磁盘故障,甚至是恶意篡改。

debsums的工作原理与安装初始化

debsums不依赖快照,它直接读取/var/lib/dpkg/info/目录下每个软件包的md5sums文件。当你安装一个包时,dpkg会把维护者生成的校验和清单解压到这里。debsums做的就是重新计算磁盘上实际文件的哈希,然后逐行比对。安装很简单,apt install debsums即可。首次运行前,建议先执行debsums --generate=all,这个命令会为那些默认不带md5sums清单的包(主要是某些配置文件或老旧的第三方包)生成一份本地快照,存放在/var/lib/debsums/目录下。注意,这个本地生成的快照只代表你当前系统的状态,如果系统已经被入侵,生成的快照本身就不可信。所以这个操作最好在系统刚安装完、确认干净的时候做。

基础审计命令与输出解读

直接执行debsums -c,会检查所有已安装包中标记为配置文件的项目,并列出变更。但更常用的是debsums -s,静默模式只输出错误,适合放在脚本里。如果输出为空,代表一切正常。一旦出现类似“debsums: missing file /usr/bin/example”或“debsums: checksum mismatch /usr/sbin/sshd”的提示,就要立刻警觉。missing file可能是误删或包管理数据库损坏,checksum mismatch则高度可疑。可以用debsums -l列出所有变更,然后针对单个包深入检查,比如debsums openssh-server。对于配置文件,debsums默认会报错,因为管理员修改配置文件是正常行为。可以用debsums -e只检查那些非配置文件的执行文件和库文件,这才是入侵检测的重点。

区分正常变更与恶意篡改

收到一堆校验和不匹配的报告不要慌。先确认文件类型,dpkg-query -S /path/to/file能告诉你文件属于哪个包。再用dpkg -V package-name交叉验证,dpkg -V会检查文件的md5、大小、权限、所有者等元数据。如果只是配置文件的md5变了,但权限和时间戳正常,大概率是你自己改过。如果/usr/bin/下的二进制文件md5变了,而dpkg -V也显示“5”这个标志(md5不匹配),那就是严重事件。有一种情况是包升级不完全导致的老版本文件残留,用apt --reinstall install package-name重装该包,再跑一次debsums,如果问题消失,说明是更新时的原子性问题,不是入侵。如果重装后很快又出现不匹配,那就要考虑rootkit或正在运行的恶意进程在持续修改文件。

利用debsums进行自动化篡改检测

把debsums -s放到cron里定期跑是最低成本的HIDS。编辑/etc/cron.d/debsums-check,写入一行:

0 3 * * * root /usr/bin/debsums -s 2>&1 | /usr/bin/mail -s "Debsums Alert on $(hostname)" your@email.com

这会在每天凌晨3点执行静默检查,有异常就发邮件。但更推荐的做法是结合auditd。先用auditctl -w /usr/bin -p wa -k binaries监控二进制目录的写入,再用debsums做事后验证。如果audit日志里某个时间点有对/usr/sbin/sshd的写入操作,而debsums恰好报告这个文件校验失败,两条证据链就形成了闭环。对于大规模服务器集群,可以用debsums --root=/mnt/chroot在宿主机上检查容器或chroot环境的文件系统,或者通过配置管理工具(如Ansible)批量执行debsums -s,将输出集中到日志平台。

处理误报与建立白名单

某些包天生就会产生校验和不匹配,比如linux-image内核包的部分文件在postinst脚本里会被动态修改,或者某些通过触发器生成的缓存文件。debsums提供了忽略机制。编辑/etc/debsums-ignore,每行写一个shell通配符路径,例如:

/usr/lib/python3/dist-packages/.*\.pyc
/boot/initrd\.img-.*

这样就能过滤掉编译缓存和initrd镜像这类正常会变的文件。但白名单要严格审计,避免攻击者把恶意文件路径混进去。建议这个文件由配置管理系统下发,并设置不可变属性chattr +i /etc/debsums-ignore,防止篡改。

深入修复与完整性恢复

发现校验和不匹配的文件后,如果确认是系统文件损坏或被篡改,最快的修复方式是提取原始deb包。用dpkg -S /path/to/file找到所属包,然后下载对应的deb:apt download package-name。用dpkg --fsys-tarfile package.deb | tar xf - ./relative-path提取单个文件到临时目录,比对确认无误后再覆盖。覆盖前务必用stat记录原始文件的权限和所有者,恢复后还原。如果大量文件异常,直接apt --reinstall install $(dpkg -l | grep ^ii | awk '{print $2}')重装所有包,但这会覆盖所有配置,慎用。更精细的做法是写个脚本,遍历debsums的输出,只重装那些非配置文件异常且属于base system的包。

debsums的局限性与纵深防御

debsums只能验证包管理器管辖范围内的文件。攻击者如果添加了全新的恶意文件(比如在/tmp或/var/tmp下放webshell),debsums完全看不到。它也无法检测运行中的内存马、内核模块rootkit或者被替换的动态链接库劫持。所以debsums必须配合其他工具:用rkhunter或chkrootkit扫描已知rootkit签名;用lynis做系统基线审计;用auditd监控关键系统调用;用nscheck这类工具检查内核完整性。另外,debsums本身的二进制文件和它依赖的perl解释器、libc库也可能被篡改。可以把debsums的基准哈希值记录在只读介质上,或者用dpkg --verify debsums先自检。如果连dpkg和apt都被替换了,那只能从已知干净介质启动救援模式,挂载根分区后做离线校验。

构建基于debsums的完整性监控体系

把debsums作为日常运维的一部分,需要形成闭环流程。第一步,新机器上线后立即运行debsums --generate=all并保存输出快照到外部安全存储。第二步,部署cron任务和audit规则。第三步,定期(比如每周)做一次全量debsums -c,与外部快照diff。第四步,任何变更都必须关联变更管理工单,如果是计划内的包升级,升级后重新生成快照。第五步,应急响应时,第一时间用debsums -l | grep -v etc导出所有非配置文件的异常,结合进程列表、网络连接、内核模块列表做关联分析。这套流程不依赖商业产品,纯靠系统自带工具就能达到可观的检测覆盖率,对于满足等保合规中的“完整性检查”要求也足够。

debsums的价值在于它的简单和可信赖。它不做启发式猜测,只做硬碰硬的哈希比对。在Debian系的服务器维护中,把它用好,相当于给系统文件加了一层防篡改的物理锁。虽然不能防住所有攻击,但能让攻击者修改系统二进制文件而不被发现的难度大幅增加。