news 2026/10/2 4:22:21

Linux权限管理详解:从rwx到ACL,彻底搞懂chmod与目录权限

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux权限管理详解:从rwx到ACL,彻底搞懂chmod与目录权限

你有没有遇到过这种情况:明明chmod 777都给了,用户还是报“权限不足”;或者删不掉一个文件,ls -l一看自己明明有w权限,却提示Operation not permitted。如果你对这些现象背后的逻辑一知半解,那这篇关于 Linux 基本权限的梳理应该能帮你把整条线串起来。

我最早是从 Windows 带过来的习惯,总觉得权限就是“勾选一下”那么简单,后来真上了生产环境,被rwx、属主、属组这些概念折腾了好几回,才慢慢摸清楚。这篇文章我不会照抄手册,而是按照我自己排查问题、设计权限方案时的思考路径来写:先讲清楚rwx在文件和目录上的本质区别,再拆解chmod/chown/chgrp实操中的易错点,接着延伸到 SUID/SGID/Sticky Bit 这套特殊权限机制,然后聊聊 umask 对默认权限的影响,最后补上 ACL、root 与排查流程。无论你是刚接触 Linux 的新手,还是需要处理服务器权限问题的一线运维,这篇都值得花十几分钟过一遍。

1. rwx 三元组:文件与目录的权限语义完全不同

1.1 权限位到底是给谁看的

Linux 的权限模型本质上是给“三类身份”分别设置“三种操作能力”。三类身份分别是:文件的属主(owner,常用u表示)、属组(group,常用g表示)、其他人(others,常用o表示)。三种操作能力就是读(read,r)、写(write,w)、执行(execute,x)。

用ls -l查看一个文件时,第一列那 10 个字符就是权限的“门牌”:

-rwxr-xr-- 1 root root 1234 Feb 14 10:00 test.sh

第一个字符表示文件类型,-是普通文件,d是目录,l是软链接。后面 9 个字符每 3 个一组,分别对应属主、属组、其他人的权限。上面的例子就是:属主可读可写可执行,属组可读可执行,其他人只可读。

很多新手会背“r=4,w=2,x=1,加起来是 7”,但为什么是这个数字?这里我建议你用二进制的思路去理解:每个权限位其实就是一个 bit,1 代表有权限,0 代表没有。rwx对应二进制111,转成十进制正好是 7;rw-对应110,是 6;r--是100,是 4。这么一想,chmod 755和chmod 754就不再是魔法数字了,而是“我想把哪些 bit 打开”的直观表达。

1.2 目录的 w 权限才是“删除文件”的关键

这里我必须先讲一个最容易被误解的点:一个文件能不能被删除,取决于它所在目录的写权限,而不是文件自身的写权限。

很多人第一次遇到这种情况都会懵:我明明对文件有rw权限,怎么rm的时候系统告诉我“Permission denied”?原因很简单,rm这个操作本质上不是在“修改文件”,而是在“修改目录的目录项”。你要把文件名从目录的列表里摘掉,操作系统检查的是你对这个目录有没有写权限。所以,如果你对某个文件只有r权限,但对它所在目录有w权限,你依然可以把这个文件删掉。

目录的r权限决定你能不能列出目录里的文件名(ls),x权限决定你能不能进入目录(cd)以及能否访问其中文件。这里有个更隐蔽的坑:如果你对一个目录只有r权限而没有x权限,那ls确实能看到文件名,但当你尝试访问文件内容或使用stat查看详细信息时,系统可能报错。因为x权限在目录上的语义是“可通行”,没有它,你对目录内容的访问无法“深入”。

1.3 文件权限的“重命名与硬链接”边界

既然说到目录写权限的重要性,顺便提一个和重命名、硬链接相关的知识点。重命名文件同样属于修改目录项的操作,所以能否重命名也取决于目录权限,而不是文件权限。

硬链接是另一个容易让人疑惑的地方。硬链接的本质是在另一个目录里新增一个目录项,指向同一个 inode。因此,创建硬链接时,你不能跨文件系统,而且通常需要你对目标目录有写权限。如果你在一个目录里尝试给别人的文件创建硬链接,但该目录没有w权限,一样会失败。

我把文件与目录的权限语义差异整理成一个对照表,方便你记忆:

权限位文件语义目录语义
r读取文件内容列出目录中的文件名(ls)
w修改文件内容在目录中创建、删除、重命名文件
x将文件作为程序执行进入目录(cd),访问目录内文件
常见坑修改文件用 w,执行用 x删除文件看目录 w,进入目录看 x

2. chmod / chown / chgrp 实操拆解:命令背后的易错点

2.1 chmod 数字法与符号法各自的应用场景

chmod是调整权限最常用的命令,它有两种写法,对应不同习惯。

数字法的好处是简洁、可批量:

chmod 750 script.sh

这句命令把script.sh设置为:属主rwx,属组r-x,其他人无权限。它特别适合在脚本里批量处理,或者按固定的权限模板给一批文件套用。

符号法的好处是精确、不用心算:

chmod u+x script.sh # 给属主加执行权限 chmod g-w,o-r file.txt # 属组去掉写权限,其他人去掉读权限 chmod a+r file.txt # 给所有人加读权限

我自己的经验是:交互式操作时用符号法居多,因为不需要做加法;但在批量部署脚本、需要把权限状态固化下来的场景,用数字法更稳妥。有一点要特别注意:用数字法给目录赋值时,chmod -R 755 /some/dir会把目录下所有文件也统一改成755,但有些可执行文件并不需要被“所有人执行”,这一下可能把权限面放大。谨慎的做法是先find区分文件和目录再分别处理,或者用下面的chmod参数来区分操作对象:

chmod -R u+rwX,go+rX /some/dir

注意大写X,它表示“仅当目标本身已是目录或已有执行权限的文件时,才赋予执行权限”。这条命令在实际部署中非常实用,它能避免可执行位被无脑放大。

2.2 chown 和 chgrp:修改归属时的身份限制

chown用来改属主,chgrp用来改属组。现代 Linux 里,我一般直接用一条chown同时改两者,格式是属主:属组:

chown alice:developers project/ chown -R alice:developers project/

几个容易踩的坑:

第一,普通用户通常不能把自己的文件chown给别人,只有 root 能做。这个限制是内核级别的,目的是防止用户通过“把文件丢给 root”来绕开配额或审计。如果遇到Operation not permitted,先反省一下是不是没加 sudo。

第二,chown会同时清除文件的 SUID/SGID 特殊权限位。原因很好理解:切换属主之后,原来的 SUID 语义可能形成权限提升漏洞,内核出于安全考虑直接把这些位清掉。所以,如果你发现某个程序在执行chown后特殊权限丢了,这不是 bug,是保护机制。

第三,chgrp虽然单独存在,但功能其实被chown user:group覆盖了。你可以把文件属组改成你所在的任何组,但不能改成你不在的组(除非有 root 权限)。

2.3 实战案例:从零搭建一个团队共享目录

这里我以一个常见的需求为例,演示完整的权限设计过程。场景:服务器上有一个/data/team_project目录,团队成员都在devteam组中,要求组内成员可以读、写、进入,但不能随意删除别人的文件;其他用户完全不可见。

第一步,创建目录并设置属组:

sudo mkdir -p /data/team_project sudo chown root:devteam /data/team_project sudo chmod 2770 /data/team_project

这里2770的前置2是 SGID 位。目录设置了 SGID 后,所有在目录内新建的文件/子目录会自动继承目录的属组(devteam),而不是创建者的主组。这一步对团队协作至关重要,否则新文件可能带着个人主组,其他组员就没有访问权限了。

第二步,让子目录也继承组并限制删除他人文件:

sudo chmod g+s /data/team_project/subdir

其实只要你设置目录时用了带 SGID 的2770,新建的子目录多数发行版会自动带上 SGID。但如果你用mkdir手动建了子目录,还是检查一下。

第三步,测试实际效果。以两个不同用户(比如alice和bob)分别登录,尝试创建文件、修改文件、删除对方文件。你会发现在这个目录里,大家都能读写,但能否删别人的文件取决于目录是否还开启了 sticky bit。上面例子中没有设置 sticky bit,所以组员是可以相互删除文件的;如果你希望只能删自己的文件,就把权限设为3770(SGID + Sticky Bit)。

这个案例的完整逻辑是:

需求对应的权限设计
组成员可读写进入属组权限rwx
其他人不可访问others 权限为 0
新文件自动归属组成目录设 SGID
防止随意删除他人文件目录加 Sticky Bit

3. 特殊权限位:SUID、SGID 与 Sticky Bit 的实际用途

3.1 SUID:为什么普通用户能改自己的密码

先看一条命令:

ls -l /usr/bin/passwd # -rwsr-xr-x 1 root root 59976 Feb 6 2024 /usr/bin/passwd

注意到属主权限里的rws了吗?这个s就是 SUID(Set User ID)位。它的作用是:当一个带有 SUID 的程序被执行时,进程的有效用户 ID(effective UID)会切换为该程序属主的 ID,而不是执行者的 ID。

passwd命令的属主是 root,所以普通用户执行它时,进程以 root 身份运行,才有权限去修改/etc/shadow这个只有 root 能写的密码文件。这是 Linux 里最典型的 SUID 应用,也是理解“最小权限原则被打破”的经典案例。

用数字法设置 SUID,是在原有三位权限前加4,例如:

chmod 4755 some_program

对应ls -l显示为-rwsr-xr-x。

这里我要给一个强烈建议:永远不要轻易给自定义脚本设置 SUID,尤其是那些可以被其他用户调用的脚本。SUID 是权限提升的“高压电”,一旦脚本能被普通用户触发并执行,几乎等于把 root 钥匙交了出去。排查安全问题时,find / -perm -4000是检查系统里所有 SUID 文件的常用命令,建议定期看一遍。

3.2 SGID:目录协作场景里的“组继承器”

SGID(Set Group ID)有两种作用方式。用在可执行文件上时,进程的有效组 ID 会切换为文件属组;用在目录上时,所有在该目录下新建的文件和子目录都会自动继承该目录的属组。

团队共享场景下,SGID 的价值非常大。假设/data/team_project属组是devteam,且开启了 SGID,那么alice在内创建文件时,文件的组会自动变成devteam,而不是alice的主组(比如alice)。这样其他组员才能顺利按组权限访问。

设置目录 SGID 的命令:

chmod g+s /data/team_project # 等价于 chmod 2770 /data/team_project

检查目录是否生效,可以用ls -ld看权限位是否有s:

ls -ld /data/team_project # drwxrws--- 2 root devteam 4096 Feb 14 10:30 /data/team_project

注意,SGID 在文件和目录上的表现不同,这是面试和实际排错都爱考的点:文件上是“运行时切换组身份”,目录上是“新建内容继承属组”。

3.3 Sticky Bit:/tmp 的防误删设计

Sticky Bit 用在目录上时,含义是:即使目录本身允许所有用户写,用户也只能删除或重命名自己拥有的文件,不能动别人的文件。典型例子就是/tmp:

ls -ld /tmp # drwxrwxrwt 20 root root 4096 Feb 14 10:35 /tmp

权限位最后的t就是 sticky bit,对应数字法中的1,所以设置方式是:

chmod 1777 /tmp/some_shared_dir

如果你在一个多人可写的共享目录里想防止用户互相删文件,这个 bit 是首选方案。结合上一节的团队案例,3770(SGID + Sticky Bit)的组合非常常见。

需要留意的是:Sticky Bit 只影响“删除/重命名”操作,不影响“修改内容”。也就是说,bob不能删alice的文件,但如果有写权限,他依然可以打开alice的文件清空内容。要真正防止内容被篡改,得结合 ACL 或更细粒度的权限模型。

4. umask 与默认权限:新文件为什么一出生就带着某个权限

4.1 umask 不是“减掉的权限”,而是“屏蔽掉的权限位”

很多资料把 umask 简单解释为“创建文件时默认减掉的权限”,比如umask 022时,新建文件权限是666 - 022 = 644,新建目录是777 - 022 = 755。这个说法在大部分场景下能对上,但本质上,umask 是按位取反后的“掩码”,它决定的是创建文件时哪些权限位会被强制清零。

为什么新文件默认不是666、新目录不是777?因为普通文件不应该默认获得执行权限(除非程序显式要求,比如脚本编译出来的二进制),所以系统把基础权限设成了666;而目录为了可进入,基础权限是777。

当 umask 为022时:

  • 文件:666去掉022的置位位,得到644,即rw-r--r--
  • 目录:777去掉022的置位位,得到755,即rwxr-xr-x

umask 值越“大”,默认权限越“小”。安全场景里,很多人会把自己的 umask 设为077,这样新建文件只有属主才能读,属组和其他人一点权限都没有。

查询当前 umask:

umask

临时修改:

umask 077

持久化修改的话,一般写在~/.bashrc或/etc/profile中。如果是要影响所有用户的登录环境,系统管理员通常会在/etc/profile、/etc/bashrc或/etc/profile.d/下的脚本里设置全局默认值。

4.2 实战:不同角色定制默认权限

我曾经给一台多人开发机设置过默认权限,需求是:所有开发人员创建的文件默认让同组可读,但不能写;部分管理员目录希望文件默认同组可写。

思路是给不同用户设置不同的 umask。开发人员的~/.bashrc里加:

umask 022

这样新建文件644,同组可读不可写。

对于需要协作编辑的目录,也可以考虑用chmod g+w在目录级别放开写权限,不过要注意这会让所有能进入该目录的组员都能改你的文件。若想更精确,建议用 ACL(见下一节)。

这中间有个常见问题:明明 umask 写好了,新建文件权限还是不对。排查思路是:

  1. 确认当前 shell 的 umask:umask -S
  2. 确认是否有/etc/profile、~/.profile、~/.bash_profile、~/.bashrc里多处设置,后执行的会覆盖先执行的
  3. 检查程序本身是否显式调用了open()并指定权限参数,比如mkdir(path, 0755)这类写死的模式,umask 只是对它做“减掩码”处理,无法让它变大

umask 和进程的关系值得多说一句:umask 是 shell 的内建状态,子进程会继承。所以你在一个终端里改了 umask,在这个终端里启动的所有程序创建文件都会受影响;但其他终端、系统服务则不会。

5. 进阶场景:ACL、root 与权限排查思路

5.1 ACL:当基本权限不够用时

基本权限模型只有属主、属组、其他人三档,在真实项目中经常不够用。比如,你想让alice对/data/project有只读权限,但alice既不是属主,也不在属组里,按传统权限模型就得改属组或把 everyone 放行,副作用很大。

这时候就该上 ACL(Access Control List)了。

查看文件 ACL:

getfacl /data/project

给指定用户添加权限:

setfacl -m u:alice:r /data/project

给指定组添加权限:

setfacl -m g:devteam:rw /data/project

删除指定用户权限:

setfacl -x u:alice /data/project

设置了 ACL 后,ls -l显示的权限位末尾会多一个+:

drwxrwx---+ 2 root devteam 4096 Feb 14 10:40 /data/project

此时真正生效的权限组合要以getfacl的输出为准,不能只看ls -l的传统三位权限。ACL 还有一个很有用的特性:mask。mask 限制了所有“命名的用户/组”在 ACL 中能拿到的最大权限。比如 mask 为r-x,那即使setfacl -m u:alice:rwx,alice实际也只能拿到r-x。这也是实际排错时容易翻车的地方——ACL 明明给了权限,用户却依然进不去。

默认 ACL(default ACL)只对目录有效,设置后新建的文件会自动继承相应的 ACL 条项。这个特性很适合团队目录,不用再担心新文件掉权限。

5.2 root 的特殊性与 sudo 的边界

root 在传统 Linux 权限模型里几乎是“无法无天”的:不管文件权限是000还是r--,root 都能读;不管目录是否可写,root 都能删文件。内核里专门有一段逻辑检查当前用户是否是 root(UID 0),是的话基本跳过大部分权限判断。

但有两个细节不要误解。第一,root 也不是绝对无敌的,面对只读文件系统、SELinux 强制策略、nosuid挂载选项等,root 同样受限。第二,sudo -u切换用户执行命令时,权限判断按目标用户来算,不会因为用了 sudo 就自动变成 root 权限,除非目标用户就是 root。

生产环境的原则是“能不用 root 就不用”。通过 sudo 按需授权,命令白名单控制在/etc/sudoers里。这里我给出一个排查权限问题时常用的命令栈:

id # 当前用户、UID/GID、附加组 ls -ld /data/project # 传统权限位 getfacl /data/project # ACL 详细规则 mount | grep /data # 挂载选项是否包含 noexec/nosuid/ro getenforce # SELinux 是否启用及模式

如果权限问题还是没解决,最容易被忽略的凶手就是 SELinux。关闭 SELinux 或者临时放行测试:

setenforce 0

这条命令会让 SELinux 进入 permissive 模式,只记录不拦截。注意这只是排查手段,不能作为长期方案。

5.3 一套完整的权限排查链路

我把自己踩过坑的排查路径整理成一个“问题-检查点”流程,你可以照着走:

  1. 先确认“用户是谁”。id看用户属主组和附加组。很多时候用户明明在devteam组里,但新加的组要重新登录或执行newgrp devteam才会在当前会话生效。

  2. 再确认“文件/目录是谁的”。ls -l看属主、属组,getfacl看 ACL。如果属组不对,检查目录 SGID 是否生效,或者直接chown修正。

  3. 确认“挂载层”。mount看文件系统是否以ro、noexec、nosuid方式挂载。尤其常见于外接磁盘、云盘挂载点,权限明明设了,但每次写操作都被read-only file system挡住。

  4. 确认“安全层”。SELinux 和 AppArmor 是排在权限模型之后的强制访问控制。ls -Z可以查看文件的 SELinux 上下文,ausearch -m avc -ts recent可以查最近的拒绝日志。对初学者来说,看日志是最快定位方式。

  5. 如果还是 blocked,检查程序自身逻辑。比如有些服务是以低权限用户启动的,它能不能读某个文件,取决于它启动时那个用户的权限,而不是你当前终端的用户权限。

这个链路走完,绝大多数“权限不足”问题都能水落石出。

最后再分享一个我的个人习惯:每次搭建一个需要协作的目录,我都会把权限设计、属主属组、ACL 规则写进 README 或运维文档,并且用stat -c '%a %U %G %n'批量核对一遍关键目录。权限问题是最容易出安全事故的环节,靠脑子记不可靠,落到文档和脚本里才是正道。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 4:22:15

基于SpringBoot+Vue的企业车辆管理系统设计与实现全解析

1. 项目概述与价值拆解这个标题看起来平平无奇,但做过毕设的人都知道,“企业车辆管理系统”属于管理信息系统里最典型的综合型题目,覆盖面广,技术点密度适中,既能体现开发能力又不至于失控。SpringBoot Vue MySQL这套…

作者头像 李华
网站建设 2026/10/2 4:20:21

从信息收集到SUID提权:Bulldog靶机完整渗透测试实战解析

1. 项目概述与环境准备1.1 为什么选 Bulldog 这个靶机Bulldog 是 OSCP 备考圈子里公认的「新手分水岭」靶机,难度标注为中等偏下,但它的价值不在难,而在全流程覆盖得特别完整:常规的端口枚举、Web 应用漏洞分析、命令注入、提权&a…

作者头像 李华
网站建设 2026/10/2 4:20:12

有符号数乘法详解:从补码原理到MATLAB实战避坑指南

做嵌入式、信号处理或者FPGA的兄弟,估计都吃过有符号数乘法的亏。ADC吐出来的FF、FE这些十六进制数据,看着是255、254,实际可能是-1、-2;两个“负值”乘在一起,结果还能被截断成一个大正数。这些问题全都绕不开“有符号…

作者头像 李华
网站建设 2026/10/2 4:20:05

Agent落地汽车研发:从需求管理到仿真调度的实战经验与避坑指南

最近圈子里的讨论风向变了。以前聊智能驾驶,大家关心的是BEV还是占用网络;现在聊汽车研发,越来越多人在问:Agent能不能把需求文档翻译成测试用例?能不能自动盯仿真任务的状态?能不能把底盘调校的参数寻优交…

作者头像 李华
网站建设 2026/10/2 4:19:04

openrig 统一配置 Claude Code 与 Codex:YAML 编排与本地模型接入实战

1. openrig 到底想解决什么问题第一次看到 openrig 这个名字,我下意识以为是某个硬件机架项目,毕竟 rig 在英文里常指设备支架、测试台架。但把 Claude Code、Codex、YAML、npm 这几个热搜词摆在一起,方向就清楚了:这是一个围绕 A…

作者头像 李华