引言:一个 rm -rf 引发的血案
曾经有一个实习生,因为 Nginx 报错 “403 Forbidden”,一怒之下对整个 /var/www 目录执行了 chmod -R 777。
第二天,服务器变成了“肉鸡”。黑客上传了一个 PHP Webshell,因为这台机器上的任何用户(包括 nobody)都有写入权限。
Linux 的权限系统 (UGO) 设计得非常精妙,它是在多用户环境下保障系统安全的最底层防线。
无脑 777,等于把防线炸了个缺口。
一、UGO 模型与数字权限法
Linux 文件权限分为三组:
- User (u):文件所有者。
- Group (g):文件所属组。
- Others (o):其他人。
每组有三种权限:
- Read (r=4):读文件内容 / 列出目录内容 (
ls)。 - Write (w=2):修改文件内容 / 在目录中创建或删除文件。
- Execute (x=1):执行脚本 / 进入目录 (
cd)。
关键点:对目录有 w 权限,意味着你可以删除里面的文件,即使那个文件不属于你!这就是为什么 777 目录极其危险。
1.1 常见场景的最佳实践
- 配置文件 (
.conf):644(rw-r--r--)。管理员可写,程序可读,闲人免进。 - Web 目录:
755(rwxr-xr-x)。Nginx 需要x才能进入目录读取文件。 - 私钥文件 (
id_rsa):600(rw-------)。SSH 客户端会强制检查这个,如果权限太开放,它会拒绝连接。 - 可执行脚本:
755或700。
二、chown:被忽视的利器
很多时候 Permission denied 不是因为权限不够宽,而是归属权错了。
场景:你用 root 账号 git pull 了代码,然后 Nginx (运行在 www-data 用户下) 报错写不进去日志。
错误做法:chmod 777 logs。
正确做法:chown -R www-data:www-data logs。
把文件的所有权还给运行该服务的用户,这才是正道。
三、特殊权限位:SUID, SGID, Sticky Bit
除了 rwx,还有三个特殊的位。
3.1 Sticky Bit (粘滞位, t)
场景:/tmp 目录。
所有用户都需要在里面创建临时文件,所以它是 777。
但是,我不希望张三能删除李四的文件。
这就是 Sticky Bit 的作用。
设置了 +t 的目录(drwxrwxrwt),只有文件所有者(和 root)才能删除该文件。
chmod +t /tmp3.2 SUID (Set UID, s)
场景:passwd 命令。
普通用户修改密码需要修改 /etc/shadow 文件,但该文件只有 root 能写。
passwd 命令被设置了 SUID。
当普通用户执行它时,进程的有效用户 ID (EUID) 会瞬间变成文件的所有者 (root)。
ls -l /usr/bin/passwd# -rwsr-xr-x 1 root root ...危险:如果你给 vim 或 python 设置了 SUID,普通用户就能用它提权变成 root。
四、ACL (Access Control Lists):超越 UGO
UGO 模型有个局限:一个文件只能属于一个组。 如果你想让:
- User A (Owner): rwx
- User B: r—
- User C: rw- (但他不属于 Group A)
这就需要 ACL。
setfacl -m u:userC:rw filenamegetfacl filenameACL 允许你对任意个用户、任意个组设置精细的权限。虽然增加了管理复杂度,但在文件服务器(Samba/NFS)场景下非常有用。
五、chattr:上帝之锁
有些时候,哪怕是 root 也不应该误删文件(比如数据库文件)。
chattr (Change Attributes) 可以在文件系统层面锁定文件。
chattr +i critical_data.db+i (Immutable):不可变。
即使是 root,也无法删除、重命名、修改这个文件。
想删?必须先 chattr -i 解锁。这对抗击“删库跑路”有奇效。
总结
Linux 权限管理是一门防御的艺术。
- 最小权限原则 (Least Privilege) 是核心心法。
- 遇到权限问题,先看
ls -l,再看ps aux(进程用户),最后才考虑chmod。 - 永远,永远,不要在生产环境敲下
chmod 777。那是对系统的亵渎。