共计 3442 个字符,预计需要花费 9 分钟才能阅读完成。
文章目录[显示]
Linux 系统里,权限是安全的基石。你在服务器上建了个文件,谁能读、谁能写、谁能执行——这些事情搞不清楚,轻则脚本跑不起来,重则数据被人随意篡改。这篇文章从基础的 rwx 权限讲起,一路聊到 SUID、SGID、Sticky Bit 这些 " 高级货 ",再把 umask 和 ACL 也捋一遍。读完之后,你对 Linux 权限体系会有一个完整、扎实的认知。
rwx 权限基础
Linux 中每个文件和目录都有三组权限,分别对应三类用户:
- Owner(属主):文件的拥有者
- Group(属组):文件所属用户组的成员
- Others(其他人):既不是属主也不在属组中的所有用户
每组权限由三个标志位组成:
| 标志 | 含义 | 对文件的作用 | 对目录的作用 |
|---|---|---|---|
| r | 读 | 查看文件内容 | 列出目录下的文件名 |
| w | 写 | 修改文件内容 | 在目录中创建、删除文件 |
| x | 执行 | 以程序方式运行 | 进入(cd)该目录 |
用 ls -l 查看时,你会看到类似 -rwxr-xr-- 这样的字符串。第一个字符表示文件类型(- 普通文件、d 目录),后面每三个字符一组,分别是属主、属组、其他人的权限。
数字表示法
每个标志位对应一个数字:r=4,w=2,x=1。三个位加起来就是一组权限的数值。
rwx = 4+2+1 = 7
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
所以 rwxr-xr-- 对应 754
记住这个换算规则,后面用 chmod 设置权限时会频繁用到。
chmod:修改权限
chmod 有两种用法——符号模式和数字模式。
数字模式,简单直接:
# 属主可读写执行,属组可读执行,其他人只读
chmod 754 myfile.sh
# 所有人都能读写
chmod 666 data.txt
符号模式,更灵活,适合只改某一组权限的场景:
# 给属主加上执行权限
chmod u+x script.sh
# 去掉其他人的写权限
chmod o-w config.yml
# 给属组设置为只读
chmod g=r document.txt
# 同时操作多组
chmod u+x,g-w,o-r myfile
加个 -R 参数可以递归修改目录下所有文件:
chmod -R 755 /var/www/html
坦白说,日常用数字模式的频率更高,因为三个数字一写,权限一目了然。
chown 和 chgrp:修改归属
权限决定 " 能做什么 ",归属决定 " 对谁生效 "。
# 修改属主
chown alice myfile.txt
# 同时修改属主和属组
chown alice:developers myfile.txt
# 只修改属组(两种写法)chgrp developers myfile.txt
chown :developers myfile.txt
# 递归修改整个目录
chown -R www-data:www-data /var/www
一个常见场景:你用 root 部署了 Web 应用的文件,但 Nginx 是以 www-data 用户运行的。如果不用 chown 把文件归属改过来,Nginx 根本读不到文件,页面直接报 403。
特殊权限:SUID、SGID、Sticky Bit
基础的 rwx 能解决大部分问题,但有些场景需要更精细的控制。这就是特殊权限存在的意义。
SUID(Set User ID)
作用对象:可执行文件。
效果:无论谁执行这个文件,执行时都临时获得文件属主的权限。
最经典的例子是 passwd 命令。普通用户修改密码时需要写 /etc/shadow,但这个文件只有 root 能写。passwd 程序设置了 SUID 位,所以普通用户执行它时,进程以 root 身份运行,就能完成密码修改。
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
# ^-- 注意这里是 s 而不是 x
# 设置 SUID
chmod u+s myprogram
chmod 4755 myprogram # 数字模式下,千位的 4 代表 SUID
SUID 很强大,但也很危险。如果一个 root 拥有的脚本被设了 SUID 又有漏洞,攻击者可以借此拿到 root 权限。所以不要随便给文件加 SUID,定期用 find / -perm -4000 审计一下系统里有哪些 SUID 文件,是个好习惯。
SGID(Set Group ID)
对可执行文件:执行时临时获得文件属组的权限,原理和 SUID 类似。
对目录:这才是 SGID 更常用的场景。在设了 SGID 的目录下创建的新文件,会自动继承目录的属组,而不是创建者的默认属组。
想象一个团队共享目录:Alice 和 Bob 都属于 project 组。如果目录没有 SGID,Alice 创建的文件属组是她的默认组(可能是 alice),Bob 未必能访问。设了 SGID 之后,新文件的属组自动变成 project,协作就顺畅了。
# 给目录设置 SGID
chmod g+s /shared/project
chmod 2775 /shared/project # 千位的 2 代表 SGID
Sticky Bit
作用对象:目录。
效果:目录里的文件只有文件属主、目录属主或 root 才能删除,其他人即使对目录有写权限也删不了别人的文件。
/tmp 目录就是典型——所有用户都能在里面创建文件,但你不能删我的,我也不能删你的。
ls -ld /tmp
# drwxrwxrwt ... /tmp
# ^-- t 就是 Sticky Bit
chmod +t /shared
chmod 1777 /shared # 千位的 1 代表 Sticky Bit
把三个特殊权限的数字总结一下:SUID=4,SGID=2,Sticky=1,加在普通三位数字前面作为第四位(千位)。chmod 4755 就是 SUID + rwxr-xr-x。
umask:控制默认权限
你有没有想过,为什么新建文件默认是 644,新建目录默认是 755?这就是 umask 在起作用。
系统创建文件时,理论最大权限是 666(文件)和 777(目录)。umask 是一个 " 掩码 ",用来从最大权限中 " 减掉 " 某些位。
umask
# 0022(常见默认值)# 文件默认权限 = 666 - 022 = 644 (rw-r--r--)
# 目录默认权限 = 777 - 022 = 755 (rwxr-xr-x)
严格来说这不是简单的算术减法,而是按位取反再做与运算,但 " 用最大权限减去 umask" 在大多数场景下结果一致,好记也好用。
# 临时修改 umask
umask 027
# 新文件: 666 - 027 = 640 (rw-r-----)
# 新目录: 777 - 027 = 750 (rwxr-x---)
# 永久修改:写入 ~/.bashrc 或 /etc/profile
echo "umask 027" >> ~/.bashrc
对于服务器来说,把 umask 设为 027 比默认的 022 更安全——直接砍掉了其他人的所有权限。
ACL:更精细的权限控制
传统的属主 / 属组 / 其他人三级权限有个明显短板:只能给一个用户和一个组设权限。如果你想让 Alice 能读写、Bob 只能读、Charlie 完全没权限——靠基础权限做不到。
ACL(Access Control List,访问控制列表)就是为了解决这个问题。
# 给用户 bob 设置只读权限
setfacl -m u:bob:r-- project.doc
# 给 devops 组设置读写权限
setfacl -m g:devops:rw- deploy.sh
# 查看 ACL
getfacl project.doc
# file: project.doc
# owner: alice
# group: staff
user::rw-
user:bob:r-- # Bob 的专属权限
group::r--
group:devops:rw- # devops 组的专属权限
mask::rw-
other::---
几个要点:
- mask 是 ACL 权限的上限。即使你给 Bob 设了 rwx,如果 mask 是 r–,Bob 实际只有读权限。用
setfacl -m m::rwx file可以调整 mask。 - 默认 ACL 用
-d参数设置,对目录下新创建的文件自动生效:
setfacl -d -m g:devops:rw- /shared/project
ls -l看到权限末尾有个+号,说明该文件带有 ACL 规则。- 用
setfacl -b file可以清除文件上所有的 ACL。
ACL 在多团队协作的服务器上特别有用,它弥补了传统权限模型 " 粒度太粗 " 的不足。不过如果能用组权限解决的问题,就别上 ACL,保持简单永远是好事。
总结
Linux 权限体系可以分成四个层次来理解:基础权限 (rwx + 数字表示法)解决 " 谁能做什么 " 的问题; 归属管理 (chown/chgrp)决定权限对谁生效; 特殊权限(SUID/SGID/Sticky Bit)处理那些基础权限搞不定的场景;umask 和 ACL 则分别控制默认行为和精细化授权。
掌握这四层,日常的权限管理基本不会再让你头疼。