ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux权限管理命令详解:从基础概念到实战排障

Linux权限管理命令详解:从基础概念到实战排障 1. 权限管理命令到底在管什么先搞清楚三个基本概念有一次同事部署完一个内部工具浏览器打开直接 403他第一反应是“权限没给够”二话不说chmod -R 777。后来我们把目录整个审计了一遍发现问题根本不在权限位的数字上而是父目录缺少x执行权限nginx的工作进程压根进不去。这件事让我意识到一个事实Linux 权限管理命令大家都会敲但真正理解权限位背后那套组合逻辑的人其实不多。权限管理命令是 Linux 常用命令里最基础也最容易被滥用的一类。它的职责一句话就能说清控制“谁”能对“什么”做“哪些操作”。这里的“谁”是用户身份“什么”是文件或目录“哪些操作”是读、写、执行。今天这篇不聊花活把权限管理命令从概念到排障完整过一遍适合刚入门的运维、后端开发也适合准备 Linux 面试的人。1.1 权限位就是一张“人群 × 动作”的小表格Linux 里每个文件或目录都带着一组权限属性ls -l一眼就能看到。拿一个典型的输出来说-rw-r--r--. 1 root root 1024 Mar 12 10:30 app.conf drwxr-xr-x. 2 root root 4096 Mar 12 10:31 conf.d开头这一串-rw-r--r--一共 10 个字符拆开看就两件事第 1 个字符是文件类型。-表示普通文件d表示目录l表示软链接b/c分别对应块设备和字符设备。后面 9 个字符分成三组每组 3 位分别对应“属主u”“属组g”“其他人o”三类身份的权限。每组里的r是读权限w是写权限x是执行权限没有对应权限就显示-。所以rw-r--r--翻译过来就是属主可读可写属组成员只读其他人也只读。权限管理命令本质上就是在修改这张“人群 × 动作”的小表格。后面要讲的chmod、chown、chgrp、umask、chattr、setfacl全都是围绕它做文章的。提示还有一个特别容易被忽略的细节——文件类型字符之后的那 9 位里如果出现了s、t这种字母说明不是普通权限那么简单那是 SUID、SGID、Sticky Bit 特殊权限位后面专门讲。1.2 日常查看权限的三板斧ls -l或ll最常用的查看方式能看到权限位、属主属组、文件大小、修改时间。id查看当前用户的 uid、gid、所属组列表。遇到“我有权限吗”这种问题第一反应就该先敲id。stat查看文件更完整的信息包括权限位的八进制表示、访问/修改/变更时间、inode 编号等。举个例子stat app.conf输出里会有一行Access: (0644/-rw-r--r--)左侧是八进制权限值右侧是符号权限位。八进制这个形态就是chmod 644这种写法的来源。1.3 权限管理命令全景清单命令作用典型用法一句话记忆chmod修改文件或目录的读、写、执行权限chmod 755 script.sh改权限chown修改文件或目录的属主和属组chown app:app data.log改主人chgrp只修改属组chgrp dev tools.sh改组umask控制新建文件/目录的默认权限umask 027定默认值chattr修改文件的隐藏属性chattr i passwd.txt上锁lsattr查看文件的隐藏属性lsattr passwd.txt看锁setfacl给指定用户/组单独授权setfacl -m u:tom:rw file精确授权getfacl查看文件的访问控制列表getfacl file看 ACLsudo以其他身份默认是 root执行命令sudo visudo临时提权passwd修改用户密码、锁定/解锁账户passwd -l user01管口令su切换用户身份su - app换身份这些命令单独看都不难难的是组合起来解决实际问题的思路。下面逐个拆开讲全部基于真实运维场景。2. chmod 修改权限最刚需也最容易写错chmod是出现频率最高的权限管理命令。它的语法很直观chmod [选项] 模式 文件/目录常见的写法有两类数字法chmod 755和符号法chmod ux。先弄懂数字法再搞符号法两条腿走路才不会瘸。2.1 数字法为什么是 r4、w2、x1r、w、x对应的数字不是拍脑袋定的它们本质上是二进制位的权重r 4二进制 100w 2二进制 010x 1二进制 001把三种权限相加就能得到一个 0~7 的八进制数。例如7 421 rwx可读可写可执行6 42 rw-可读可写不可执行5 41 r-x可读可执行不可写4 r--只读0 ---什么都没有一个权限模式由三位数字组成依次是属主、属组、其他人的权限。chmod 755就是属主 rwx、属组 r-x、其他人 r-x。这个值在 Web 服务目录、脚本、可执行程序上最常见因为属主有完整控制权其他人只能读和执行不能乱改。写几个常用值的含义chmod 644 file.txt # -rw-r--r-- 属主可写其他人只读最常见的数据文件 chmod 600 id_rsa # -rw------- 只允许属主读写私钥文件务必这样设 chmod 750 /data/app # -rwxr-x--- 属主全权属组可读可执行其他人禁止 chmod 777 test.sh # -rwxrwxrwx 所有人全权尽量避免2.2 文件与目录的 x 权限解读完全不一样很多新手把文件和目录的权限套同一个逻辑结果栽在各种奇怪的问题上。对普通文件来说x表示这个文件可以被执行。它通常配合文件头部的 shebang如#!/bin/bash或二进制格式来生效。脚本就算有x权限第一行写错了也会报错没有x权限但用bash script.sh这种方式显式调用依然能跑。对目录来说x的含义就重要多了它表示“是否允许你穿过这个目录”。具体来说目录有r没x你能列出文件名但没法cd进去也没法访问里面的任何文件。目录有x没r你能进入目录但看不到里面有啥除非你知道精确文件名。目录有r又有x既能列目录又能进去访问这是最常见的形态对应755或750。这就是文章开头那个 403 场景的根源nginx工作进程对 Web 根目录的每一层父目录都必须有x权限否则就算文件本身是644也照样无法读取。注意检查权限问题时要沿着路径逐层查/home、/data、/data/www、/data/www/html任何一层少了x都会导致最终访问失败。这个排查方式后面单列一节详细讲。2.3 符号法适合精细调整数字法适合整体设置但如果你想“只给属主加个执行权限其他不改”数字法就得先算出当前值再改很麻烦。符号法就灵活得多chmod ux script.sh # 给属主加执行权限 chmod g-w file.log # 去掉属组的写权限 chmod or readme.txt # 把其他人的权限设置为只读 chmod ax run.sh # 给所有身份加执行权限a 表示 all符号法的格式是“身份 操作 权限”身份有u、g、o、a操作有加权限、减权限-、直接赋值。几个身份可以连写比如chmod ugrw file表示给属主和属组都加上读写权限。我自己的习惯是设置固定权限用数字法增量调整用符号法。尤其是chmod -R批量操作的时候数字法更容易出现问题下面就是实打实的坑。2.4 我在生产环境踩过的两个 chmod 坑坑一chmod -R 777一把梭。这是最经典的运营事故起手式。某个服务报没权限有人直接对整个项目目录chmod -R 777当时业务确实恢复了但带来的问题是所有用户都能读写所有文件。如果里面有配置文件、私钥、日志后果可想而知。正确的做法是先定位是哪个身份、对哪个路径、缺哪个权限只对最小范围做修改。坑二对软链接执行chmod产生误解。chmod命令遇到符号链接时默认不会修改链接本身的权限而是直接操作它指向的目标文件。我见过有人想改链接权限结果把指向的真实文件权限改了然后把链接删掉重建目标文件权限却已经乱了。如果需要修改链接自身的属性通常要用chmod -h某些系统支持更稳妥的做法是直接对链接指向的目标操作或者换chown -h来处理链接属主。2.5 递归授权 -R 的两个副作用chmod -R可以批量修改目录树里所有文件和子目录的权限。但它有两个副作用容易忽略它会把目录和文件设置成同一个权限值。实际场景里目录通常需要x进入权限文件通常不需要所以chmod -R 777这种操作会让所有普通文件都带上执行位既不美观也不安全。遇到符号链接时-R默认不会顺着链接追到目标去修改除非显式加-L或-H选项。这一点在不同发行版上行为基本一致但很多人没意识到导致“我改了怎么没生效”。如果确实需要分别设置目录和文件的权限建议用find配合find /data/www -type f -exec chmod 644 {} \; find /data/www -type d -exec chmod 755 {} \;这样能把文件和目录分开处理是比chmod -R 777文明得多的做法。3. chown 与 chgrp属主属组不对服务一定起不来chmod管的是“能做什么”chown和chgrp管的是“以谁的身份做”。很多服务起不来的原因不是权限位不够而是属主属组根本不对尤其是从别的地方拷贝过来的文件。3.1 先记住这两个命令的完整形态chown 用户:组 文件 # 同时改属主和属组 chown 用户 文件 # 只改属主 chown :组 文件 # 只改属组等价于 chgrp 组 文件 chgrp 组 文件 # 专门的改属组命令chown是谁和组一起管理的chgrp是单独管组的。实际工作中chown用得更多因为改属主的时候通常顺手就把属组一起指定了。举个例子一个 Java 应用以app用户运行日志目录/data/app/logs必须归属app否则进程写日志时会报 permission deniedchown -R app:app /data/app-R同样表示递归适用于目录树。3.2 为什么拷贝文件后命令找不到跨服务器拷贝文件经常遇到一种情况rsync或scp过去以后执行脚本报“Permission denied”或者“No such file or directory”但ls -l一看权限位明明是755。问题往往出在属主上。文件从服务器 A 拷贝过来后属主可能还是原来机器上的 uid。比如源机器上的属主 uid 是 1001叫dev新机器上 uid 1001 对应的是另一个用户bak或者根本没有这个 uid显示成一个数字。服务用户自然跑不了。解决方式就是把属主改对chown -R app:app /opt/deploy/这个命令在部署脚本里几乎是标配。这里还想补充一个细节用 chown 修改属主时建议先于 chmod 执行。因为如果先批量 chmod 再把属主改走中间空窗期文件可能被其他人用旧权限读走反过来先确定属主再收紧权限操作更安全。3.3 chown 不影响权限位但影响能力边界chown修改属主属性不改变rwx那 9 位但它在权限模型里的作用是决定“u 这一组权限到底是给谁的”。同一个文件属主是 root 和属主是 www能力边界完全不同。举个例子一个配置文件-rw-r--r--属主 root那么只有 root 能写其他人只能读。如果某个应用需要写这个文件而应用本身以www用户运行那么只改chmod 666让所有人可写是一种粗暴解法更合理的解法是chown www:app config.conf然后chmod 640或chmod 600把写权限只给www。这就是“权限尽量收敛”的原则。另外一个常见点是软链接。chown默认会顺着软链接修改目标文件的属主这通常不是你想要的。想只修改链接本身的属主用chown -h dev:dev link_file-h表示不要解除引用只针对链接本身。这也是我在实际排障中踩过的一个细节批量chown -R一个目录时里面如果有软链接指向别处的敏感文件链接本身会被跳过但它指向的目标不会被归纳到目录树里所以反而更安全。但如果你单独chown一条链接就要小心它是不是把目标文件改了。4. umask默认权限的“隐形修改器”chmod、chown是主动修改权限umask则是在你新建文件或目录时系统自动套用的一套“默认权限模板”。它不显眼但影响无处不在。很多面试题会考它而且考倒一片人。4.1 umask 的计算不是普通减法umask命令直接输入会显示当前掩码例如$ umask 0022它的作用是新建文件时系统从默认权限里“扣掉”掩码对应的权限。文件的最大默认权限是666目录的最大默认权限是777。为什么文件不是777因为默认情况下文件不应该一创建就带执行权限这是安全设计。严格的计算方式是默认最大权限 (~umask)。用umask022举例文件666 ~022110110110 111101101110110100644目录777 ~022111111111 111101101111101101755这里要特别提醒不要用“666 - 022 644”这种口算方式去套所有情况。它刚好在022这类掩码下数值碰巧成立但换成umask033就出问题了文件666 ~033110110110 110100100110100100644而不是633。目录777 ~033111111111 110100100110100100744。目录的普通减法恰好等于744文件差就大了。所以理解成“按位去掉掩码中置位的权限”才是正确的姿势。4.2 为什么你新建的文件总是 644默认情况下绝大多数发行版的全局umask是022所以普通用户touch a.txt得到-rw-r--r--mkdir dir1得到drwxr-xr-x。这不是某个发行版随意定的而是安全性和可用性平衡的结果文件可写权只留给属主其他人只能读目录也一样。如果你希望新建的文件别人完全不可见可以临时把掩码调严umask 077 touch secret.txt此时文件权限是600只有属主能读写。这个技巧在写临时脚本、创建私密配置文件时非常实用。4.3 改 umask 的正确姿势临时生效直接执行umask 027即可但它只对当前 shell 有效退出终端就失效。要永久生效需要写进 shell 初始化文件里。常见位置~/.bashrc当前用户的交互式 shell 配置~/.profile当前用户的登录 shell 配置/etc/profile全局登录配置/etc/bashrc全局 bash 配置部分发行版路径不同改成什么值取决于安全要求。普通开发机022用得最多服务器上如果强调保密性027很常见此时新建文件为640、新建目录为750同组的人可以查看但不能改其他人一律拒绝。提示umask还有个-S参数能以符号形式显示当前掩码对应的“允许权限”例如umask -S输出urwx,grx,orx。查看时更直观但设置时建议大家还是用八进制。5. 文件隐藏属性与其他权限相关命令chattr、sudo、passwd除了rwx这套权限模型Linux 里还有几个容易被忽略的“外挂”权限机制。它们不是日常必用但关键时刻非常值钱。5.1 chattr 与 lsattr给文件上一道“root 也动不了”的锁chmod对 root 是失效的——root 对所有文件天然有读写权限但如果文件被设置了chattr i就连 root 也不能随意删除或修改。chattr i passwd.txt # 锁定文件不可修改、不可删除、不可重命名 lsattr passwd.txt # 查看隐藏属性输出如 ----i--------- passwd.txti是 immutable不可变属性通常用于保护关键配置、证书文件、日志目录里的重要文件。要解除时执行chattr -i passwd.txt。另一个常用属性是aappend-only只允许追加内容不允许覆盖和删除。日志文件配合这个属性很合适能防止进程“清空日志”这类误操作但注意有些日志轮转工具logrotate会因为无法重命名文件而报错需要提前处理。chattr本身不算权限管理命令的“正册”但它是权限体系里最后一道硬保护排查问题时往往会兜底。5.2 sudo 与 visudo普通用户执行特权命令的合法通道聊到权限就绕不开“提权”这个话题。面试题里经常出现网络上热搜词也有“linux提权”。正规的提权路径最基础的就是配置sudo而不是什么偏门漏洞技巧。运维上说的“给某用户提权”通常是配置 sudoers让他能执行特定命令。查看当前用户能执行哪些 sudo 命令sudo -l修改 sudo 授权文件的正确姿势是sudo visudovisudo会先做语法检查再落盘避免你写错一个字符导致整个系统 sudo 不可用。/etc/sudoers文件里常见的配置dev ALL(ALL:ALL) ALL # 允许 dev 用户执行所有命令需要密码 %wheel ALL(ALL:ALL) NOPASSWD: ALL # 允许 wheel 组成员执行所有命令免密 dev ALL(ALL) /usr/bin/systemctl restart nginx # 只允许 dev 重启 nginx最后一条是最小权限的典范只给需要执行的命令而不是全部放开。生产环境里“能用具体命令就不要开放所有”这是铁律。常见场景是普通用户部署服务时需要重启服务但他不该有整台机器的 root 权限。用visudo加一行精确授权既满足需求又控制风险。5.3 passwd 与 su账户口令和身份切换的边界passwd不只是改密码那么简单它还能锁定账户、查看密码状态passwd testuser # 修改 testuser 的密码 passwd -l testuser # 锁定账户拒绝登录 passwd -u testuser # 解锁账户 passwd -S testuser # 查看账户密码状态账户锁定之后该用户无法通过 SSH 或终端登录但已经在运行的进程不受影响。这个点经常被面试官拿出来考锁账户 ≠ 杀掉进程。su是切换登录身份的命令。su - app会切换到 app 用户并加载其完整环境su app则保留当前环境变量。日常排障时切换到目标服务用户去复现问题是权限排查的常用手段。需要注意su切换到别的用户需要输入目标用户的密码而sudo su -走的是当前用户的 sudo 授权不需要目标用户密码这也是运维里更推荐的方式。6. 特殊权限位 SUID / SGID / Sticky Bit面试重点和事故高发区前面讲过ls -l输出的权限位里除了rwx偶尔还会看到s和t。这些是特殊权限位理解它们才算真正把权限管理命令吃透。6.1 SUID为什么普通用户也能改自己的密码先看一个文件ls -l /usr/bin/passwd -rwsr-xr-x. 1 root root 36240 /usr/bin/passwd注意属主权限位的rws这个s就是 SUIDSet User ID。它的作用是当一个可执行文件设置了 SUID 时任何用户执行这个文件进程会临时获得文件属主的身份。/usr/bin/passwd的属主是 root普通用户执行它时进程以 root 身份运行因此可以写/etc/shadow这种只有 root 能访问的文件。如果没有 SUID普通用户根本没机会改自己的密码。设置 SUID 的方式chmod us /path/to/file chmod 4755 /path/to/file # 4 开头表示 SUIDSUID 的危险性也在这里如果某个 root 属主的程序被设置了 SUID等于任何执行它的人都能短暂获得 root 能力。排查系统中异常的 SUID 文件是所有安全加固的必查项find / -type f -perm -4000 -ls看到权限位里出现-rwsr-xr-x时都要多留个心眼尤其是那些不该有 SUID 的可执行文件。如果在某个非系统路径下发现属主为 root 且带s位的陌生文件大概率是异常。6.2 SGID团队协作目录的继承魔法SGIDSet Group ID和 SUID 类似但它作用在属组权限位上。文件设置 SGID 后执行进程会临时获得文件属组的身份目录设置 SGID 后在目录里新建的文件和子目录会自动继承该目录的属组。团队共享目录是 SGID 的最佳实践场景。比如一个项目组共享/data/shared要把组统一成devchown root:dev /data/shared chmod 2770 /data/shared # 2 开头表示 SGID同时设置 770 chmod gs /data/shared # 或者用符号法完成之后任何dev组成员在这个目录里新建的文件属组都会自动变成dev不会因为创建者自己的主组不同而出现乱七八糟的属组归属。这个特性在多人协作目录、代码共享目录里特别好用。6.3 Sticky Bit临时目录为什么别人删不了你的文件/tmp目录的权限是drwxrwxrwt最后一个t就是 Sticky Bit粘滞位。它的作用是在设置了 Sticky Bit 的目录里只有文件属主、目录属主或 root 可以删除或重命名文件其他用户即使有目录写权限也删不动别人创建的文件。/tmp是公共目录所有人都能创建文件但没有 Sticky Bit 的话任何人都能删除其他人的临时文件那早就乱套了。共享上传目录、缓存目录也经常设置 Sticky Bitchmod t /data/upload chmod 1777 /data/upload # 1 开头表示 Sticky Bit6.4 特殊权限位的大小写暗藏玄机ls -l输出里如果对应的x权限存在特殊位显示小写s或t如果x权限不存在则显示大写S或T。比如rwsr-xr-x说明属主有执行权限才显示小写s而rwSr-xr-x说明属主没有执行权限SUID 形同虚设但依然存在。这个细节偶尔会出现在面试题和排障里看到一个S大写先别急着以为安全它只是“没有执行权限的 SUID 位”设置方式不算规范最好清理掉。特殊权限位的八进制前缀总结数字前缀含义典型值4SUID47552SGID27701Sticky Bit1777426SUID SGID67557. 实战权限管理命令综合排障流程命令学了一大篇最终要落到排障上。这里分享三个我在工作中反复遇到的权限类故障以及对应的完整排查链路。7.1 场景一部署完 Web 服务浏览器 403现象页面返回 403 ForbiddenNginx 日志里写着Permission denied。错误的反应是直接chmod -R 777。正确的链路是# 1. 确认 nginx 工作进程用什么用户跑 ps aux | grep nginx # 2. 切换到这个用户尝试访问文件 su - www -s /bin/bash -c cat /data/www/html/index.html # 3. 如果读不了逐层看路径权限用 namei 最直观 namei -om /data/www/html/index.htmlnamei -om这条命令会列出路径上每一层的权限位和属主属组非常直观。输出类似f: /data/www/html/index.html dr-xr-xr-x root root / drwxr-xr-x root root data drwx--x--x root root www -rw-r--r-- root root index.html一眼就能看出问题www目录权限是drwx--x--xwww用户对它只有x没有r列表不出来而且nginx也没有足够的读取通道。然后针对缺的权限做精确修改就好。7.2 场景二上传目录写不进去但没有报权限错误现象应用能读文件但上传新文件失败或者日志能写但轮转失败。先确认上传目录的属主和运行用户是否一致ls -ld /data/www/upload ps aux | grep php-fpm # 或 java、python看运行用户 stat /data/www/upload最常见的结局是运行用户是www上传目录属主是root权限是755。www用户根本没有写权限。这种问题不是权限位不够而是属主不对。但注意 Web 服务不会总是用www有的用nginx有的用apache还有的是daemon一定要以实际进程为准。修复方式分两步chown -R www:www /data/www/upload chmod 750 /data/www/upload如果同一个目录要给多个服务用户写入可以用 ACL 做精细授权而不要随便chmod 777setfacl -m u:backend:rwx /data/www/upload7.3 场景三普通用户执行某个命令需要 sudo但无法配置现象开发同事需要一个权限执行systemctl restart nginx你不想给他 root。修改点只有/etc/sudoers注意用visudosudo visudo加入dev ALL(ALL) /usr/bin/systemctl restart nginx然后让同事执行sudo systemctl restart nginx注意逗号和路径的复杂度systemctl实际路径用which systemctl查一下不同发行版可能不同。如果配置错了sudo 会直接拒绝执行通常不会导致整个系统 sudo 崩溃但visudo自带的语法检查就是为这种失误兜底的。7.4 排查思路小结权限排障最重要的是确定三个信息操作者是谁、路径层级权限如何、目标文件的属主属组是什么。症状优先怀疑第一排查命令常见修复403 / 读不了父目录缺 xnamei -omchmod 755 父目录写不了 / 上传失败属主不对statpschown -R 运行用户:组 目录执行脚本没反应缺 xls -lchmod x script.sh服务反复报权限特殊权限被改lsattrchattr i保护多用户协作混乱属组错乱ls -ldSGID 目录继承8. 面试与日常高频考点权限命令的进阶细节既然书读到这里顺手把权限相关的面试高频点整理一下。这一部分对准备 Linux 岗位面试的人尤其有用。8.1 面试常考的知识点整理以下是权限方向上最容易被拎出来问的问题chmod 777和chmod 666分别是什么权限什么时候用文件默认权限为什么是 644 而不是 666 或 755关键在 umask 和执行位不默认开放。chown和chmod的本质区别在哪里一个管属主一个管操作权限。普通用户为什么能通过/usr/bin/passwd修改密码SUID 在这里起什么作用/tmp目录为什么所有人都能创建文件但不能互相删Sticky Bit 的作用。setfacl能做什么chmod做不到的事情精确到单个用户的授权。sudo 和 su 的区别是什么sudo 基于授权策略su 需要目标用户密码。如何查找一个系统里所有带 SUID 的文件find / -perm -4000 -type f。8.2 容易忽略但面试会挖的细节x权限对目录和文件的意义完全不同能展开讲是最佳加分项。umask的计算不是普通减法033掩码下文件权限与“666 - 033”不等。大小写S/s、T/t的区别能看出执行权限是否存在。chattr i是 root 也无法直接违反的权限限制除非先chattr -i。sudo -l能查看当前用户可执行的授权命令这也是 Linux 常用命令里被低估的排障工具。8.3 一个实战向的复习建议准备面试或想巩固命令记忆不要死记命令参数直接把一台测试机上折腾出一系列问题再修复用useradd新建用户用chown把目录分给某个用户用umask控制默认权限用setfacl给另一个用户单独开写权限最后用visudo精确限制他能执行的命令。这一套走下来权限管理命令不会再有死角。顺便说一下现在国产 Linux 发行版越来越常见热词里也有“linux国产”的搜索趋势。不管用什么发行版权限体系都是同一套 POSIX 模型命令完全通用。这可能也是权限管理命令一直排在 Linux 常用命令热榜前列的原因。最后分享一个我自己的实际操作习惯所有权限变更操作能加-v参数显示变更明细的我都会加上批量操作之前一定先ls -ld看一眼现状再stat确认没有特殊权限位遗漏。权限不怕你权限给得少怕的是稀里糊涂给了一大片。熟练使用这些命令之后你会慢慢形成肌肉记忆排查问题时第一反应就不再是盲目的chmod -R 777而是一层层顺着身份、路径、权限的关系把问题挖出来。
返回列表