Linux设置文件只读分四层:chmod仅防普通用户,chattr +i内核级锁死连root也无法修改,mount -o ro锁定整个挂载点,lvchange -p r在LVM层禁写;选错层级将导致防护失效或运维受阻。

Linux 中“设置文件为只读”不是单一操作,而是分层防护:普通用户防误改用 chmod,防 root 误删/覆盖用 chattr +i,防整个挂载点写入用 mount -o ro。选错层级会导致该锁不住、该放行的被拦住。
chmod 444 只对普通权限生效,root 仍可改删
这是最常用也最容易误解的方式。chmod 444 file 或 chmod a=r file 仅移除所有用户的写位(w),但 root 用户不受此限——只要父目录有写权限,root 就能 rm、mv、echo > file 覆盖它。
- 适用场景:临时限制普通用户编辑配置文件,或配合用户组隔离使用
- 不适用场景:保护关键私钥、证书、系统配置等需防 root 误操作的文件
- 验证方式:
ls -l file输出应为r--r--r--;但sudo echo test > file仍会成功 - 注意:
chmod -R 444 dir/会让目录不可进入(缺少执行 x 权限),应改用chmod 555 dir保留目录遍历能力
chattr +i 是真正的“硬只读”,连 root 也得先解锁
chattr +i 设置的是文件系统级不可变属性,内核在 write 系统调用阶段就拦截,优先级高于一切 POSIX 权限。加了 i 的文件,root 也无法修改、删除、重命名、硬链接、软链接指向它,甚至无法用 vim 或 sed -i 编辑(会报 Operation not permitted)。
- 必须用 root 执行:
sudo chattr +i /etc/ssl/private/server.key - 验证是否生效:
lsattr /etc/ssl/private/server.key输出末尾含i - 目录加
+i后,禁止在其中新建/删除/重命名任何文件(哪怕子文件本身没加i) - 常见坑:脚本批量处理前未
lsattr扫描,遇到+i文件直接中断;容器中常因 CAP_LINUX_IMMUTABLE 被禁用而失败
mount -o ro 锁定整个挂载点,适合归档盘或 NFS 共享
当你要保护的不是单个文件,而是一整块设备(如备份盘、只读镜像、NFS 挂载点),mount -o ro 是更自然的选择。它让整个挂载点下所有文件和目录都拒绝写入,且不依赖单个文件属性。
- 临时挂载为只读:
sudo mount -o ro /dev/sdb1 /mnt/archive - 已挂载后重挂为只读(需文件系统支持 remount):
sudo mount -o remount,ro /mnt/archive - 若 remount 失败,说明底层文件系统损坏或不支持(如某些只读 squashfs 无法 remount 为 rw),只能先
umount再重新挂载 - fstab 持久化:
UUID=abcd-1234 /mnt/archive ext4 defaults,ro 0 2,之后sudo mount -a测试
lvchange -p r 在 LVM 层锁定逻辑卷写入
对使用 LVM 管理的归档卷(如 /dev/vg0/archive_lv),lvchange -p r 提供了一种快速、无损、不涉及文件系统的只读控制。它不改动文件系统结构,只是让内核拒绝向该 LV 发起任何写 I/O 请求。
- 前提:逻辑卷必须未挂载,且无进程占用(
lsof +D /mount/point或fuser -v /mount/point确认) - 启用:
sudo lvchange -p r /dev/vg0/archive_lv - 验证:
sudo lvs -o+attr vg0/archive_lv中 Attr 字段从iw变为ir - 恢复可写必须显式执行:
sudo lvchange -p w /dev/vg0/archive_lv,不会自动回退 - 优势:比
chattr -R +i更快(不用递归扫描 inode),且不影响文件系统日志或一致性检查
真正难的不是“怎么设”,而是判断该在哪一层设:chmod 是门把手,chattr 是焊死的锁,mount -o ro 是封楼,lvchange -p r 是切断整栋楼的供电。设错一层,要么形同虚设,要么让合法运维寸步难行。


















