场景引入:那次我差点把公司数据库删了
几年前接手一台老服务器,/home分区快满了。同事说"清理一下日志吧"。我习惯性敲了 rm -rf /var/log/*,发现有几个日志文件压根删不掉。提示"Operation not permitted"(操作不允许)。当时冷汗都出来了,以为文件系统坏了。老同事看了一眼,笑着说:"看看lsattr,上面挂+i了。"
这就是 chattr(change attribute,改变文件属性)的威力。它能让关键文件像上了锁一样,root用户来了也动不了。
核心概念:Linux文件属性 vs 文件权限
传统 chmod(change mode,修改文件权限)控制的是"谁可以读/写/执行"。而 chattr 控制的是文件在文件系统层面的行为,比权限更底层。
打个比方:chmod 是门锁上的密码,有密码就能开。chattr 是在门外焊了根铁条,有密码也得先拆铁条。
chattr最常用属性详解
+i(immutable,不可变属性):终极保护
一旦文件被设置 +i 属性:
- ·root 用户也不能修改内容
- ·不能删除或重命名
- ·不能创建硬链接
- ·不能向文件追加数据
适用场景:配置文件(/etc/passwd、/etc/shadow、/etc/ssh/sshd_config)、关键二进制文件、已审计的日志归档。
# 给 /etc/passwd 设置不可变属性,防止被篡改
sudo chattr +i /etc/passwd
# 验证一下,尝试追加内容会报错
echo "test" >> /etc/passwd
# 去掉不可变属性
sudo chattr -i /etc/passwd
+a(append only,仅追加属性):日志防篡改神器
设置了 +a 的文件只能以追加模式写入,不能修改或删除已有内容。
# 给重要日志设置仅追加属性
sudo chattr +a /var/log/secure
# 现在可以追加日志
echo "test log" >> /var/log/secure
# 但无法覆盖或修改已有内容
# 这种操作会直接失败
生产环境里我习惯把 secure、messages、audit.log 这些审计日志都加上 +a。就算黑客拿到 root 权限,他也不能抹掉自己的入侵痕迹。
+e(extent format,范围格式属性)
大部分现代 Linux 文件系统(ext4)上的文件默认就有 +e 属性。它表示文件使用 extent(范围)格式存储,这是一种高效的文件存储方式。
# 查看 /etc/hosts 的属性,通常能看到 e
lsattr /etc/hosts
# 输出类似:----e-------------- /etc/hosts
+u(undeletable,不可删除属性)
设置 +u 属性的文件,即使被删除了,内容也会被保存,可以恢复。不过实际用得不多,我更推荐做好备份。
lsattr:查看文件属性
lsattr(list attributes,列出属性)用来查看文件当前的 chattr 属性。
# 查看单个文件属性
lsattr /etc/passwd
# 递归查看目录下所有文件
lsattr -R /etc/ssh/
# 列出目录本身的属性(默认不显示目录自身)
lsattr -d /etc/
# 查看所有文件,包括隐藏文件
lsattr -a /var/log/
输出结果解读:
第一列是属性字母。没有设置属性就是减号。常见的属性位顺序是:
aAcCdDeFijPsStTu
大多数时候你只看到 i、a、e 这几个。
常用属性集合
| 属性 | 全称 | 作用 |
|---|
| i | immutable | 不可修改、删除、重命名 |
| a | append only | 仅追加,不能修改已有内容 |
| d | no dump | 不会被 dump 备份 |
| S | synchronous | 修改同步写入磁盘(类似 sync) |
| u | undeletable | 删除后可恢复 |
# 给一个配置文件同时设置 i 和 a
sudo chattr +ia /etc/myapp.conf
# 查看设置结果
lsattr /etc/myapp.conf
# 输出类似:-ia--------------e--- /etc/myapp.conf
实际工作中 d 属性有点用:当你用 dump(备份工具)做系统备份时,加了 d 属性的文件会被跳过,适合缓存文件或临时数据。
实操经验:我的一套保护策略
生产服务器上我通常会这样做:
# 保护关键系统文件
sudo chattr +i /etc/passwd
sudo chattr +i /etc/shadow
sudo chattr +i /etc/group
sudo chattr +i /etc/gshadow
sudo chattr +i /etc/ssh/sshd_config
sudo chattr +i /etc/sudoers
# 关键日志文件只允许追加
sudo chattr +a /var/log/secure
sudo chattr +a /var/log/messages
sudo chattr +a /var/log/cron
# 保护启动脚本
sudo chattr +i /etc/rc.d/rc.local
这套组合拳下来,就算服务器被提权到 root,攻击者删不掉 sshd_config 去改端口,也抹不掉登录日志。
安全提醒:chattr不是银弹
chattr 是双刃剑,有几点需要特别注意:
第一,设置 i 属性前确保配置没问题。 曾经有个同事给 Nginx 配置文件加 i 后,发现配错了,改不了。只能重启到单用户模式用 chattr -i 解除。如果你在远程 SSH 连接重启配置服务,改了配置没法写回去,服务挂了就断了。
第二,内核参数 fs.protected_regular 会影响操作。 新版 Linux 内核加了额外保护,某些场景下即使去掉 i 属性也可能报错。
第三,chroot 和 Live CD 可以绕过。 如果攻击者有物理接触,挂载硬盘进 Live CD 修改,chattr 根本拦不住。它防的是远程攻击者,不是物理攻击。
第四,解除属性需要 CAP_LINUX_IMMUTABLE 权限。 Docker 容器默认没有这个权限,在容器里想用 chattr 会失败。
解除属性和常见错误
# 去掉 i 属性
sudo chattr -i /etc/passwd
# 去掉所有额外属性
sudo chattr = /etc/passwd
# 常见错误:没有权限
chattr +i /etc/passwd
# 报错:chattr: Operation not permitted
# 原因:普通用户不能设置属性,必须 sudo
最佳实践:先 lsattr 看一眼再动手。养成习惯,就像 rm 之前先 ls 确认一样。
适用场景总结
- ·SSH 配置保护:sshd_config 加 i,防止被改端口和密钥认证
- ·日志审计:secure、audit.log 加 a,保证攻击痕迹可追溯
- ·二进制加固:/usr/bin/ 下关键命令加 i,防止被替换为恶意版本
- ·网站文件保护:Web 目录下 index.php 等关键文件加 i,防 webshell 篡改
- ·容器镜像:Dockerfile 里对敏感配置用 chattr,增加一层纵深防御
chattr 是 Linux 管理员工具箱里被低估的一把锁。多数人只在被入侵后才后悔:"早知道当时加个 i"。现在知道还不晚,去给你的关键文件上个保险吧。