docker diff 是检查容器文件是否被篡改的直接手段,它比对容器可写层与原始镜像只读层,以 a(新增)、c(修改)、d(删除)标识偏离初始状态的文件变更,但不覆盖挂载卷和 tmpfs 中的改动。

docker diff 是检查容器内文件是否被篡改的直接手段。它不对比运行时行为,只忠实反映容器文件系统相对于原始镜像的变更——任何未经授权的新增、删除或修改,都会在输出中留下明确标记。
理解 diff 的比对基准
docker diff 实质是将**当前容器的可写层(upperdir)** 与**其启动所用镜像的只读层(lowerdir)** 做逐文件比对。它不关心容器是否在运行,也不比较主机文件系统,只回答一个问题:这个容器自创建起,哪些文件偏离了镜像初始状态?
- 篡改行为(如恶意写入配置、替换二进制、植入后门脚本)必然落在可写层,会被 diff 捕获为 A 或 C
- 删改镜像自带文件(如清空 /etc/shadow、覆盖 /bin/bash)会显示为 D 或 C
- 挂载卷(-v)和 tmpfs 中的变更不会出现在 diff 输出里,因为它们不在容器的联合文件系统层级中
识别高风险篡改模式
单看 A/C/D 符号不够,需结合路径判断意图。以下几类变更应立即核查:
- /etc/passwd、/etc/shadow、/etc/group 出现 C —— 账户权限被修改
- /usr/bin/、/bin/、/sbin/ 下关键命令(如 ls、ps、netstat)显示 C —— 可能被 rootkit 替换
- /root/.bash_history、/home/*/.*history 新增 A —— 人为操作痕迹,需确认是否授权
- /tmp、/var/tmp 大量 A + 混杂可执行文件名(如 *.sh、*.elf)—— 典型恶意载荷落地迹象
- /etc/cron.*、/var/spool/cron 出现 A 或 C —— 持久化任务被植入
快速定位并验证可疑文件
不要只扫一眼输出,要联动检查内容:
- 先执行 docker diff 容器名 获取全量变更列表
- 用 grep -E '^(A|C|D) /etc|/usr/bin|/tmp' 筛出重点路径
- 对标记为 C 的文件,用 docker exec 容器名 sha256sum /path/to/file 计算哈希,与原始镜像中同路径文件哈希比对(需提前备份或从镜像导出)
- 对标记为 A 的文件,用 docker exec 容器名 ls -l /path/to/file 查看属主、权限、时间戳;再用 docker exec 容器名 cat /path/to/file | head -n 20 快速查看内容特征
注意 diff 的盲区和辅助手段
diff 强大但有边界,需配合其他命令交叉验证:
- 它看不到内存驻留进程或网络连接,发现可疑文件后,用 docker top 容器名 和 docker exec 容器名 netstat -tuln 查活跃行为
- 它不反映日志写入,用 docker logs --since 1h 容器名 看近期输出是否有异常报错或调试信息
- 若容器已停止,diff 仍有效;但若容器被重建,历史变更即丢失,建议对关键服务容器定期自动执行 diff 并存档











