Linux 用户、密码、组、权限详解——Linux用户权限体系入门

Linux系统 0 876 团子精英 收藏

    刚接触 Linux 的时候,很多人都会被 /etc/passwd/etc/shadow/etc/group 这几个文件,还有 ls -l 里那一堆 rwxr-xr-x 搞得云里雾里。其实这套东西的逻辑并不复杂,理清楚"谁是谁、谁属于谁、谁能干什么"这三个问题,基本就掌握了一大半。


这篇文章分成两部分:

第一部分讲清楚基础的四块内容——用户档案、密码、组、文件权限;

第二部分补充一些实际运维中绕不开、但入门教程经常漏讲的内容,比如 umask、SUID/SGID、ACL,以及企业环境里用户身份到底是怎么被识别和认证的。



第一部分:基础四件套

一、每个用户的"身份证":/etc/passwd

系统里的每一个用户,都会在 /etc/passwd 里留一条记录:

cat /etc/passwd

格式是用冒号隔开的七列,比如:

root:x:0:0:root:/root:/bin/bash
  1. 用户名

  2. 密码占位符:永远是 x,真正的密码不存在这里(下面会讲)

  3. UID(用户编号):系统内部真正认的是这个数字,root 固定是 0

  4. GID(主组编号):这个用户默认所属的组

  5. 用户信息备注

  6. 家目录root/root,普通用户一般是 /home/用户名

  7. 登录 Shell:如果是 /sbin/nologin,说明这个账号不允许登录,通常是系统内部服务专用的账号

关于 UID 的编号范围0 永远是 root,这个是固定的;但"系统账号用 1~999、普通用户从 1000 开始"只是很多发行版的默认惯例,具体范围其实由发行版和 /etc/login.defs 里的配置决定,不同环境可能不完全一样,不建议当成写死的规则去记。

记住一句话:passwd 存的是用户的"户口信息",不存真密码。


二、真正的密码藏在这里:/etc/shadow

/etc/shadow 只有 root 能读,安全性更高,格式是九列:

root:$6$aHtE6jAFkMG...:18000:0:99999:7:::
  1. 用户名

  2. 密码哈希值:这里更准确的说法是"哈希"而不是"加密"。Linux 并不会把密码"加密后存起来、需要时再解密",而是通过哈希算法(配合随机 salt)把密码变成一段不可逆的字符串存起来,登录时用同样的算法处理输入的密码,比对哈希结果是否一致。前缀 $6$ 一般代表用的是 SHA-512 算法。这一列如果是 !!,表示从未设置过密码;开头是 !,表示账号被锁定

  3. 上次改密码的日期:从 1970-01-01 起算的天数

  4. 密码最短使用天数0 表示不限制

  5. 密码最长使用天数:默认 99999,相当于永不过期

  6. 过期前提醒天数:默认 7 天

  7. 密码过期后的宽限天数

  8. 账号失效日期:空着表示一直有效

  9. 保留字段

一句话总结:passwd 负责"你是谁",shadow 负责"你的密码哈希和有效期"。


三、"部门"是怎么划分的:/etc/group

组的信息存在 /etc/group,格式是四列:

root:x:0:
  1. 组名

  2. 组密码占位符:真正的组密码在 /etc/gshadow,实际生产环境基本用不到

  3. GID

  4. 附加成员列表:把这个组当"兼职组"的用户(逗号分隔)。主组是这个组的用户不会出现在这一列

新手最容易搞混的概念——主组 vs 附加组

  • 主组:每个用户创建时都会分配一个主组(默认是和用户名同名的私有组),只能有一个。

  • 附加组:主组权限不够用时,再把用户加进别的组,一个用户可以有多个附加组。


四、文件到底谁能读、谁能改:目录文件属性

ls -l

看到类似这样一行:

-rw-r--r-- 1 root root 1.3K Feb 10 20:30 anaconda-ks.cfg

依次是:文件类型+权限位、硬链接数、属主、属组、大小、修改时间、文件名

重点看第一段的 10 个字符:

-  rw-  r--  r--↑   ↑    ↑    ↑类型 属主 属组 其他人

第 1 位是文件类型

符号含义
-普通文件
d目录
l软链接
b块设备文件
c字符设备文件
p管道文件
s套接字文件

后 9 位是权限,三个一组分别对应属主(u)、属组(g)、其他人(o),每组内是读(r)写(w)执行(x)。数字对照表:

权限二进制数字
---0000
--x0011
-w-0102
-wx0113
r--1004
r-x1015
rw-1106
rwx1117

比如 755,就是"属主可读可写可执行、属组和其他人可读可执行",程序、脚本、目录都很常用这个组合(脚本能不能真正跑起来,还要看解释器、noexec 挂载参数、SELinux 等因素,属于更进阶的话题)。

一个容易理解偏的地方:目录的 x 到底是什么权限。

严格来说,目录的 x 表示的是能不能"穿越/搜索"这个目录,而不只是简单等同于"能不能 cd 进去"。举个例子:

chmod 111 dir

这时候你不能 cd dir,也不能 ls dir 列出目录内容,但如果你已经知道目录里有个文件叫 test.txt,并且这条路径上其它权限也允许,你依然可以:

cat dir/test.txt

也就是说,x 权限控制的是"能否穿过这个目录去访问里面的东西",r 权限控制的是"能否列出目录里都有什么",两者是分开生效的。

判断权限时到底看哪一组? 系统的判断顺序是这样的:

用户访问文件     │     ▼是不是 owner(属主)?   │          │  是          否   │          ▼按属主权限   是不是 group(属组)成员?              │           │             是           否              │           │          按属组权限    按其他人权限

注意:只要你是文件的属主,系统就按属主权限判断,不会再往下看你是不是属组成员——哪怕属主权限比属组权限还严格,也是这样。


第二部分:光看这四张表还不够——实际运维会用到的内容

五、命令要对应到操作:useradd / passwd / groupadd / usermod

前面讲的四个文件,都是靠这几个命令去增删改的:

useradd -m alice        # 创建用户,-m 表示同时创建家目录passwd alice             # 给用户设置密码groupadd eda              # 创建一个组usermod -aG eda alice     # 把 alice 加入 eda 附加组id alice                  # 查看用户的 UID/GID/所在组groups alice               # 查看用户所在的所有组

这里有一个运维中非常容易踩坑的地方,一定要区分清楚:

usermod -G eda alice      # 危险!会覆盖 alice 原有的所有附加组,只保留 edausermod -aG eda alice     # 安全,在原有附加组基础上追加 eda

-G 不加 -a 会把用户原来所在的其它附加组全部清空,只留下新指定的这个组——这在生产环境里是个经典的"手滑事故",一定要养成习惯:加组永远用 -aG


六、chmod / chown / chgrp:怎么改权限和归属

chmod 755 test.sh        # 用数字方式一次性设置权限chmod u+x test.sh         # 只给属主加执行权限chmod g-w test.sh         # 去掉属组的写权限chown alice test.txt       # 改属主chown alice:eda test.txt   # 同时改属主和属组chgrp eda test.txt          # 只改属组

数字方式(如 755)和符号方式(如 u+x)各有用处:数字方式适合"一次性覆盖设置",符号方式适合"只微调某一部分权限"。


七、umask:为什么新建文件默认就是 644,目录默认是 755

这是很多入门内容会漏掉、但非常基础的一环。执行:

umask

常见输出是 0022。它决定了新建文件和目录时默认会"减掉"哪些权限

逻辑是这样的:

  • 普通文件的理论最高权限666(Linux 出于安全考虑,新建文件默认不给可执行权限,即使 umask 是 0 也一样)

  • 目录的理论最高权限777

然后用 umask 的值去"扣掉"对应的权限位:

文件: 666umask:022------------结果: 644目录: 777umask:022------------结果: 755

这就是为什么大多数系统里 touch 出来的文件默认是 644mkdir 出来的目录默认是 755

umask 的值也会影响协作场景。比如共享目录场景下:

  • umask 002:属组默认有写权限,适合一个组里的人需要互相修改彼此新建的文件(比如共享工程目录)

  • umask 027:属组只有读权限、其他人完全没权限,更保守,适合对权限要求更严格的环境


八、SUID / SGID / Sticky Bit:三个特殊权限位

除了 r/w/x,Linux 还有三个"特殊权限",ls -l 里会体现在权限位的特殊符号上。

SUID(属主位上出现 s

-rwsr-xr-x

设置方式:

chmod u+s file

作用:程序运行时,会以文件属主的身份权限去执行,而不是运行它的那个用户的权限。最经典的例子就是 passwd 命令本身:

ls -l /usr/bin/passwd

普通用户执行 passwd 修改自己的密码,本质是在改 /etc/shadow,而这个文件普通用户是没有写权限的——之所以能改成功,就是因为 passwd 命令带了 SUID,执行时临时"借用"了 root 的权限。

SGID(属组位上出现 s

对文件:chmod g+s file,作用和 SUID 类似,但借用的是属组的权限。

目录chmod g+s project/ 更常用,作用是——这个目录里新建的文件/子目录,会自动继承目录本身的属组,而不是继承创建者当前的主组。这在团队共享目录里特别实用:

mkdir /eda/projectchgrp eda /eda/projectchmod 2775 /eda/project     # 2 就是 SGID 位

设置好之后,团队里任何人在这个目录下新建文件,属组都会自动是 eda,不需要每次手动 chgrp

Sticky Bit(其他人位上出现 t

ls -ld /tmpdrwxrwxrwt

典型场景就是 /tmp 这种所有人都能写的公共目录。加了 Sticky Bit 之后,即使某个用户对目录有写权限,也只能删除自己创建的文件,不能删除别人的文件,避免了公共目录被人乱删东西。


九、当传统权限不够用:ACL

owner / group / other 这套三层权限模型,遇到"一份文件要给不同的人分配不同权限"时就不够用了。比如:

张三需要读写,李四只能只读,同组的其他人完全不能写。

这种诉求靠传统的 rwx 是表达不出来的,这时候就要用 ACL(访问控制列表)

setfacl -m u:zhangsan:rw project    # 给张三单独设置读写权限setfacl -m u:lisi:r project          # 给李四单独设置只读权限setfacl -m g:eda:rwx project          # 给 eda 组设置读写执行getfacl project                       # 查看当前的 ACL 设置

用了 ACL 之后,getfacl 的输出里会多一行 mask,很多人第一次看到会困惑:

group::rwxmask::r-x

明明 group 显示的是 rwx,为什么实际生效的却像是 r-x?这是因为 mask 定义了 ACL 生效的权限上限——最终生效的权限,是 ACL 具体条目和 mask 取交集的结果。所以用了 ACL 之后,改权限不能只看某一行,还要留意 mask 有没有把它"限制"住了。


十、往深一层想:Linux 内核认的其实不是"用户名"

前面一直在说"用户""组",但有一点值得点破:

用户名(alice)   ↓UID(1001)   ↓GID(1001) + 附加组(2000, 3000...)

Linux 内核层面真正识别的是数字 UID/GID,不是字符串"用户名"。 用户名只是给人看的一层"翻译"。执行:

id alice

会看到类似:

uid=1001(alice) gid=1001(alice) groups=1001(alice),2000(eda),3000(dv)

这个概念在跨主机场景(比如 NFS 共享目录)里特别重要——如果两台机器上同一个 UID 对应的用户名不一样,文件权限判断依然是按 UID 数字来的,很容易出现"看起来是别人的文件,其实 UID 是我"这种情况。

那这层"翻译"是怎么完成的呢?靠的是 NSS(Name Service Switch)。系统怎么把 alice 翻译成 UID、去哪里查这个映射关系,是由 /etc/nsswitch.conf 决定的:

passwd: files sssgroup:  files sssshadow: files

也就是说,执行 id alice 时,系统会按配置的顺序去查:先查本地的 /etc/passwdfiles),如果配置了 sss,还会去问 SSSD 服务,SSSD 背后可能连着 LDAP 或者 AD 域——这也是企业环境里"域账号"能直接在 Linux 上登录的原理。也就是说,一个用户信息不一定只存在于本机的 /etc/passwd 里,入门时了解这一点,遇到"明明加了用户,怎么查不到"这类问题时会更容易排查方向。


十一、身份查询和身份认证是两回事:NSS vs PAM

很容易把这两件事搞混,简单区分一下:

  • NSS 解决的问题是:"这个用户是谁?UID/GID 是多少?属于哪些组?"——纯粹是查信息。

  • PAM(可插拔认证模块)解决的问题是:"这个用户的身份认证能不能通过?"——涉及密码校验、登录策略等。

以 SSH 登录为例,大致流程是:

ssh 客户端   │   ▼sshd   │   ▼PAM(依次经过 auth → account → password → session 几个阶段)   │   ├── 可能连接 SSSD   ├── SSSD 再连接 LDAP / AD / Kerberos   ▼认证通过,允许登录

理解了这一层,就能明白为什么有的环境改了密码策略是改 PAM 配置,而查用户信息又是另一套 NSS 的逻辑——这是两个独立的子系统,配合起来完成"登录"这件事。


十二、sudo:不是"变成 root",而是"按策略执行指定命令"

很多人对 sudo 的理解停留在"让普通用户临时变成 root",但更准确的理解是:sudo 是按照预先定义好的策略,允许某个用户以指定身份执行指定的命令,不一定是变成 root,也不一定能执行所有命令。

策略配置在 /etc/sudoers(推荐用 visudo 编辑,避免语法错误导致文件报废)以及 /etc/sudoers.d/ 目录下的独立文件里,比如:

alice ALL=(root) /usr/bin/systemctl restart xxx

这一行的意思是:alice 只被允许以 root 身份执行这一条特定命令,而不是拥有 root 的全部权限。

常见用法:

sudo -l                       # 查看自己被允许执行哪些 sudo 命令sudo -i                        # 切换为 root 的登录 shell 环境sudo -u oracle command          # 以 oracle 用户身份(而不是 root)执行命令

最后提一句:生产环境里通常不建议这样配置:

alice ALL=(ALL) NOPASSWD: ALL

这等于完全放开了权限限制,也不需要输密码验证,一旦账号被盗用风险很大。合理的做法是按最小权限原则,只开放必要的命令。


最后,把整条逻辑串起来

  1. /etc/passwd:系统里有哪些用户,UID、主组、家目录、能不能登录。

  2. /etc/shadow:密码哈希、有效期怎么管。

  3. /etc/group:用户怎么分组,方便批量授权。

  4. 文件权限(rwx):具体到某个文件,属主/属组/其他人分别能做什么。

  5. umask / SUID / SGID / Sticky Bit:权限是怎么"默认生成"的,以及几个特殊场景下的权限位。

  6. ACL:当传统三层权限不够精细时的补充方案。

  7. UID/GID + NSS:Linux 内核真正认的是数字,用户名只是"翻译层",这层翻译可能来自本地文件,也可能来自 LDAP/AD。

  8. PAM + sudo:身份查询之外,"认证"和"提权"分别是怎么一回事。


相关推荐:

网友留言:

您需要 登录账户 后才能发表评论

我要评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
验证码