如何实现Ubuntu磁盘的取证级只读启动?overlayroot方案未达预期效果
我来帮你拆解这个问题——你已经尝试用overlayroot把Ubuntu系统设为tmpfs叠加层启动,本以为这样磁盘会完全只读,但重启后发现/dev/rdisk5s2的SHA512校验和还是变了,这确实挺闹心的,毕竟取证级只读要求磁盘不能有任何写入操作对吧?
先搞清楚:为什么overlayroot没拦住写入?
你用的overlayroot=tmpfs确实会把系统的可写层放到内存tmpfs里,但有几个可能的漏网之鱼导致磁盘仍被写入:
- 目标分区没被overlay覆盖:你的
/dev/rdisk5s2大概率不是根分区,而是EFI分区、swap分区或者单独的数据分区——这些分区不在overlay的保护范围内,系统某些进程(比如引导更新、swap交换)会直接往里面写数据。 - overlayroot未完全生效:如果重启后根分区实际还是以读写模式挂载(可以用
mount | grep /查看),那overlay的只读层根本没起作用。 - 文件系统元数据写入:比如ext4的日志功能,即使挂载为只读,极端情况下内核可能仍会更新日志(不过这种情况很少见)。
一步步实现取证级只读启动
第一步:确认overlayroot真的生效
重启后先跑这条命令,检查根分区的挂载状态:
mount | grep overlay
正常输出应该能看到类似overlay on / type overlay (rw,relatime,lowerdir=/media/root-ro,upperdir=/media/root-rw/upper,workdir=/media/root-rw/work)的内容,同时原根分区(比如/dev/rdisk5s1)应该是ro(只读)模式挂载的。如果没看到,说明overlayroot配置有问题,重新检查/etc/overlayroot.conf的设置,确保overlayroot="tmpfs"没有拼写错误。
第二步:锁定所有磁盘分区的写入权限
针对你测试中校验和变化的/dev/rdisk5s2,先搞清楚它是什么分区:
lsblk -f /dev/rdisk5s2
根据结果对应处理:
- 如果是swap分区:直接禁用swap,因为swap会持续写入磁盘:
sudo swapoff -a sudo sed -i '/swap/d' /etc/fstab - 如果是EFI分区/数据分区:把它改成只读挂载,编辑
/etc/fstab添加或修改对应的挂载行:
替换/dev/rdisk5s2 /mnt/your-mount-point ro 0 0/mnt/your-mount-point为实际的挂载路径,然后重新挂载:sudo mount -o remount,ro /dev/rdisk5s2 - 如果是其他系统分区:确保它被overlay覆盖,或者同样设为只读。
第三步:加固内核级只读保障
在GRUB启动参数里添加ro,强制根分区以只读模式启动,叠加overlayroot的保护:
- 编辑GRUB配置文件:
sudo nano /etc/default/grub - 找到
GRUB_CMDLINE_LINUX_DEFAULT行,在quiet splash后面加上ro overlayroot=tmpfs,比如:GRUB_CMDLINE_LINUX_DEFAULT="quiet splash ro overlayroot=tmpfs" - 更新GRUB:
sudo update-grub
第四步:禁用所有可能写入磁盘的服务
比如日志服务、自动更新服务,或者把日志目录挂载到tmpfs:
# 临时挂载日志目录到tmpfs sudo mount -t tmpfs tmpfs /var/log # 永久生效,加到/etc/fstab echo "tmpfs /var/log tmpfs defaults 0 0" | sudo tee -a /etc/fstab
同时禁用logrotate、rsyslog这类会写磁盘的服务:
sudo systemctl disable --now logrotate rsyslog
终极方案:硬件级磁盘只读
如果上面的软件层面设置还不够,可以直接把整个磁盘设为只读:
sudo blockdev --setro /dev/rdisk5
这个命令会让磁盘硬件层面拒绝所有写入请求,适合严格的取证场景。不过要注意,执行后磁盘完全不能写入,包括任何分区操作,需要恢复时再用blockdev --setrw /dev/rdisk5改回来。
再验证你的校验和
做完上面的设置后,重启系统,先跑一遍openssl dgst -sha512 /dev/rdisk5s1 /dev/rdisk5s2记录校验和,然后正常操作一段时间,再重启跑一遍,应该就能看到两个分区的校验和都保持不变了。
备注:内容来源于stack exchange,提问作者sunknudsen

