原标题:用户与权限

系统需要判断:谁(用户)对什么(文件)能做什么(权限)。

用户、组、其他人(User / Group / Other)

Linux 是多用户系统,每个文件/目录都有三类“主体”与之关联:

  • User (u):文件的所有者(owner),通常是创建这个文件的用户
  • Group (g):文件所属的用户组,组内可以有多个用户
  • Other (o):既不是所有者、也不属于该组的其他所有用户

每个文件在内核里实际存的是 UID(用户ID)和 GID(组ID)两个数字,root、star 这些用户名只是 /etc/passwd 里的一层映射,方便人类阅读。

rwx 三个权限位的含义

对文件和目录,rwx 含义不同:

权限 对文件 对目录
r (read) 能读取文件内容 能列出目录里的文件名(ls)
w (write) 能修改文件内容 能在目录里创建/删除/重命名文件
x (execute) 能把文件当程序执行 能“进入”该目录,或访问目录下文件的属性(cd、stat)

这也是为什么目录经常需要 x 权限——没有 x,即使有 r,你也没法真正 cd 进去访问里面的文件内容,只能看到文件名列表。

为什么是 rwxr-xr-x 755vs777

ls -l 输出的10个字符结构是:

-rwxr-xr-x
类型 | 所有者 | 组 | 其他人
  • 第1位:文件类型(普通文件,d目录,l软链接……)
  • 2-4位:owner 的 rwx
  • 5-7位:group 的 rwx
  • 8-10位:other 的 rwx

rwxr-xr-x 翻成数字就是:

  • owner: rwx = 4+2+1 = 7
  • group: r-x = 4+0+1 = 5
  • other: r-x = 4+0+1 = 5

所以是 755,不是 777。

777 意味着“所有人(包括陌生用户)都能读写执行”,这在实际场景里几乎总是不合理、也不安全——尤其是可执行文件或脚本,任何本地用户都能篡改内容再等你/root 运行它,等于开门揖盗。

755(或普通文件常见的644)才是常规默认:所有者全权限,同组/其他人只读(+可执行文件的可执行权限),这是最小权限原则的体现。

chmod —— 改变权限

两种写法: 数字法(常用):

chmod 755 script.sh   # rwxr-xr-x
chmod 644 note.txt    # rw-r--r--
chmod -R 755 dir/     # 递归修改整个目录

符号法:chmod u+x file(给owner加执行权限),chmod go-w file(去掉组和其他人的写权限),chmod a+r file(所有人加读权限,a=all)

chown —— 改变归属

改变文件属于谁:

chown star file          # 改owner为star
chown star:devs file     # 同时改owner为star,group为devs
chown -R star:devs dir/  # 递归修改
chgrp devs file          # 只改组,等价于 chown :devs file

注意:普通用户不能把自己的文件 chown 给别人(防止用这招“甩锅”占用别人的磁盘配额),一般只有 root 能任意 chown。

sudo —— 以及它为什么能提权

sudo(superuser do)本身其实是一个setuid root 的可执行程序。关键就在这个 setuid 位:

ls -l /usr/bin/sudo
# -rwsr-xr-x ... root root ... /usr/bin/sudo

注意 owner 那一位是 s 而不是 x——这就是 setuid bit。它的效果是:无论谁来运行这个程序,运行时的有效身份(effective UID)都变成这个文件的所有者,也就是 root,而不是执行它的那个普通用户。

流程大致是:

  1. 你以普通用户身份执行 sudo apt update
  2. 内核发现 sudo 这个二进制文件带 setuid root 标记,于是把这个进程的 effective UID 设为 0(root)
  3. sudo 程序(此时已经是 root 权限在运行)检查 /etc/sudoers(或 /etc/sudoers.d/),看你的用户名/所在组是否被授权执行这条命令,通常还会要求你输入自己的密码验证身份
  4. 验证通过后,sudo 以 root 身份 fork/exec 出你要运行的实际命令(apt update)
  5. 命令执行完,普通用户进程本身并没有“变成”root,只是这一次调用被 root 代劳了

所以本质上:提权靠的是 setuid root 这个文件权限特性,sudo 只是在这个特权基础上加了一层“你有没有资格”的策略判断(sudoers 配置)和审计日志(谁在什么时候用sudo做了什么,通常记在 /var/log/auth.log 或 journalctl)。

这也是为什么 sudoers 文件的权限和内容要极其谨慎地维护——它是普通用户到 root 的唯一“官方闸门”。


几个容易踩的坑,供参考:

  • chmod 777 或对整棵目录树 chmod -R 777 是常见误操作,会让文件对所有本地用户可写可执行,生产环境基本不该这么做
  • 不要直接编辑 /etc/sudoers,用 visudo 命令,它会做语法检查,防止你把自己锁在门外
  • SUID 程序本身是一个攻击面,如果某个带 setuid root 的程序有漏洞(比如能被诱导执行任意命令),相当于给了本地提权的捷径,所以尽量不要随意给自定义脚本加 setuid(chmod u+s)