虚拟机镜像安全,镜像删除密码密钥再分发镜像模板
制作虚拟机镜像模板时,如果直接把已经配置好密码、SSH密钥和主机标识的系统打包分发,接手镜像的机器会继承原系统的登录凭据和机器身份,存在被破解或串号的风险。
本文从零开始演示一套可执行的镜像清理流程,目标是把虚拟机做成干净、可安全分发的模板:不保留原密码、不携带SSH密钥、不复制原主机标识。
整个过程不需要太高门槛,照着做即可。
制作镜像前需要准备什么
开始操作前,先确认三件事:
- 你需要对虚拟机有 root 权限。普通用户无法修改系统密钥和密码配置。
- 建议准备一台独立测试虚拟机,别用正在跑业务的机器直接做模板。
- 记录当前系统的发行版和版本号,例如 CentOS 7、Ubuntu 22.04,不同版本的配置文件路径略有差异。
另外需要明白一个基本概念:镜像模板的密码删除不是把密码文件删掉,而是清除加密密码项,让新机器首次启动时强制重新设置密码,或者通过 cloud-init 注入新密码。
直接删 /etc/shadow 会导致系统无法登录,这是新手容易踩的坑。
分步清理密码、密钥和敏感痕迹
以下操作默认在虚拟机内通过 SSH 或控制台以 root 身份执行。
1. 清理本地用户密码
先查看当前系统有哪些可登录用户:
cat /etc/passwd | grep -E '/bin/(bash|sh)$'
对需要保留但必须重置密码的用户,执行:
passwd -d 用户名
-d 参数会删除用户密码,让该用户无需密码即可登录。
注意,这只适用于测试环境;
如果目标环境不允许空密码,更稳妥的做法是设置一个临时随机密码并在分发后立即修改:
passwd 用户名
如果你使用 cloud-init,可以在清理步骤中保留 cloud-init 配置,让新实例启动时自动生成新密码或注入 SSH 公钥。
此时可以只删除原密码,不用额外设临时密码。
2. 删除 SSH 主机密钥和用户密钥
SSH 主机密钥保存在 /etc/ssh/ 下,文件名通常类似 ssh_host_*_key 和 ssh_host_*_key.pub。
如果不删掉,所有从同一模板克隆出的机器 SSH 指纹相同,会引发中间人攻击风险。
删除命令:
rm -f /etc/ssh/ssh_host_*_key*
删除后记得让系统在下次启动时自动重新生成。
在大多数发行版中,只要对应服务存在,重启后会自动创建新密钥。
如果重启后没有生成,可以手动执行:
ssh-keygen -A
用户级 SSH 密钥通常放在 /root/.ssh/ 和 /home 下各用户目录中,全部删除:
rm -rf /root/.ssh
rm -rf /home/*/.ssh
3. 清理历史记录和临时文件
历史命令可能包含密码或敏感参数,清空当前会话和 root 的历史:
history -c
rm -f /root/.bash_history
同时清理临时文件、日志和软件包缓存,减小镜像体积:
apt clean 2>/dev/null || yum clean all 2>/dev/null
rm -rf /tmp/* /var/tmp/*
journalctl --vacuum-time=1d 2>/dev/null
4. 重置主机标识
主机名、machine-id 这类标识也会被复制到新机器。
如果所有克隆机 Hostname 相同,会影响 DHCP 和集群管理。
先修改主机名:
hostnamectl set-hostname localhost
再清空 machine-id(Ubuntu 和大多数 systemd 系统):
rm -f /etc/machine-id
重启时系统会自动重新生成。
有些特殊环境可能还需要删除 /var/lib/dbus/machine-id,可以视发行版决定。
5. 禁用或重置 cloud-init 实例信息
如果镜像基于 Ubuntu 或 CentOS 云镜像,需要清除 cloud-init 的实例缓存,避免新虚拟机继承旧实例ID:
cloud-init clean --logs
没有安装 cloud-init 的虚拟机可以跳过这一项,但需要确认系统里没有残留的 /var/lib/cloud/instance 目录。
常见报错和踩坑点
清理过程中最容易出现三种问题:
- 删完 SSH 主机密钥后重启失败,通常是
/etc/ssh/目录权限不对或 sshd 配置里指定了不存在的主机密钥路径。检查配置文件里HostKey字段,并确认目录权限为 755。 - 清空 machine-id 后某些程序启动异常。如果重启后问题依旧,可以手动执行
systemd-machine-id-setup重新生成。 - 密码删除后远程登录失败。清空密码后 SSH 默认不允许空密码登录,建议先用本地控制台测试,再决定是否需要开启
PermitEmptyPasswords。生产环境不建议开启此项。
分发后如何验证镜像安全
镜像分发到新虚拟机后,不要急着投入使用,先做一轮快速检查。
- 登录后运行
hostname,确认主机名不是继承自旧模板。 - 执行
ls -l /etc/ssh/,确认 ssh_host 开头的密钥文件存在于新机器且生成时间距当前不远。 - 检查关键用户是否可以正常登录,密码策略是否生效。
还可以用以下命令对比新旧机器的标识:
cat /etc/machine-id
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
新机器的 machine-id 和 SSH 指纹必须与旧模板不一致,不一致才能确认清理成功。
虚拟机镜像安全的核心不是“删干净”,而是确保新机器第一次启动时不会复用旧身份和旧凭据。
只要密码、SSH 密钥和主机标识这三类数据被正确处理,镜像分发后的安全风险就能控制在可接受范围内。
如果你正在制作镜像模板,建议先在测试环境完整跑一遍本文流程,确认没问题后再批量分发。
遇到异常时,优先检查 sshd 配置和 cloud-init 状态,大多数问题都能从日志里找到答案。