qcow2镜像不支持文件级只读保护,因chmod/chattr仅限宿主机元数据,而qemu-img等工具可绕过直接写入块设备;有效防护需guestmount --ro+挂载点权限锁死,或qemu-nbd+ro挂载+bind二次锁定,并配合母盘目录remount,ro及快照清理。

直接结论:qcow2 镜像本身不支持“文件级只读属性”写保护,必须靠挂载时强制只读 + 文件系统权限 + 运行时隔离三重控制,否则任何 root 用户或 qemu 进程仍可覆盖写入。
为什么 chmod 444 或 chattr +i 对 qcow2 文件无效
qcow2 是一个封装了完整块设备结构的二进制文件,chmod 或 chattr +i 只影响宿主机对该文件的“元数据访问权限”,但只要进程有读写权限(如 root),就能用 qemu-img、guestmount -w、qemu-nbd 等工具打开并修改其内部文件系统——这些操作绕过宿主文件权限检查,直接解析和写入镜像逻辑扇区。
常见错误现象:
- 执行
chattr +i base.qcow2后,qemu-img resize base.qcow2 +1G仍成功(因为内核不拦截块设备级写) - 用
guestmount -a base.qcow2 -m /dev/sda1 /mnt挂载后,touch /mnt/test成功写入(即使镜像文件被chmod 444)
真正有效的只读保护:guestmount --ro + 挂载点权限锁死
唯一能从用户态阻止写入的方案,是让所有挂载行为都强制只读,并限制挂载点本身不可写。这需要两步协同:
- 挂载命令必须显式带
--ro(或-r),不能依赖默认行为——guestmount默认是读写模式 - 挂载点目录需设为
root:root所有者 +0555权限:sudo chmod 0555 /mnt/qcow2-ro,防止非 root 创建子目录或覆盖挂载点 - 挂载后检查是否真只读:
mount | grep qcow2应含ro,字样;尝试echo test > /mnt/qcow2-ro/test必须报Read-only file system
示例命令:
sudo mkdir -p /mnt/qcow2-ro sudo chmod 0555 /mnt/qcow2-ro sudo guestmount -a /opt/images/base.qcow2 -i --ro /mnt/qcow2-ro
更彻底的防护:用 qemu-nbd + loop 设备 + mount -o ro,bind
当需要对镜像做 LVM/NTFS 等复杂分区识别,或要规避 libguestfs 的自动挂载逻辑时,qemu-nbd 更底层可控。但必须严格按顺序执行,漏一步就失效:
- 加载 nbd 模块时指定
max_part=16,否则/dev/nbd0p1等分区节点不会生成 -
qemu-nbd --connect后必须立即执行partprobe /dev/nbd0,否则内核不识别分区表 - 挂载时必须显式加
-o ro,且建议再加noatime,nodiratime减少元数据写尝试 - 最后用
mount --bind -o remount,ro /mnt/nbd-root二次锁定,防止后续 remount rw
关键命令链:
sudo modprobe nbd max_part=16 sudo qemu-nbd --connect=/dev/nbd0 /opt/images/base.qcow2 sudo partprobe /dev/nbd0 sudo mkdir -p /mnt/nbd-root sudo mount -o ro,noatime,nodiratime /dev/nbd0p1 /mnt/nbd-root sudo mount --bind -o remount,ro /mnt/nbd-root
容易被忽略的破坏点:libvirt 自动写入与快照残留
即使你本地所有挂载都设为只读,若该 qcow2 被 libvirt 定义为某虚拟机的磁盘,且该虚拟机曾启用快照功能,则 qemu-img info base.qcow2 可能显示 backing file 指向自身或空路径——这是快照链损坏的征兆,会导致后续 qemu-img commit 或 rebase 操作意外覆写母盘。
验证与清理方法:
- 运行
qemu-img check -r all base.qcow2,若报 “ERROR cluster XXXX refcount=0” 则已损坏,不可再用作母盘 - 确认无快照依赖:
qemu-img snapshot -l base.qcow2输出应为空;若有,先用qemu-img snapshot -d删除 - 终极保险:将母盘文件所在目录挂载为只读文件系统,例如
sudo mount -o remount,ro /opt/images
真正的“金牌母盘”不是靠一个命令实现的,而是靠挂载策略、权限控制、快照管理、宿主文件系统挂载选项四层叠加。漏掉任意一层,都可能在某次误操作中静默覆写。


















