尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Linux权限模型全解析:从UID/GID到chmod与特殊权限位

发布时间:2026/9/29 17:19:24

资讯中心
01
ARTICLE

Linux权限模型全解析:从UID/GID到chmod与特殊权限位

Linux权限模型全解析:从UID/GID到chmod与特殊权限位
很多年前我第一次在服务器上执行 rm被 Permission denied 弹回来时我盯着那行红色报错发呆了好久。明明我登录的是 root为什么还是没权限后来才发现我登的是自己的普通账号。这个故事听起来很蠢但它特别真实——Linux 权限系统的第一步不是理解那些 rwx 符号而是先搞清楚一件事你现在到底是谁。这篇内容想做的就是把这套我是谁 → 我能干啥的权限逻辑彻底讲透。它适合三类人被权限问题折磨到想放弃的开发者和运维新手、因为权限配置不当而被安全审计挑战的工程师以及所有想搞懂 Linux 而不是只会背命令的人。我会把权限模型、特殊权限、排查思路都串起来用实际场景来演示而不是堆砌一条条命令。1. 先搞清楚我是谁UID、GID 与用户身份的底层逻辑在讨论权限之前必须先解决一个更重要的问题系统怎么知道你是谁Linux 系统中真正被系统识别的不是用户名而是用户 IDUID和组 IDGID。你在登录界面输入的用户名只是内核为了方便人类记忆而加的一层壳。当你登录系统时PAM 模块完成身份验证login 程序确认你的 UID、GID并把它们绑定到当前会话的所有进程中。此后你每启动一个子进程、访问一个文件内核都基于这套数字身份来做判定。这个逻辑和 Windows 的 ACL 体系差异很大。Windows 下权限判断很多时候会依赖域、SID、令牌等一整套复杂机制而 Linux 则是极简的一个进程 一个 UID 一组 GID模型。正因为它简单才值得把所有细节吃透。1.1 Unix 权限模型的最小设计单元整个 Linux 权限模型建立在一个非常简洁的思路上任何一次文件访问请求都可以归结为某个进程who对某个对象what执行某个动作how。判定标准是这个进程的 UID 和 GID与文件记录的属主、属组、其他身份三元组进行核对。这个设计在 1970 年代的 Unix 中就已成型到今天依然是操作系统领域最优雅的方案之一。它没有给每个用户单独设定 ACL而是把所有用户划分为三个类别属主owner文件创建者、属组group与文件归属组相同的用户群、其他other以上两类之外的所有人。这里有个容易被忽略的细节文件创建者并不永远是属主。root 可以把任意文件的属主改成别人——这就解释了为什么管理员能把某个目录转交给离职同事也可以把历史项目的所有权批量划给新负责人。属主身份是一个记录不是物理绑定。三个分类大大降低了管理复杂度代价是粒度较粗。如果你需要更细的控制比如只允许 A 用户读、B 用户写、其他人一律不可访问就得借助后续的 ACLsetfacl/getfacl。但 ACL 是基础模型之上的补丁不是在替代它。我建议先彻底掌握基础三元组再碰 ACL不然很容易把权限理解成一锅粥。1.2 一条命令看清你的全部身份id 输出详解实操中第一件该做的事就是弄清当前身份。很多人一上来就查文件权限却忽略了我是谁这个变量。当你在终端输入 id 时会得到类似这样的输出$ id uid1000(zhang) gid1000(zhang) groups1000(zhang),4(adm),27(sudo),130(lpadmin)我见过太多人只看 uid 和 gid却忽视 groups 那一列。要知道Linux 判断进程权限时不仅看进程的有效组还会把用户的所有附加组都纳入检查范围。这就是为什么某些用户明明不是某个文件的属组却依然能访问——因为他的某个附加组与文件属组匹配了。所以在排查权限问题时我习惯把 id 命令当作第一现场勘察。不看 id 就开始猜文件权限本质上是盲人摸象。你连自己是以什么身份在操作都不清楚又怎么判断权限是被谁挡住的补充一个冷知识/etc/passwd 里存储了用户名与 UID 的对应关系/etc/group 存储了组名与 GID 的对应关系用户的附加组成员关系也记在 /etc/group 的最后一列。生产环境修改用户身份时最好编辑完这两个文件后用 id 验证一下避免出现权限明明给了为什么还是不行的诡异现象。1.3 用户切换背后的权限传递机制很多新手分不清 su 和 sudo 的本质区别导致权限管理上的混乱。su 是切换用户默认切到 root需要输入目标用户的密码切换后整个 Shell 会话的有效 UID 变为目标用户之后所有操作都以该身份执行。这就像一个人在门禁处换了一张别人的门卡全程都顶着别人的身份在楼里走动。sudo 则完全相反——它以其他用户身份执行单条命令验证的是当前用户自己的密码通过 /etc/sudoers 文件中的规则决定你能以什么身份执行什么命令。sudo 自带审计机制命令执行前会查规则执行后会记日志。我个人的生产环境习惯禁止直接 su root所有管理操作一律走 sudo。原因很简单sudo 会在 /var/log/secure或 journald中记录每一个提权操作的时间、用户和完整命令su 切到 root 后所有操作都归在 root 名下等于断了追溯链路。等出了安全事故日志里只有一堆 root 操作的痕迹根本定位不到人那时候就真的叫天不应了。2. 九位权限位的真正含义文件和目录的行为差异身份确认完毕接下来看我能干啥。Linux 权限位的标准展示形式是 ls -l 输出中的十个字符比如-rwxr-xr-- 1 root root 2048 Jun 20 10:30 backup.sh第一个字符表示文件类型- 是普通文件d 是目录l 是符号链接。后面九个字符从第 2 位到第 10 位恰好是三组三位属主权限rwx、属组权限r-x、其他用户权限r--。2.1 r、w、x 对文件和目录分别意味着什么九位权限的基础是三种动作r读、w写、x执行。但同样一个字符作用在普通文件和目录上的含义完全不同这一点很多人没想透。对普通文件来说r允许查看文件内容。w允许修改文件内容。x允许运行这个文件脚本或二进制程序。对目录来说r允许列出目录中的文件名。但仅仅看得见名字没有进入权限。w允许在目录中新建、删除或重命名文件。请注意w 作用于目录时和文件本身的内容修改没有任何关系。x允许进入该目录也允许访问目录中文件的内容。这是最容易被忽略的一个权限位。有一个核心知识点必须刻在脑子里对目录的 x 权限决定了你是否能够穿过这层目录去访问里面的文件。如果你对某个目录没有 x 权限即使里面的文件自身权限是完全开放的你也无法访问到它们因为你的路径在目录这层就被拦死了。2.2 为什么你能浏览却删不掉文件经典场景来了你能用 cat 查看一个文件的内容用 rm 删除它时却报 Permission denied为什么答案藏在 Linux 的文件操作概念里。删除文件这个动作针对的不是文件本身而是文件所处的目录——因为删除的本质是修改目录中的文件名条目目录项把它从目录列表里移除。所以决定你能否删除文件的关键权限是父目录的 w 权限而非文件本身的权限。举个例子。假设目录 /data/upload 属主是 zhangsan权限为 drw-r--r--属主只有 rw没有 w 和 x其他用户只有 r。用户 lisi 能通过 cat 读取目录里的文件内容但当他想 rm 删除文件时即便那个文件的权限是 rwxrwxrwx 也一样会被拒绝——因为 lisi 对目录 /data/upload 没有 w 权限。这个原理在写自动化脚本时特别重要。很多初次写部署脚本的工程师会直接在脚本里对文件执行 rm -f结果把日志文件所在目录的权限都清理掉了导致应用无法写入日志。正确思路是先确认你要删除的文件所在的目录有 w x 权限再谈文件本身的权限。2.3 无执行权限目录的诡异现象分享一个我真实踩过的坑。某次部署 Web 应用网站根目录是 /data/web我当时检查发现 /data 是 755、/data/web 是 777心想权限绝对够用了。结果访问页面始终报 403 Forbidden折腾了一个多小时才发现 /data/web 的父目录 /data 被前人加固脚本改成了 750。750 意味着什么属主 root 有 rwxroot 组有 r-x其他用户一点权限都没有。而运行 Nginx 进程的用户是 www-data既不是 root也不在 root 组对 /data 连 x 权限都没有——根本进不去这层目录自然谈不上访问里面的文件。这个案例的教训是权限检查永远是链式的。你在看目标文件权限之前必须沿着路径自顶向下确认每一级目录的 x 权限都是放开的。很多权限问题不是目标文件本身的权限不对而是路径上某一层目录把请求挡在了门外。3. chmod 实操数字法与符号法之间如何选择讲完权限的含义进入修改权限的实操环节。chmod 是 Linux 中使用频率最高的命令之一但用法上存在两种流派数字法八进制和符号法。很多人只会一种我要说的是两种都该会而且知道什么时候用哪种。3.1 数字法背后的二进制逻辑数字法的核心是三个八进制数每个数对应一组权限。r 值 4、w 值 2、x 值 1三个值相加得到一个 0-7 的数字。为什么是 4、2、1因为这个机制本质上是三个二进制位r 对应最高位二进制 100即十进制 4w 对应中间位二进制 010即十进制 2x 对应最低位二进制 001即十进制 1。755 这个经典组合拆开看就是属主 7rwx421、属组 5r-x41、其他用户 5r-x41。644 就是属主 6rw-、属组 4r--、其他 4r--。数字法的最大问题是读起来反直觉。当你看到 chmod 766 的文件你能立刻反应出其他用户能不能执行吗未必。所以生产环境里我默认推荐用符号法让权限变更的语义更加明确降低出错的概率。下面的表可以帮你快速对照数字权限组合含义7rwx读、写、执行6rw-读写不可执行5r-x读和执行不可写4r--只读0---无任何权限3.2 符号法的写法与适用场景符号法的格式是chmod [u/g/o/a][/-/][r/w/x] 文件。例如 chmod ux script.sh 是给属主增加执行权限chmod g-w config.ini 是去掉属组的写权限。实际工作中最常用的符号操作chmod x script.sh所有类别都加执行权限。不指定 u/g/o 时默认作用于全体a。chmod us /path/to/file设置 SUID后面细讲。chmod o-r secret.key去掉其他用户的读权限。符号法的优势在于只改目标位不会误伤其他位。比如 chmod ar 只是把读权限放开给所有人w 和 x 保持不变。而数字法必须列出全部三个数字想只改一组权限时还得先算出另外两组的当前值很容易算错。我在交付脚本时尤其强调符号法的可读性。一份部署脚本里写 chmod ux deploy.sh 的意图比写 chmod 751 deploy.sh 好理解得多。读者不需要先心算 751 是什么再对照文件类型判断。3.3 一个真实案例Web 目录的权限配平部署 Nginx 时我的标准操作是这样# 目录权限 755属主 rwx属组和其他 r-x find /data/web -type d -exec chmod 755 {} \; # 文件权限 644属主 rw属组和其他 r find /data/web -type f -exec chmod 644 {} \;这里的关键点在于目录需要 x 权限才能进入所以目录用 755普通文件只需要读没必要给执行权限所以用 644。这样也避免了在 Web 目录中遗留任何可执行脚本的风险——万一某天攻击者上传了一个 webshell没有执行权限的恶意脚本也跑不起来多一层防护。配完权限后再配合属主设置 chown -R www-data:www-data /data/web整个目录的权限结构就非常干净了。很多安全审计对 Web 目录的评分标准恰恰是看是否遵循了目录不多给权限、文件不顺手加 x的原则。4. 特殊权限位SUID、SGID、Sticky Bit 如何改变游戏规则聊完基础权限必须提三个特殊权限位。它们经常被忽视却在生产环境里异常重要也是面试中权限模块的高频考点。4.1 SUID为什么普通用户能改自己的密码你肯定好奇过这个问题/usr/bin/passwd 是 root 拥有的文件root 才能写普通用户为什么能通过它修改自己的密码答案是 SUIDSet User ID位。当可执行文件设置了 SUID 后任何人运行这个程序时进程的有效 UID 不是运行者的 UID而是文件属主的 UID。这意味着普通用户运行 passwd 时进程暂时变成了 root 身份从而有权限修改 /etc/shadow但只能执行程序内写好的极有限功能。在 ls -l 中SUID 表现为属主权限位的 x 变成 s 或 S例如-rwsr-xr-x 1 root root 68208 Jun 10 2023 /usr/bin/passwd关于这个 s 有一个细节大写的 S 表示设置了 SUID 但没有执行权限小写的 s 表示 SUID 与执行权限同时存在。实际系统中绝大多数都是小写 s。需要警惕的是任何设置了 SUID 的可执行文件都是提权攻击的潜在入口。如果某天你在系统里发现了一个没预期到的 SUID 文件那几乎可以断定系统被入侵或被植入了后门。我每台服务器上线前都会做一次 SUID 审计find / -perm -4000 -type f 2/dev/null跑完对比一下已知的合法 SUID 列表一般集中在 /usr/bin、/usr/lib 几个固定目录出现陌生文件就立刻深入排查。4.2 SGID协作目录的权限继承魔法SGIDSet Group ID和 SUID 逻辑类似继承的是组身份。不同的是SGID 除了作用于可执行文件对目录还有一个独特效果当目录设置了 SGID 后任何人在该目录下新建文件新文件的属组自动继承为目录的属组而不是创建者自己的默认属组。这个特性在团队协作目录中非常好用。假设项目组统一的组是 devteam组长把项目目录设成 devteam 并加上 SGID 位之后任何组员在该目录下生成的代码文件属组都会自动变成 devteam。这样避免了同一个项目组里 A 创建的文件 B 无法编辑的尴尬——因为 B 虽然是 devteam 成员但 A 的文件如果属组还是 A 的个人组B 对它就失去了组协作的权限。用法很简单chown -R :devteam /srv/project chmod -R gs /srv/project生产环境里很多代码仓库目录就是这么配的。如果你发现团队协作时总是出现别人的文件我改不了的问题第一反应就该检查目录的 SGID 位是否设置。4.3 Sticky Bit/tmp 为什么谁也删不了谁/tmp 目录的权限通常是 drwxrwxrwt结尾这个 t 就是 Sticky Bit粘滞位。它的效果是即使目录对所有人开放 w 权限文件也只能被文件属主或 root删除。这个设计是为了解决共享临时目录的混乱。没有 Sticky Bit 时任何用户都能删除他人在共享目录里创建的临时文件安全隐患和可用性问题都非常严重加上 Sticky Bit 后大家能共享空间却无法互相破坏对方的文件保护了共享目录的基本秩序。如果自己建了共享写入目录比如 /var/shared强烈建议同样加上 Sticky Bitchmod t /var/shared三个特殊权限位设置时也可以用数字法SUID4、SGID2、Sticky Bit1放在常规三位数字的前面。例如 chmod 4775 file 就是给文件设置 SUID rwxrwxr-xchmod 1777 /tmp 就是 Sticky Bit 全员读写执行。但说句实话特殊权限位用符号法更稳妥数字法写错一位影响面太大还是让意图在命令里直接可见比较好。5. 权限问题排查实战从报错到根因的定位链路最后是实战部分。这部分内容来自我踩过的坑和总结的排查方法论希望能帮你在下一次Permission denied出现时不再抓瞎而是有条不紊地顺着链路定位到根因。5.1 权限不足的常见原因拓扑我总结的排查顺序如下确认当前身份和附加组id 命令看 uid、gid、groups。检查路径链路上每一级目录的 x 权限从根目录沿路径逐级 ls -ld。检查目标文件的属主、属组、权限位ls -l。排查特殊权限位干扰检查父目录是否有 Sticky Bit、文件是否有 ACL。排查安全模块干扰SELinux、AppArmor、文件扩展属性chattr。很多人会卡在第 4 和第 5 步。尤其是 SELinux这是 CentOS/RHEL 系默认开启的强制访问控制机制它可以在传统 Unix 权限全部放行的情况下依然拒绝进程访问文件。遇到过的最隐蔽 case 是权限配得很正常、所有传统权限检查都通过Web 服务依然报 Permission denied最后查出来是 SELinux 的 httpd_sys_content_t 标签没有打上。快速判断安全模块影响的方法getenforce # Enforcing 表示强制模式 ls -Z /data/web/index.html # 查看文件的安全上下文标签 chcon -R -t httpd_sys_content_t /data/web # 修正标签临时方案如果确认被 SELinux 阻挡正确做法是给文件打上合理的标签或者用 semanage fcontext 添加持久规则而不是粗暴地 setenforce 0 了事。生产环境关 SELinux等于把一道重要的防线自己拆了。5.2 完整排查案例Docker 挂载卷权限异常说一个我真实遇到过的场景用 Docker 启动了一个 Nginx 容器挂载了宿主机的 /data/web 目录容器内始终报 Permission denied无法写入挂载目录。当时的排查过程如下。先看宿主机目录权限ls -ld /data/web # 返回 drwxr-xr-x 2 root root ...目录是 root:root755 权限宿主侧没问题。但容器内 Nginx 以 nginx 用户运行UID 是 101。宿主机上 UID 101 没有一个对应的账号可内核根本不认识用户名它只认 UID 数字。容器内 UID 101 的进程落在宿主机上就会被当作UID 101 的用户来判定权限而目录 /data/web 属主是 root其他用户只有 r-x所以写入被拒。解决办法是把目录属主改成 101或者把目录属组改成容器内进程的 GID 并放开组写权限。我在生产环境的做法是统一规划应用 UID宿主机和容器用同一对 UID/GIDuseradd -u 10001 -M -s /sbin/nologin appuser chown -R 10001:10001 /data/web然后在 docker-compose.yml 中指定运行时身份services: nginx: image: nginx:latest user: 10001:10001 volumes: - /data/web:/usr/share/nginx/html:rw这样宿主机与容器内使用完全一致的 UID/GID权限问题从根源上消失。这个案例真的要反复讲容器权限问题十有八九不是容器内部的事情而是宿主机 UID/GID 映射关系没理清。5.3 那些容易忽略的权限干扰项最后分享几个容易中招的隐蔽点全部来自我实际运维中碰到过的问题。第一个是 umask 导致的新文件权限异常。umask 是创建文件时的默认权限遮罩常见值 022 表示新文件会去掉其他用户的写权限。如果你的应用经常生成临时文件并需要其他用户写入但权限总是不对先检查启动进程环境的 umask而不是怀疑代码。第二个是 chattr i 的不可修改权限。有些系统加固脚本会给关键文件加上 immutable 属性这时即便你是 root 也无法修改或删除文件。遇到root 都删不掉却没有常规权限报错的情况用 lsattr 查一下lsattr /etc/passwd # 输出中带 i 就说明被锁定了 # 解开方式chattr -i /etc/passwd第三个是挂载文件系统的权限边界。NFS 挂载、FUSE 挂载、Windows CIFS 共享这些文件系统的权限判断有时不完全受传统 Linux 权限位约束。挂载选项比如 noexec、nosuid、root_squash会直接影响行为。排查这类问题要跳出文件权限本身去查 mount 参数。第四个是 ACL 的干扰。如果文件上有 setfacl 设置的额外 ACLls -l 输出的末尾会多一个 号。这时候仅看九位权限位是不够的必须用 getfacl 查看完整的访问控制列表。很多人遇到看起来权限是对的结果还是不行的案例多半就是 ACL 里藏了限制。我自己收到权限类工单的处理习惯是先在脑海里过一遍上面的链路然后让 id、ls -ld 路径各级目录、ls -l 目标文件、getenforce、lsattr 这几条命令的输出一次性到位大多数问题十分钟内都能定位。权限问题最怕的从来不是权限本身而是心里没有排查路径乱试一气。把我是谁和我能干啥这条链路彻底吃透所谓玄学也就变成了日常。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。