news 2026/10/16 4:41:23

Linux权限学习记录:从rwx基础到SUID/ACL进阶实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux权限学习记录:从rwx基础到SUID/ACL进阶实战

Linux——权限 学习记录

干这行久了你会发现,Linux里十有八九的“诡异问题”,最后都能追溯到权限身上。不是服务起不来,是脚本没有执行权限;不是文件丢了,是目录没有写权限;不是配置改错了,是进程根本没权限读那个文件。权限这东西,刚接触时觉得就是chmod 777走天下,等真正部署一次服务、搭一次环境、被线上故障折腾几回,才会老老实实回来把它啃明白。

这篇文章是我自己学习Linux权限的一份完整记录,从最基础的rwx讲到SUID、ACL这些进阶玩法,把每个命令背后“为什么这么做”也一并讲清楚。适合刚入门Linux的同学系统过一遍,也适合有一定基础但总是“会用不会讲”的朋友查漏补缺。我尽量用大白话,把那些文档里写得绕来绕去的概念,掰开揉碎放在实际场景里。

1. 为什么Linux权限值得你认真学一遍

1.1 权限搞不懂,后面全是坑

很多人刚开始用Linux时,觉得权限就是个“附加题”。毕竟自己一个人用虚拟机,root用户想干嘛干嘛,chmod 777一敲,什么问题都没有了。但权限这东西,本质上和Linux的文件系统、多用户机制、进程模型深度绑定。你后面写脚本、部署网站、搭数据库、做自动化运维,每一个环节都会遇到权限问题。

举个最常见的例子:你用nginx运行一个Web服务,网页文件是root用户上传的,nginx工作进程以www-data用户运行,结果浏览器访问时一片403。这时候你才意识到,文件存在还不够,得让“别人”能读、能执行。这个“别人”是谁?权限模型里的“其他人(other)”说的就是这种情况。类似场景在配置cron定时任务、挂载磁盘、搭建Docker环境时还会反复出现。

我自己的体会是:权限不是一个可以绕开的点,它是Linux安全的基石,也是你从“会用Linux”走向“懂Linux”的必经门槛。早一点系统学一遍,后面踩的坑会少一半。

1.2 从ls -l输出说起

要理解权限,最好的切入点是终端里那一行ls -l的输出。随便找个文件看一眼:

$ ls -l /etc/passwd -rw-r--r-- 1 root root 2859 Nov 18 10:32 /etc/passwd

这一行看起来简短,信息量却非常大:

  • -rw-r--r--:文件类型 + 权限位
  • 1:硬链接数量
  • root root:所有者和所属组
  • 2859:文件大小(字节)
  • Nov 18 10:32:修改时间
  • /etc/passwd:文件路径

权限位那一串字符rw-r--r--,可以拆成四段来看。第一段是文件类型,-表示普通文件,d是目录,l是软链接,c是字符设备,b是块设备。后面九位每三位一组,依次是“所有者(u)”、“所属组(g)”、“其他人(o)”的权限。每组内部都按rwx顺序排列,出现字母表示有对应权限,-表示没有。

所以rw-r--r--的意思就是:所有者可读可写,所属组和其他人只能读。这个模型构成了Linux权限管理的基本框架,掌握了它,再看任何权限相关的问题都会一目了然。

2. 基本权限模型:rwx到底在管什么

2.1 读、写、执行,三类权限的含义

r、w、x代表三种基本操作权限,分别对应读、写、执行。这里要特别注意:同一个字母,作用在普通文件上和作用在目录上,含义是截然不同的。很多人第一次栽跟头就是因为分不清“文件权限”和“目录权限”。

普通文件上的权限容易理解:

  • r(读):能查看文件内容,比如cat、less、head都能正常工作
  • w(写):能修改文件内容,比如vim编辑、用>重定向写入
  • x(执行):能把文件当作命令或脚本运行

目录上的权限就有点绕了:

  • r(读):能读取目录里的文件名列表,也就是能ls看到有哪些文件
  • w(写):能在目录里创建、删除、重命名文件或子目录
  • x(执行):能“进入”目录,也就是能cd进去,并且能访问目录里文件的具体属性

关键点在于:目录的r权限管的是“能否列出文件名”,目录的x权限管的是“能否真正访问到文件本身”。如果你只有r没有x,你ls可以看到目录里有哪些名字,但cd进不去,也读不了文件内容,甚至ls -l查看详细属性都会被拒绝,因为读取文件的inode信息需要通过x权限。反过来,只有x没有r,你能进去,也能访问知道名字的文件,但没法列出目录里还有什么。

我见过最典型的案例是:有人把网站目录设成了755,文件也是644,但访问时依然报错No such file or directory,明明文件就在那。最终排查发现是中间某一层目录权限不足,nginx工作进程没有x权限无法穿越路径。记住这句话:要访问一个路径下的文件,路径上每一层目录都需要有执行权限。

2.2 三种身份:所有者、所属组、其他人

Linux是多用户操作系统,权限自然围绕“用户”来划分。每个文件都有三个身份维度:

  • 所有者(user,缩写u):文件的创建者或通过chown指定的人
  • 所属组(group,缩写g):文件所属的用户组,组内所有成员共享这个权限
  • 其他人(other,缩写o):既不拥有文件,也不在所属组里的所有用户

另外还有一个特殊身份:root(超级用户)。root几乎不受普通权限限制,它可以读写任何文件、进入任何目录。这一点既能救命也容易造成惯性思维——你用root排查问题没问题,但线上服务跑起来通常不是root,问题就暴露了。

判断一个进程能不能访问文件时,系统只认一个身份:进程的运行用户。具体判断顺序是:进程用户是否等于文件所有者?不等的话再看是否属于文件所属组?也不属于的话,就落到“其他用户”权限。这三选一,不会叠加,也不会取并集。这个逻辑虽然简单,但很多新手会误以为“我是所有者我有读,我又在组里我有写,那权限就是读+写”,其实不是,只看命中的第一顺位身份。

下面这张表是判断过程的直观展示:

判断顺序条件生效权限
1进程用户 == 文件所有者所有者权限位(u)
2进程用户 ∈ 文件所属组所属组权限位(g)
3其他情况其他人权限位(o)

2.3 数字权限的由来:rwx二进制编码

聊到chmod 755这类命令,就绕不开数字权限。三位数字的权限其实是将每类身份的rwx权限看作一个二进制数:r代表4,w代表2,x代表1,相加起来得到0到7的十进制数字。

为什么恰好是4、2、1?因为在计算机底层,这三个权限位可以看作一个三位二进制数,从高到低分别是"读、写、执行"。有权限则该位为1,没有则为0。rwx全部开启就是111,转成十进制是7;rw-是110,转成十进制是6;r--是100,转成十进制是4。

这三种权限组合一共8种情况,从0到7:

数字二进制权限字符含义
0000---无任何权限
1001--x仅可执行
2010-w-仅可写
3011-wx可写、可执行
4100r--仅可读
5101r-x可读、可执行
6110rw-可读、可写
7111rwx可读、可写、可执行

所以chmod 755就是把所有者设为rwx(7),所属组设为r-x(5),其他人设为r-x(5)。这个编码规则不会变,熟练之后看到644、600、755,脑子里应该立刻浮现出对应的权限字符,这是Linux操作的基本功。

3. 实操:chmod、chown的完整用法

3.1 chmod:数字法与符号法怎么选

chmod是修改权限的核心命令,支持两种语法风格:数字法和符号法。

数字法直接、高效,适合批量设置:

chmod 755 script.sh chmod 644 /etc/nginx/sites-available/app.conf chmod 600 ~/.ssh/id_rsa

符号法则更直观,适合局部修改某个身份的权限:

chmod u+x script.sh # 给所有者加执行权限 chmod g-w file.txt # 去掉所属组的写权限 chmod o=r file.txt # 把其他人的权限设为只读 chmod a+rx app.sh # 给所有身份都加读和执行权限 chmod u=rwx,g=rx,o=rx app.sh # 等同chmod 755

符号法里的操作符有三种:+增加权限、-移除权限、=直接赋值权限。我个人的习惯是:设置一个明确的权限状态用数字法,临时调整某个身份用符号法。两种方法不冲突,但建议至少把数字法练到条件反射,因为看脚本和配置文件时数字出现频率太高了。

这里提醒一句:别动不动就chmod 777。这相当于给所有用户完全控制权,等于把安全机制关掉了。临时调试可以用,生产环境必须避免。如果确需要让多个用户协作访问文件,正确做法是设置所属组并赋予组权限,而不是把“其他人”权限放开。

3.2 递归修改与链接文件的坑

目录下有成百上千个文件时,手动逐个改不现实,需要递归操作:

chmod -R 755 /var/www/html chown -R www-data:www-data /var/www/html

-R参数会递归处理目录下所有文件和子目录。用起来很方便,但也有两个坑。

第一个坑:chmod -R把目录和文件设置成同一个权限往往不合理。目录需要x权限才能进入,但普通文件如果给了x权限,等于告诉别人“这个文件可以执行”,对于纯数据文件来说完全没有必要,而且会增加风险。更规范的做法是分开处理:

find /var/www/html -type d -exec chmod 755 {} \; find /var/www/html -type f -exec chmod 644 {} \;

这也是很多部署脚本里的标准写法,目录统一755,文件统一644,兼顾功能与安全。

第二个坑:chmod -R默认不会穿透软链接(符号链接)。对软链接本身执行chmod通常会报错或者没实际效果,因为权限只能修改链接指向的目标文件,而不能修改链接自身。所以遇到软链接时,要么直接对目标文件操作,要么用chmod -R -L穿透到链接指向的文件,但这个参数容易误伤,建议还是手动梳理清楚再操作。

3.3 chown与chgrp:改所有者、改所属组

chmod只管权限位,不管是谁拥有文件。实际场景中,经常要把文件转交给另一个用户或组去管理,这时候用chown。

chown alice file.txt # 把所有者改为alice chown :devs file.txt # 只改所属组为devs chown alice:devs file.txt # 同时修改所有者和所属组 chown -R www-data:www-data /var/www # 递归修改整个目录

注意chown后的用户和组名可以省略其一:只写alice表示修改所有者,所属组不变;只写:devs表示只修改所属组,所有者不变。这个特性在只想改组时很实用,不用先查原所有者。

chgrp命令只负责修改所属组,功能上chown :group等价,所以现在很多习惯直接用chown,chgrp用得少了。但它是老牌命令,脚本里见到也不奇怪。

一个日常高频操作是:需要普通用户管理某个目录下的文件,但目录又属于root。此时不应给普通用户sudo权限一放了之,而应该用chown把目录转移给该用户,或把目录所属组改成包含该用户的组,再配合chmod g+rwx。这样既满足需求,又把权限控制在了最小范围内。

3.4 umask:新建文件为什么不都是777

还有一个容易被忽略但非常重要的问题:为什么touch出来的新文件权限是644,而新目录是755?这两个数字不是系统默认写死的,而是由umask计算出来的。

umask是一个掩码,用来屏蔽掉那些“不应该默认授予”的权限位。查看当前值:

$ umask 0022

计算规则并不复杂。对文件来说,系统默认基础权限是666(因为文件默认不给执行权限,这是出于安全设计);对目录来说,默认基础权限是777。然后用“基础权限去掉umask中出现的位”来得到最终权限。

umask为022时,转换为二进制就是000 010 010,表示将所属组的写权限(2)和其他人的写权限(2)屏蔽掉。所以新建文件是666 - 022 = 644,新建目录是777 - 022 = 755。实际上这个“相减”并不是简单的算术减,而是把umask中为1的位对应的权限清除。但由于权限位恰好是4、2、1这样的数,且没有跨位影响,直接做减法的结果也是对的。

如果想让新建文件对组内成员可写,可以把umask调成002:

umask 002 touch newfile.txt ls -l newfile.txt # -rw-rw-r-- 1 user user 0 ... newfile.txt

umask只在当前Shell会话中临时生效,要永久修改可以写入~/.bashrc或/etc/profile。这个细节在多人协作、共享目录的工作流中很关键,很多人遇到“明明是我新建的文件,同事却改不了”的问题,根源往往就是umask设得太严。

4. 进阶内容:特殊权限、ACL与实战场景

4.1 SUID、SGID与Sticky Bit

基础权限之外,Linux还有三个特殊权限位。它们不常见,但在特定场景下是必需品,也是排查诡异问题时的重点怀疑对象。

SUID(Set User ID):当一个可执行文件设置了SUID位后,普通用户运行它时,进程的有效身份会临时变成文件所有者,而不是运行者自己。最典型的例子是/usr/bin/passwd:

$ ls -l /usr/bin/passwd -rwsr-xr-x 1 root root 64152 Nov 6 23:43 /usr/bin/passwd

注意所有者权限位变成了rws,那个s就是SUID。普通用户执行passwd修改自己的密码时,需要写入/etc/shadow,而该文件只有root能写。如果没有SUID,普通用户根本没法改密码。这里SUID让程序可以在运行期间“借用”root身份完成必要操作,但命令结束后权限随之消失。

SUID设置方法:chmod u+s file,对应数字法chmod 4755 file中的4。生产环境中能不用就不用,因为SUID是提权漏洞的高发点,一旦可执行文件本身可写或有漏洞,攻击者很容易利用SUID获取root权限。

SGID(Set Group ID)作用类似,但针对的是所属组身份。对可执行文件来说,赋予SGID后运行进程会临时获得文件所属组的身份。对目录来说更常用:当目录设置了SGID后,在该目录内新建的文件或子目录,其所属组会自动继承父目录的所属组,而不是创建者的主组。这个特性非常适合团队共享目录。

设置方式:chmod g+s dir,数字法是chmod 2770 dir中的2。

Sticky Bit(粘滞位)则用在目录上。它规定:在这个目录里,只有文件所有者、目录所有者或root才能删除或重命名文件,其他人即使对这个目录有写权限也删不动别人的文件。最典型的例子是/tmp:

$ ls -ld /tmp drwxrwxrwt 1 root root 4096 ... /tmp

注意其他人权限位变成了rwt,末尾的t就是Sticky Bit。它的存在让/tmp这样的人人可写的目录不至于变成“互删战场”。设置方式:chmod +t dir,数字法是chmod 1777 dir中的1。

三个位叠加在chmod的数字写法里,就是四位数字,比如4755表示包含SUID,2770表示包含SGID,1777表示包含Sticky Bit。也可以组合,比如6755表示同时有SUID和SGID。

4.2 ACL:更精细的权限控制

基本权限模型只能精确到“所有者、所属组、其他人”三个身份,这在复杂协作场景下不够用。假设你希望文件所有者是alice,同时允许bob和carol有读写权限,但不希望整个组都拿到权限,基本权限就做不到了,而ACL(Access Control List)正是为这种需求设计的。

查看文件是否有ACL:

getfacl demo.txt

给特定用户或组设置ACL:

setfacl -m u:bob:rw demo.txt # 给bob读写权限 setfacl -m g:devs:rx demo.txt # 给devs组读和执行权限 setfacl -x u:bob demo.txt # 移除bob的ACL条目 setfacl -b demo.txt # 清除所有ACL条目 setfacl -R -m u:bob:rwx /shared/project # 递归设置

设置ACL后,再执行ls -l,权限位末尾通常会多一个+标记:

-rw-rw-r--+ 1 alice devs 1024 ... demo.txt

ACL有一个被高频提及的特性:mask。简单理解,mask是一个“权限上限”,它约束了所有命名用户、所属组和命名组能获得的权限上限,但不影响文件所有者。也就是说,即使ACL里给bob设置了rwx,如果mask是r--,bob实际也只能读到,不能写和执行。这个机制容易让人困惑,但它是ACL安全性的关键一环。

用getfacl可以清晰看到mask值:

$ getfacl demo.txt # file: demo.txt # owner: alice # group: devs user::rw- user:bob:r-- group::rwx # effective: r-- mask::r-- other::r--

这里group::rwx后面标注了effective: r--,说明实际生效权限被mask限到了只读。遇到ACL权限“怎么设都不生效”的问题时,第一反应就是查mask。

4.3 实战场景:Web目录部署的标准权限方案

理论讲了一堆,落到实际场景里看看怎么组合使用。以一个常见的Web部署为例:网站目录在/var/www/html,Web服务以www-data用户运行,团队里还有一个开发者账户alice需要更新代码。

第一步:确定目录归属。把目录的所有权和组都交给www-data:

chown -R www-data:www-data /var/www/html

第二步:设置目录和文件的权限。目录要能穿越,文件对外可读,但只有所有者能改:

find /var/www/html -type d -exec chmod 750 {} \; find /var/www/html -type f -exec chmod 640 {} \;

这里没给“其他人”任何权限,因为Web服务通过www-data组身份访问,实际命中的是组权限,不需要开放“其他人”。这比常见的755/644方案更严格,也更安全。

第三步:让alice也能更新文件。把alice加入www-data组:

usermod -aG www-data alice

如果要让alice新建的文件也自动属于www-data组,避免“文件是alice建的,Web服务读不了”的尴尬,可以给目录加SGID:

chgrp www-data /var/www/html chmod g+s /var/www/html

这样alice在目录里新建的任何文件,所属组都自动是www-data,再配合umask设置为002(保证组内有rw权限),整套协作流程就很顺了。

如果某个子目录需要bob单独访问,还可以加ACL兜底:

setfacl -R -m u:bob:rx /var/www/html/reports

这套方案生产环境里跑得很稳。它的核心思想是:能分组的用组权限解决,个别特殊身份用ACL解决,实在没办法才考虑放开“其他人”。每一步都尽量收紧权限,而不是一放了之。

5. 常见问题与排查技巧

5.1 权限问题排查三板斧

权限问题的表现五花八门,但排查思路是固定的。我自己遇到权限相关故障时,基本就按下面这个顺序走。

第一,确认运行身份。服务是哪个用户跑的?是root、www-data,还是某个专用账号?查看进程运行用户可以用:

ps aux | grep nginx

如果是systemd管理的服务,看看单元文件里的User=参数。

第二,检查完整路径上每一层目录的权限。文件最终能不被访问,取决于从根目录到文件本身的所有路径节点。可以用namei命令一键查看:

$ namei -l /var/www/html/reports/2024-01.xlsx f: /var/www/html/reports/2024-01.xlsx drwxr-xr-x root root / drwxr-xr-x root root var drwxr-xr-x root root www drwxr-x--- root www-data html drwxr-x--- alice www-data reports -rw-r----- alice www-data 2024-01.xlsx

一层层看下来,哪一层权限不对一目了然。这个命令在排查“明明文件权限没问题,但就是读不了”的场景里非常高效。

第三,模拟目标身份验证。真正的验证不是看权限位,而是切换到那个身份去实际操作。比如怀疑www-data读不了文件,就直接切过去试试:

sudo -u www-data cat /var/www/html/2024-01.xlsx

能读到,说明路径和权限都没问题;读不到,说明问题确实出在权限配置上。这套逻辑比对着ls -l猜要可靠得多,因为实际进程还会受ACL、mask、文件系统挂载选项等因素影响。

5.2 高频报错速查

报错信息常见原因处理方向
Permission denied文件或目录权限不足chmod调整权限,或改用归属用户运行
Operation not permitted通常是root权限不足(如挂载、chown)确认是否需要sudo
Cannot open file for writing对文件有写权限但目录无写权限(或反之)检查所在目录的写和执行权限
No such file or directory路径中某层目录无执行权限检查路径每一层的x权限
Stale file handleNFS等文件系统句柄失效重新挂载或刷新文件句柄
Text file busy可执行文件正在运行中被覆盖不能直接覆盖运行中的二进制,先停进程或改文件名

排查时的一点实战经验:在文件系统层面确认一下磁盘是否真的挂了。有时Permission denied其实不是权限问题,可能是noexec、nosuid等挂载选项导致的。用mount命令查看当前挂载选项:

mount | grep /data

如果挂载选项里有noexec,那你只能访问目录里的数据,但没法执行任何二进制文件,无论chmod怎么设都没用。

5.3 几个能救急的小命令

日常维护中这几个命令和参数会反复用到,值得记下来:

# 查看某个用户对文件的权限,比ls -l更直观 namei -l /path/to/file # 找出目录下所有有异常写的文件 find /var/www -type f -perm -o+w -ls # 找出所有设置了SUID的文件(安全检查用) find / -type f -perm -4000 -ls 2>/dev/null # 查看当前用户在目录里的实际权限 namei -m /some/directory/path # 递归设置目录和文件不同权限的标准姿势 find /data/web -type d -exec chmod 750 {} \; find /data/web -type f -exec chmod 640 {} \;

find按权限查找这个技巧,在巡检系统是否有“权限过度开放”的文件时非常省力。比如上面找出所有other有写权限的文件,很多时候这就是安全隐患的源头。

写在最后的几个心得

这套东西我前前后后系统学了三遍,每次都是被生产环境的问题推着回来重看。第一遍只记住了chmod 755,第二遍搞明白了rwx和数字的对应,第三遍才真正理解SUID、SGID、ACL这些机制的存在意义。回头看,学习权限最好的方式不是背命令,而是带着场景去理解——为什么passwd有rws权限?为什么/tmp要设t权限?为什么共享目录要设g+s?每个特殊设计背后,都是为了解决一个真实问题。

最后分享一个小技巧:改任何权限之前,先想清楚“到底要给谁开什么权限”,而不是“现在报错了,试试777”。前者是管理思维,后者是碰运气思维。线上环境里多一份谨慎,少一次故障,这就是权限学习带给你最直接的回报。

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

双节锂电池主动均衡系统设计:MP2642GR-Z与MK64FX512VDC12协同方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 4:39:53

滑动窗口+哈希计数:日志统计热帖的O(N log N)解法与边界处理

1. 从"日志统计"这道题看滑动窗口的实战价值"日志统计"这个题目名字听起来平平无奇,但如果你真正动手做过历届算法竞赛的真题,就会发现它是一道非常典型的滑动窗口加哈希计数的综合应用题。我第一次看到这道题的时候,第一…

作者头像 李华
网站建设 2026/10/16 4:39:38

技术博客创作前,项目标题与关键词该如何填?

请提供需要拆解撰写的项目标题,以及可选的补充字段(项目正文、关键词、摘要描述)。你上一轮发送的内容中,核心的角色设定与创作规范我已经完整接收,但缺少最关键的一个输入参数——“项目标题”本身。没有标题&#xf…

作者头像 李华
网站建设 2026/10/16 4:39:37

Spring Boot + Vue 3 全栈项目实战:从接口设计到前后端联调

在后台管理系统、小程序管理端、企业官网这类项目里,Spring Boot Vue 的组合几乎成了事实标准。后端 Spring Boot 提供稳健的 API 服务,前端 Vue 负责交互体验,两者配合能快速完成从数据库到页面的全链路打通。这篇文章不是我第一次写全栈项…

作者头像 李华
网站建设 2026/10/16 4:39:16

JavaWeb学习路线:从Servlet到Spring Boot的全链路解析

1. 为什么我在2024年才开始写JavaWeb学习日记打开博客后台准备敲第一篇文章的时候,其实挺感慨的。做开发这几年,断断续续用过不少框架,也写过一些接口,但一直没系统梳理过JavaWeb这条线。直到最近重新翻自己早年记的零散笔记&…

作者头像 李华
网站建设 2026/10/16 4:38:46

端侧大模型推理性能调优实战:从0.4到12.8 token/s的排查指南

最近被一个“80 倍”的性能对比搞得相当狼狈。前提是端侧推理——模型不联网,完全在手机本地跑 LLM 的那种部署方式。别人演示视频里每秒稳定输出二十多个 token,我手里这台设备一个字一个字往外蹦,体感差距大到让人怀疑是不是拿错了机器。以…

作者头像 李华