Skip to content

权限管理

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=4w=2x=1,相加组合。

bash
chmod 644 file.txt       # owner 读写,其余只读
chmod 755 script.sh      # owner 全权限,其余读+执行
chmod 750 /opt/app       # owner 和 group 可用,other 无权限
chmod 600 private.key    # 仅 owner 读写
八进制组合权限含义
74+2+1读+写+执行
64+2读+写
54+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 -Rchmod -R 的递归会影响整个目录树。路径打错时破坏面很大——特别是 /etc/var 等系统目录。执行前先 pwdls -ld 确认。

四、umask 默认权限

umask 决定新建文件和目录时,默认减掉哪些权限位。它不直接设置权限,而是设置一个"掩码"——从满权限里扣除。

bash
umask             # 查看当前值
umask 022         # 设置为 022

常见默认结果:

umask新建文件实际权限新建目录实际权限
022644(rw-r--r--)755(rwxr-xr-x)
027640(rw-r-----)750(rwxr-x---)
077600(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,回到纯 UGO

ACL 适合少量例外场景。如果系统里到处在用 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 值得一看。