Appearance
权限管理
Linux 的文件访问控制以 UGO(user/group/other)为基础,按需配合 ACL、特殊权限位和扩展属性。
一、UGO 权限模型
每个文件有三组权限,分别对应三类身份:
| 身份 | 含义 |
|---|---|
| User(owner) | 文件的所有者 |
| Group | 文件所属组的成员 |
| Other | 既不是 owner 也不属于 group 的所有人 |
权限判断的顺序是 owner → group → other,命中即停。这意味着:即使属于文件 group 且有组权限,如果自己就是 owner,那只看 owner 权限位,group 部分被跳过。
另一个容易被忽略的规则:访问文件需要路径上每一级目录都有 x(执行)权限。目录没有 x,就算文件本身权限是 777 也进不去。
ls -l 的输出:
-rw-r----- 1 nginx adm 1024 May 21 10:00 app.log逐段拆开:
| 部分 | 含义 |
|---|---|
- | 文件类型,- 表示普通文件 |
rw- | owner(nginx)有读和写权限 |
r-- | group(adm)只有读权限 |
--- | other 没有任何权限 |
nginx | 文件所有者 |
adm | 文件所属组 |
权限位对文件和目录的意义不同:
| 权限 | 作用于文件 | 作用于目录 |
|---|---|---|
r(读) | 查看文件内容 | 列出目录中的文件名(ls 可行) |
w(写) | 修改文件内容 | 在目录中创建、删除、重命名文件 |
x(执行) | 作为程序运行 | 进入目录(cd 可行) |
目录的 w 权限要特别注意:有 w 权限就能删除目录中的任何文件,即使这个文件不属于自己(前提是目录的 w 权限对自己开放)。/tmp 就是典型——每个人都能在里面创建文件,也能删别人的文件,所以 /tmp 一般会加 Sticky Bit 限制删除权限。
二、chmod 修改权限
数字模式用三位八进制数表示权限。r=4、w=2、x=1,相加组合。
bash
chmod 644 file.txt # owner 读写,其余只读
chmod 755 script.sh # owner 全权限,其余读+执行
chmod 750 /opt/app # owner 和 group 可用,other 无权限
chmod 600 private.key # 仅 owner 读写| 八进制 | 组合 | 权限含义 |
|---|---|---|
| 7 | 4+2+1 | 读+写+执行 |
| 6 | 4+2 | 读+写 |
| 5 | 4+1 | 读+执行 |
| 0 | — | 无权限 |
符号模式适合做增量修改:
bash
chmod u+x script.sh # owner 加执行权限
chmod g+w shared-dir # group 加写权限
chmod o-r file.txt # other 去掉读权限
chmod +x deploy.sh # 所有身份加执行(等同 a+x)私钥文件(SSH key、TLS 密钥)、含密码的配置文件,权限至少 600。权限过宽(如 644、777)时,某些服务(如 sshd)会拒绝使用并报错。
三、chown 修改所有者
bash
chown nginx:nginx /var/log/nginx/access.log
chown -R app:app /opt/app # 递归修改chown -R 和 chmod -R 的递归会影响整个目录树。路径打错时破坏面很大——特别是 /etc、/var 等系统目录。执行前先 pwd 加 ls -ld 确认。
四、umask 默认权限
umask 决定新建文件和目录时,默认减掉哪些权限位。它不直接设置权限,而是设置一个"掩码"——从满权限里扣除。
bash
umask # 查看当前值
umask 022 # 设置为 022常见默认结果:
| umask | 新建文件实际权限 | 新建目录实际权限 |
|---|---|---|
022 | 644(rw-r--r--) | 755(rwxr-xr-x) |
027 | 640(rw-r-----) | 750(rwxr-x---) |
077 | 600(rw-------) | 700(rwx------) |
注意新建文件默认不会得到执行权限(x),因为大多数文件不需要可执行。服务进程创建出来的日志文件权限与预期不符时,除了检查程序代码中的权限设置,也要看启动用户的 umask。
五、ACL 访问控制列表
UGO 只能表达三类身份。当需要"文件属于 app 组,但同时让 deploy 用户有只读权限"这种例外时,ACL 可以单独授权。
bash
getfacl file.txt # 查看文件 ACL
setfacl -m u:deploy:r file.txt # 给 deploy 用户加只读
setfacl -m g:ops:rx /opt/app # 给 ops 组加读和执行
setfacl -x u:deploy file.txt # 删除 deploy 用户的 ACL 条目
setfacl -b file.txt # 清空所有 ACL,回到纯 UGOACL 适合少量例外场景。如果系统里到处在用 ACL 管理权限,排查时只看 ls -l 会漏掉很多信息,维护成本上升很快。
六、SUID、SGID、Sticky Bit
这三个特殊权限位在 ls -l 中会替代通常的 x 位置显示。
SUID(Set UID):文件执行时,进程临时获得文件 owner 的权限。
bash
ls -l /usr/bin/passwd
# -rwsr-xr-x 注意 owner 权限位中的 s/usr/bin/passwd 是典型例子:普通用户执行它时要修改 /etc/shadow(仅 root 可写),靠 SUID 临时提权完成。SUID 权限安全风险较高,系统中出现的 SUID 文件都应该被确认是预期的。
SGID(Set GID):设在目录上时,该目录下新建的文件自动继承目录的所属组,而非创建者的主组。
bash
chmod g+s shared-dir多人协作的共享目录常用 SGID,确保所有人创建的文件都属于同一个组。
Sticky Bit:设在目录上时,只有文件 owner、目录 owner 和 root 能删除目录中的文件,其他人即使有目录写权限也不能删别人的文件。
bash
ls -ld /tmp
# drwxrwxrwt 注意 other 权限位中的 t
chmod +t shared-dir/tmp 设了 Sticky Bit——所有用户都能在里面创建临时文件,但不能删除别人的文件。
七、chattr 扩展属性
chattr 设置的属性作用于文件系统层面,比普通权限更底层。
bash
chattr +i important.conf # 设为不可修改(immutable)
lsattr important.conf # 查看扩展属性
chattr -i important.conf # 去掉不可修改属性+i(immutable)之后,即便是 root 用户也不能修改、删除、重命名该文件,也不能创建硬链接。必须先 chattr -i 去掉属性才能操作。
另一个有用的属性是 +a(append only):只允许向文件追加内容,不能覆盖已有内容,适合保护日志文件不被误删。
线上遇到过的情况:自动化部署脚本修改配置文件失败,排查很久才发现配置文件被加了 +i 属性——可能是之前某次临时加固时设的,后来忘了去掉。所以改不动文件时,lsattr 值得一看。