☰
Linux用户与权限核心详解:从用户组、chmod/chown到sudo实战
2026/10/14 12:38:58 网站建设 项目流程

说实话,我刚接触Linux那会儿,最头疼的不是命令数量多,也不是编辑器那套反人类的按键逻辑,而是搞不清“用户与权限”到底在管什么。明明是自己的机器,为什么用普通用户创建的文件,换到root账号下面看就感觉别扭;为什么一个目录明明设了777,其他用户还是进不去。这些问题如果不系统捋一遍,后面不管是部署服务、搭环境还是排查服务器故障,都会反复踩坑。到现在我给人做Linux入门培训,也总是把“用户与权限”这块单独拎出来讲,因为它直接决定了你敲的每一行命令能不能生效、系统里的每个文件是不是安全。这篇笔记就是我结合平时学习和实战整理的完整版,一次性把用户管理、权限位、chmod/chown、特殊权限、sudo这些内容讲透,刚上路的新手可以照着操作,有基础的人也能补上一些容易忽略的细节。

1. 用户与组:先看清管理对象

1.1 用户信息记录的底账:/etc/passwd 和 /etc/shadow

在动手敲命令之前,先得知道Linux把用户信息存放在哪里。很多人以为用户信息是一个“数据库”,其实它就是一串文本文件,核心的两个是/etc/passwd和/etc/shadow。

/etc/passwd每一行对应一个用户,典型长这样:

root:x:0:0:root:/root:/bin/bash zhangsan:x:1000:1000:zhangsan:/home/zhangsan:/bin/bash

字段从左到右分别是:用户名、密码占位符、UID、GID、注释信息、家目录、默认Shell。中间的x表示真正的密码不放在这个文件里,而是放到/etc/shadow,因为/etc/passwd全局可读,谁都能看。所有用户信息都在这两个文件里,这也是为什么root能直接修改文件内容来增删用户,但正规操作还是走useradd、usermod这些命令,避免手一抖改坏格式。

这里必须理解UID的含义。UID为0的账户就是超级用户,也就是root;1到999(不同发行版边界略有不同)通常是系统服务账户,比如sshd、nginx、mysql,它们没有实际登录Shell,纯粹为了隔离权限而存在;1000及以上才是普通用户。系统判断“你是谁”靠的是UID,不是用户名,用户名只是给人看的壳。所以哪怕你把一个普通用户的用户名改掉,只要UID没变,它的权限范围就不会变。

/etc/shadow里存放的是加密后的密码哈希、密码最后修改日期、过期策略等信息,只有root和少数管理组成员能读。这里有个常见的误解:密码字段显示为!!或*,不代表密码为空,而是表示该账户处于锁定状态,不能登录。

1.2 用户组背后的三个关键文件

用户组的信息记录在/etc/group里,一行对应一个组,格式如下:

sudo:x:27:zhangsan,lisi

字段含义比passwd还简单:组名、组密码占位符、GID、组成员列表。组密码一般用不到,对应文件是/etc/gshadow,里面存的是组密码和组管理员信息。

初次接触的人容易把“组”理解成一种权限模板,其实更准确的说法是“权限聚集地”。一个用户可以在多个组里,这些组通过GID关联。在Linux里,用户至少会出现在两个地方:passwd里的GID字段是他的主组(也叫初始组),/etc/group里列出的额外组叫附加组。文件默认归属的组是创建者的主组,而不是他所在的所有组。如果你想用某个组的身份去访问文件,确保自己是该组成员,这个在后面讲权限位时特别重要。

1.3 常用用户管理命令与注意事项

用户管理日常用到的基本就这几个命令,我直接列成速查表:

命令作用常用参数与备注
useradd创建用户-m创建家目录,-u指定UID,-g指定主组,-G指定附加组
usermod修改用户属性-aG追加附加组,-s改Shell,-L锁定账户,-U解锁
userdel删除用户-r连同家目录和邮件池一起删
groupadd创建用户组-g指定GID
groupdel删除用户组该组若已是某用户主组则删不掉
passwd设置密码root可以给任何用户设密码,普通用户只能改自己的
id查看用户UID与所属组排查权限问题时第一件事执行id
whoami查看当前身份简单但不常用,正式环境一般看id

实际操作中我见过不少新手踩坑:useradd创建用户后,直接ssh登录发现进不去,原因是还没有用passwd设置密码,或者用户根本没有家目录。还有个容易忽视的点:usermod加附加组时如果漏掉-a,会把用户原来的附加组全部覆盖掉。比如用户原来在docker组里,你执行usermod -G wheel zhangsan,他立刻就从docker组里被踢出去了。改成usermod -aG wheel zhangsan才是追加。这个错误在配置sudo权限时极其常见,一旦发生,用户可能连正常业务都跑不了。

建议新手做完每个用户操作后,用id 用户名确认一下UID和组列表,再切换用户实测,别光看命令输出就完事。

2. 文件权限:看懂权限位才能真正动手

2.1 九个权限位如何读懂

用ls -l查看任意文件,输出的第一列是最核心的信息:

-rw-r--r--. 1 root root 0 Jan 8 10:00 test.txt

第一列去掉开头的类型字符,剩余正好九个字符,分成三组,每组三个,依次代表“属主(u)权限”“属组(g)权限”“其他人(o)权限”。每组三个字符对应读(r)、写(w)、执行(x),有权限就显示对应字母,没有就用-占位。

三个角色要分清楚:属主通常是文件创建者,属组是文件所属组的任何成员,其他就是不属于前面两者的所有人。root是个例外,前面说的这套权限判断规则在root面前基本失效,root对绝大多数文件拥有无条件的读写权限,这才让它能管理系统。

开头那个类型字符同样重要:-是普通文件,d是目录,l是符号链接,c是字符设备,b是块设备。有人看到符号链接权限是lrwxrwxrwx,以为它权限很宽,其实符号链接本身的权限没有实际意义,系统最终看的是它指向的目标文件权限。这个细节在排查问题时容易让人绕弯。

2.2 数字权限与符号权限的等价转换

数字权限的表象是三个数字,本质是三组二进制的缩写。每个权限位对应一个数值:r=4,w=2,x=1,相加得到该角色的权限。举例:rwx=7,rw-=6,r--=4,--x=1。

常见的组合我需要反复强调:755代表属主可读可写可执行,属组和其他人可读可执行,这是很多二进制程序和静态资源的标准配置;644代表属主可读可写,其他人只读,这是普通配置文件的正解。新手如果把文件设成777,虽然解决了临时访问问题,但也把系统内部文件暴露给所有用户了,属于典型的图省事留后患。

符号模式则是在命令行直接用人能读懂的字母操作,不涉及数值计算。形式是“角色 操作 权限”,角色用u、g、o、a,操作用+、-、=,权限用r、w、x。比如chmod u+x script.sh给属主加执行权限,chmod go-w app.conf去掉属组和其他人的写权限,chmod a=rw file把所有人权限统一设为可读可写。数字模式适合批量设定完整权限,符号模式适合微调局部权限,两者没有谁绝对更好,都得会。

2.3 目录权限的特殊性:x位决定能不能进入

目录的权限和普通文件的含义完全是两码事,这是新手最容易懵的地方。

对目录来说:

  • r权限:能列出目录里的文件名。
  • w权限:能在目录里创建、删除、重命名文件。
  • x权限:能进入这个目录,也就是能cd进去,同时决定了在访问目录内文件时,系统能否遍历到这些文件。

关键在于只给r不给x时,你可以ls看到文件名,但看不到文件的元数据详情,更没法cd进去获取文件内容。很多人在部署网站时遇到“目录权限明明设了644,页面还是403”,就是因为644对目录来说缺少x权限,Web服务无法进入目录。正确做法是目录用755或750,文件用644或640。理解了这个区别,很多权限问题迎刃而解。

另外还有一个常被忽略的坑:访问某个路径时,路径上的每一层目录都必须有x权限。比如访问/home/user/project/logs/app.log,如果/home/user权限是700且你当前用户不是该目录属主,后面即使logs设了777也进不去。排查这种问题时,用namei -l /home/user/project/logs/app.log一下就能看全部层级权限,比手动逐层ls快得多。

3. chmod与chown实战:权限修改的实施细节

3.1 chmod符号模式的完整操作

符号模式精细控制权限时特别好用,我在脚本部署类场景里几乎每天都要用到。几个典型的写法:

# 给脚本添加执行权限 chmod +x deploy.sh # 仅给属主加执行权限,属组和其他人不动 chmod u+x deploy.sh # 去掉属组和其他人的写权限 chmod go-w config.conf # 把属主权限设为读写执行,属组设为读执行,其他人清空 chmod u=rwx,g=rx,o= config.conf

这里有个细节:chmod +x不加角色前缀时,默认对所有角色生效,也就是等价于a+x。而chmod u+x只针对属主。批量管理时我一般显式写清角色,避免“我想给属主加,结果所有人都能执行”的误操作。

chmod还支持递归参数-R,但用起来要非常小心。chmod -R 777 /some/dir会把整个目录树所有文件都覆盖成高权限,这在生产环境属于高危操作。更稳妥的做法是用find配合-exec或管道xargs,只对目录或只对文件分别设置。比如:

# 目录统一755,文件统一644 find /var/www/myapp -type d -exec chmod 755 {} \; find /var/www/myapp -type f -exec chmod 644 {} \;

这样既满足了目录要有x权限、文件无需x权限的原则,又避免把执行权限错误地加到所有文件上。我之前接手的某台服务器,前任就是执行了chmod -R 777,导致整站文件全部可写,一旦被上传恶意脚本就是灾难,清理由此麻烦了不少。

3.2 chown与chgrp的使用时机

chown负责改属主和属组,chgrp单独改属组。实际用法:

# 同时修改属主和属组 chown zhangsan:developers app.log # 只修改属主 chown zhangsan app.log # 只修改属组 chown :developers app.log # 等价于 chgrp developers app.log

关于这个冒号,要注意chown zhangsan:developers中的冒号可以用点号替代,写法兼容但容易混淆,建议统一用冒号。chown zhangsan app.log只改属主,chown :developers app.log只改组,chown zhangsan: app.log则把属主改成zhangsan,同时组改成zhangsan的主组,这个简写容易忘。

什么时候必须动chown?最常见的场景是把应用目录的属主改成运行该程序的用户。比如你的Java服务以appuser身份运行,那么日志目录必须是appuser拥有,否则程序想写日志时就会Permission denied。同理,Web服务上传目录一般归www-data或nginx用户所有。不修改属主,光调文件权限位是解决不了根本问题的。

用chown -R的时候同样要克制,修改属主通常比修改属组风险更高,特别是系统目录。我建议每次递归改属主之前,先想清楚:这个目录下的所有文件真的都要给这个用户吗?有没有哪些系统文件混在里面?

3.3 umask默认权限的计算逻辑

每次新建文件或目录时,系统会根据umask自动压缩权限,这就是为什么你新建的文件默认不是777而是644,新建目录默认不是777而是755。

umask的值本质上是“要屏蔽掉的权限位”。文件基准是666,目录基准是777,分别减去umask值得到最终权限。umask为022时,文件是666-022=644,目录是777-022=755。注意这里默认文件没有x位是系统有意为之,防止新建脚本立刻变成可执行导致安全隐患。

查看当前umask直接敲umask,临时设置就执行umask 022。如果想永久生效,需要写到Shell配置里(比如Linux下常见的是配置在/etc/profile或用户的.bashrc里)。多用户服务器上,我习惯给运维用户设置027甚至077,这样组内其他人和外部默认读不到新文件,需要共享时再单独授予权限。这比创建完文件之后再收敛权限省事得多,也避免了文件先裸奔一阵的窗口期。

这里实际计算有个边界情况:如果umask对应位上的权限本身在基准里就是0,那减去后不会出现负数,结果就是0。比如umask 777时新建文件权限是000,因为每一位都被屏蔽了。

4. 特殊权限与sudo:权限体系中的“放大器”和“闸门”

4.1 SUID、SGID、粘滞位的原理与风险

基础权限位之外,Linux还隐藏着三个特殊权限位,平时不显眼,出事就是大事。

第一个是SUID,表现为属主执行位变成s(小写)或S(大写,表示原本没有x权限位)。它的作用是:当普通用户执行这个程序时,进程的属主临时变成该程序的属主,而不是执行者本人。最经典的例子是/usr/bin/passwd,普通用户执行它修改密码时,需要写入/etc/shadow,这个文件只有root能写。正因为passwd命令带SUID,执行瞬间进程以root身份运行,才能完成密码写入。如果去掉passwd的SUID位,普通用户就没法自己改密码了。

排查服务器时,重点关注系统里所有带SUID的可执行文件,因为SUID一旦被恶意利用,等于给了提权后门。常规检查命令:

find / -perm -4000 -type f 2>/dev/null

第二个是SGID,作用于文件和目录时效果不同。作用在文件上时,进程的属组变成文件的属组;作用在目录上时,该目录下新建文件的属组会自动继承目录的属组,而不是创建者的主组。这个特性非常适合团队共享目录:大家在同一目录下协作,新文件天然属于同一个组,不用每次chgrp。

第三个是粘滞位,作用于目录时表现为其他执行位上的t。它的作用是目录内只有文件属主(或root)可以删除自己的文件,即使目录权限是777。最典型的就是/tmp目录,所有人都有读写执行权限,但谁都不能删别人的临时文件。检查所有权时看到/tmp权限是drwxrwxrwt,那个t就是粘滞位。给公共共享目录设置粘滞位是个好习惯,避免组员互相删文件。

这三个特殊权限用数字表示时,刚好对应在权限数字前面多加一位:SUID=4,SGID=2,粘滞位=1。比如chmod 4755给程序加SUID,chmod 1777给目录加粘滞位。也可以用符号模式:chmod u+s、chmod g+s、chmod o+t。

4.2 sudo的配置与最小化授权

sudo是普通用户临时获得root权限的闸门,配置在/etc/sudoers里。修改这个文件必须用visudo命令,它会做语法检查,防止你写错格式导致sudo全部瘫痪。

sudoers的基本语法是:

用户或组 主机名=(可切换用户) 可执行命令

常见的几种写法:

# 给wheel组所有用户完整root权限 %wheel ALL=(ALL) ALL # 允许某用户无需密码执行systemctl zhangsan ALL=(ALL) NOPASSWD: /usr/bin/systemctl # 允许某用户以apache身份执行命令 lisi ALL=(apache) /usr/sbin/httpd

关于主机名这一项,单机上填ALL就行。后面的括号表示允许切换成哪个用户,默认是root。命令列表务必写全路径,否则sudo找不到对应命令,还会带来找不到命令的错觉。

我见过太多人偷懒直接给用户加%wheel ALL=(ALL) ALL,让运维人员都成了准root。合理做法是“最小授权”:用户只需要重启某个服务,就只给systemctl restart 服务名的权限;只需要读某个日志,就让他直接读对应文件,根本不用给sudo。把sudo的权限范围控制到命令粒度,既能做事,又不会放大风险。多用户生产环境里,我还习惯把带NOPASSWD的权限压到最少,尽量减少免密入口。

4.3 实战场景:普通用户临时提权

实际工作中,sudo的使用频率远超su。su是切换用户,需要目标用户密码;sudo是提权执行,输入的是当前用户的密码,而且有日志记录。日常运维应主推sudo而不是su,因为sudoorable的操作记录可以在/var/log/secure里查得到,出问题便于回溯。

一个典型场景:普通用户需要安装系统包。直接执行yum install或apt install会报权限不足,标准做法是:

sudo apt update sudo apt install -y nginx

如果我们在sudoers里只给了包管理权限,那么这位用户能装包,却无法随意修改系统文件。这种精细授权在多团队共用的服务器上尤其有价值:后端团队能重启自己的服务,但不能动数据库;前端团队能读发布目录,但没有sudo权限。说白了,sudo让你能“借力”而不是“接管”,系统还是牢牢控制在root手里。

我自己管理服务器时,几乎从不远程直接登录root,平时都是普通用户加sudo。这样好处很明显:操作之前多一道确认碰撞,误操作的执行面被限制在当前命令;真出事也清楚是哪条命令哪个人执行出现的,不会变成一锅糊涂账。

5. 权限问题排查:遇到Permission denied怎么办

5.1 定位问题的思考顺序

每次遇到Permission denied,我的排查顺序已经套路化了,写下来供你参考:

第一步,确认当前身份是谁。执行id,搞清楚当前用户的UID,以及它在哪些组里。这个信息比命令后面的错误提示更有用。

第二步,检查目标的属主和属组。ls -ld目标路径,看目标属于哪个用户、哪个组。这里有个关键:如果当前用户在属组里,走的是g权限位;如果不在,走的是o权限位。很多人纠结“我明明在组里,为什么还没权限”,大概率是因为组权限位本来就设成-。

第三步,从根路径开始逐层检查目录权限。前面说过,访问文件涉及路径上每级目录的x权限。namei -l可以一次性看到完整路径的权限矩阵。这条命令在排查时的高效让很多人直观地感受到了价值,比一层层ls快得多。

第四步,考虑特殊权限和ACL。用getfacl查看是否有基于ACL的额外授权。加上SELinux环境下,即使传统权限放行,SELinux策略也可能拦截,这时看审计日志才能定位到真正的拦截原因。我遇到过不少案例:公司内部服务器权限看起来完全正常,用户死活写不进文件,最后一查是SELinux enforcing状态在“作祟”,传统权限规则只是前提条件,不是全部。

5.2 常见场景复盘

我把工作中高频遇到的权限问题整理成了一张表,算是排障速查:

场景典型现象常见根因解决思路
SSH登录失败密钥被拒绝~/.ssh权限过宽或authorized_keys权限过宽.ssh目录设700,authorized_keys设600
网站403能访问首页但子目录打不开目录缺少x权限目录755,文件644
服务写日志失败应用报Permission denied日志目录属主不对chown应用用户,目录设755或775
共享目录互相删文件组员能删别人文件目录缺粘滞位chmod +t或chmod 1777
普通用户装软件失败提示权限不足需要sudo按最小授权配置sudoers
挂载盘写入失败明明有权限还是写不了挂载选项只读或noexec检查mount输出和fstab
定时任务不执行脚本手工能跑自动不行脚本权限无x或环境变量缺失chmod +x,注意cron环境PATH较窄

SSH那个问题值得单独强调。openssh对密钥文件权限非常敏感,~/.ssh目录如果设置成755,authorized_keys设置成644,服务端会认为文件不安全,直接拒绝使用密钥登录,报错信息还很含糊。我一个同事排查了几小时,最终发现就是权限问题。配置SSH密钥后,记得检查一遍权限:~/.ssh必须是700,authorized_keys必须是600,私钥600,公钥644,这是死规矩。

5.3 安全加固视角的权限检查清单

权限管理不只是把业务跑起来,还要防着自己人犯错、防着攻击者提权。按下面的清单定期过一遍服务器,能清掉大部分隐患:

  • 检查所有用户家目录权限,非本人都无权访问,至少是750或700。
  • 检查系统全局可写文件:find / -xdev -type f -perm -002,全局可写文件越少越好。
  • 检查SUID文件:find / -xdev -perm -4000 -type f,确认每个都是系统需要的。
  • 检查sudoers配置,去掉不必要的ALL授权和NOPASSWD。
  • 检查空密码账户:awk -F: '($2=="")' /etc/shadow,空密码账户必须立即锁定。
  • 检查/etc/group里wheel或sudo组人数,原则上只保留真正负责系统管理的人。
  • 检查定时任务目录和脚本的属主,确保不能被其他用户改写。
  • 定期审计/var/log/secure里的sudo和su记录,发现异常授权及时收回。

这套清单不需要每天都做,但上线新服务、新人员加入后最好跑一遍。权限这个东西,越到后期越难收敛,一开始就养成最小化授权的习惯,后面会省很多事。

最后再分享一点个人体会:权限问题有时候不是技术问题,而是管理问题。多人共用服务器时,最忌讳的就是动辄把权限调大到777、把sudo权限给一组人、把属主随便chown到运行用户。每一次破例都在为未来的失控埋单。我在实际维护中慢慢养成一个习惯:凡是遇到权限报错,先不问“怎么放开”,而是问“为什么他能访问这个文件”以及“他应该以什么角色访问”。带着这两个问题去设计权限,方案和默认做法会截然不同。Linux的权限体系其实并不复杂,复杂的是在开放和可控之间找到平衡点,这块想明白了,后面学SELinux、容器权限、Kubernetes安全上下文都会顺畅很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询