用户与权限 — CodeRoadMap用户与权限
这一课你将能做到
- 读懂
ls -l 输出中的权限字符串(如 drwxr-xr-x),并能口述出文件谁能读、谁能写、谁能执行
- 使用
chmod 的符号模式和数字模式修改权限,使用 chown 修改文件所有者
- 理解
sudo 的工作原理,能在最小权限原则下完成日常运维操作(如修改 Nginx 配置、查看系统日志)
为什么要学
Linux 是多用户系统,权限是其安全的核心防线。本站后端(Spring Boot + MySQL + Redis + Nginx)跑在 Linux 上,如果任何人都能读数据库密码文件、写 Nginx 配置、杀掉进程,那系统随时会崩溃或被入侵。实际工作中,「应用无法写入日志」「Nginx 启动报 Permission denied」「上传的文件访问不了」这类问题,80% 都是权限问题。
面试中,「给一个文件加可执行权限」「777 和 755 的区别」「sudo 和 su 的区别」是高频送分题,但也是高频丢分题。
先建立图像
ls -l 输出的权限拆解:
-rwxr-xr-x 1 ubuntu ubuntu 1234 Oct 7 10:00 start.sh
││││││││││
││││││││└┴ 其他用户权限(o = others)
││││││└┴── 所属组权限(g = group)
│││└┴───── 所有者权限(u = user)
│└──────── 文件类型(- 普通文件,d 目录,l 软链接)
r = read(读) 权重 4
w = write(写) 权重 2
x = execute(执行)权重 1
rwx = 4+2+1 = 7
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
跟着做
步骤 1:读懂当前权限
cd ~
touch start.sh
echo '#!/bin/bash' > start.sh
echo 'echo "Hello, CodeForge!"' >> start.sh
ls -l start.sh
# 输出:-rw-r--r-- 1 ubuntu ubuntu 30 Oct 7 10:00 start.sh
解读:
-:普通文件
rw-:所有者(ubuntu)可读可写,不可执行
r--:所属组可读,不可写不可执行
r--:其他用户可读,不可写不可执行
步骤 2:修改权限——数字模式(面试必会)
chmod 755 start.sh # rwxr-xr-x:所有者可读可写可执行,其他人可读可执行
ls -l start.sh
chmod 644 start.sh # rw-r--r--:所有者可读可写,其他人只读(配置文件常用)
ls -l start.sh
chmod 700 start.sh # rwx------:只有所有者能操作(密钥文件常用)
ls -l start.sh
常用数字组合速查:
755:目录、可执行脚本的标准权限
644:普通文件(如配置文件、HTML、日志)的标准权限
700:SSH 私钥、数据库密码文件等敏感文件
777:极度危险,任何人都能读写执行,生产环境禁止使用
步骤 3:修改权限——符号模式(更灵活)
chmod u+x start.sh # 给所有者加执行权限
chmod g-w start.sh # 去掉组的写权限
chmod o=r start.sh # 设置其他用户只有读权限
chmod a+x start.sh # 给所有人加执行权限(a = all = u+g+o)
符号模式适合局部调整,不需要知道原来的权限是什么。
步骤 4:修改所有者和所属组
sudo chown root start.sh # 把文件所有者改为 root
sudo chown ubuntu:ubuntu start.sh # 同时改所有者和所属组
sudo chown -R ubuntu:ubuntu /var/www/html # -R 递归修改目录下所有文件
生产场景:Spring Boot 应用以 app 用户运行,日志目录需要把所有权给 app:
sudo useradd -r -s /bin/false app # 创建系统用户
sudo mkdir -p /var/log/myapp
sudo chown -R app:app /var/log/myapp
步骤 5:理解 sudo——以管理员身份执行
whoami # ubuntu(普通用户)
sudo whoami # root(临时提升权限)
sudo -l # 查看当前用户被允许执行哪些 sudo 命令
sudo 的原理:不是切换用户,而是以 root 权限执行单条命令,同时留下审计日志(在 /var/log/auth.log 里)。
步骤 6:理解特殊权限位(面试加分项)
chmod u+s /usr/bin/some-binary # SUID:以文件所有者权限运行(如 passwd)
chmod g+s /shared-dir # SGID:目录内新文件继承目录所属组
chmod +t /tmp # Sticky Bit:目录内文件只能由所有者删除
查看 /tmp 目录的权限:ls -ld /tmp,你会看到 drwxrwxrwt,最后的 t 就是 Sticky Bit。
步骤 7:umask——新建文件的默认权限
umask # 默认输出 0002(普通用户)或 0022(某些系统)
文件默认最大权限是 666,目录是 777,减去 umask 得到实际权限:
- 普通用户 umask
0002 → 文件 664(rw-rw-r--),目录 775(rwxrwxr-x)
- 设置 umask:
umask 0077 会让新建文件只有所有者能访问
步骤 8:ACL——更细粒度的权限控制
sudo apt install acl -y
setfacl -m u:redis:r-x /var/log/myapp/ # 给 redis 用户单独加读和执行权限
getfacl /var/log/myapp/ # 查看 ACL
当传统 user/group/other 三组权限不够用时(比如想让某个特定服务用户读取日志但不属于日志组),ACL 是标准解法。
讲清楚要点
- Linux 权限的三层结构:所有者(user)、所属组(group)、其他人(other)。每个文件有且只有一个所有者和一个所属组。
- 数字模式是面试硬通货:
r=4, w=2, x=1,三位数字分别对应 u/g/o。看到 755 要瞬间反应出 rwxr-xr-x。
- 目录的
x 权限意味着「进入」:没有 x,即使有 r,也 cd 不进去,更没法 ls 里面的内容。目录的标准权限是 755 而非 644。
sudo 不是 su:su 是 switch user(完全切换身份,需要 root 密码);sudo 是以 root 权限执行单条命令(需要当前用户密码,且需在 sudoers 列表中)。
- 最小权限原则:只给完成任务所需的最小权限。配置文件用
644,密钥用 600,日志目录用 755,绝不用 777 偷懒。
- SUID/SGID/Sticky 是高级安全机制:SUID 让普通用户临时以文件所有者权限运行(如修改密码的
passwd 命令);Sticky Bit 保护公共目录(如 /tmp)里的文件不被他人删除。
- 权限检查的顺序:内核先检查你是不是所有者,再检查组,最后检查 other。一旦匹配就停止,不会叠加。
你可能会懵的地方
-
为什么我给文件加了 r,还是读不了?
可能是上级目录没有 x 权限,你根本进不去那个目录。权限检查是沿路径逐层进行的。
-
为什么脚本加了 x 还是执行不了?
如果脚本第一行没有 shebang(#!/bin/bash),系统不知道用哪个解释器执行。或者脚本在 Windows 下编辑过,换行符是 \r\n 而非 \n。解决:dos2unix script.sh。
-
chmod 777 到底有什么问题?
任何人(包括被入侵的 Web 服务、恶意脚本)都能修改你的文件。一旦 Nginx 配置或 SSH 密钥被篡改,系统就沦陷了。生产环境用 777 是红线。
-
sudo 为什么不用输入 root 密码?
因为 /etc/sudoers 里配置了当前用户可以使用 sudo,验证的是用户自己的密码(或免密配置)。这是安全设计,不是漏洞。
-
组是什么?什么时候用?
组是一组用户的集合,方便批量授权。例如 www-data 组包含 Nginx 工作进程用户,把静态资源目录设为 www-data 组,Nginx 就能读取。
错法对照
| 错法 | 问题 | 正解 |
|---|
chmod 777 /opt/app 解决一切权限问题 | 极度危险,任何用户都能篡改 | 分析需要的最小权限:chmod 755 目录,chmod 644 文件 |
chmod +x script.py 后发现执行乱码 | 没有 shebang,系统按 shell 解析 Python | 文件第一行加 #!/usr/bin/env python3 |
chown user:group file 时没加 sudo | 普通用户不能把所有权转给别人 | sudo chown user:group file |
目录权限设成 644(去掉 x) | 用户无法进入目录 | 目录保持 755,文件 644 |
sudo su 后一直在 root 下操作 | 容易误操作,且操作无审计 | 用 sudo 执行单条命令,需要 root 环境时用 sudo -i |
| 忽略上级目录权限 | 文件有 rwx,但父目录没 x | 确保路径上每一级目录都有 x 权限 |
卡点急救
-
现象:Permission denied 修改系统配置文件
普通用户无权修改 /etc 下的文件。解决:命令前加 sudo;或者用 sudo nano /etc/nginx/nginx.conf 直接以 root 权限编辑。
-
现象:应用(如 Spring Boot)启动后写不了日志文件
应用运行用户(如 app)对日志目录没有写权限。解决:sudo chown -R app:app /var/log/myapp 或 chmod 755 /var/log/myapp。
-
现象:sudo: command not found 或 user is not in the sudoers file
当前用户不在 sudo 授权列表里。解决:用 root 登录执行 usermod -aG sudo username,然后重新登录使权限生效。
面试常问
-
chmod 755 和 chmod 644 分别代表什么?什么时候用?
755 = rwxr-xr-x,用于目录和可执行脚本,所有者全能,其他人能进入/读取/执行;644 = rw-r--r--,用于普通文件,所有者读写,其他人只读。配置文件、静态资源用 644,程序入口用 755。
-
sudo 和 su 的区别?
sudo 以 root 权限执行单条命令,需要当前用户在 sudoers 中,留下审计日志;su 是完全切换到 root 用户(需要 root 密码),退出前所有操作都是 root 身份。日常运维推荐 sudo,减少 root 暴露面。
-
为什么删除文件需要对父目录有写权限,而不是对文件本身?
删除文件的本质是修改父目录的内容(删除该目录项),所以需要对父目录有 w 和 x 权限。这与直觉相反,但符合 Linux「一切皆文件」的设计哲学。
自测三问
- 如何用数字模式给一个脚本设置「所有者可读可写可执行,组可读可执行,其他人可读」的权限?
- 你创建了一个目录
/data/app,Spring Boot 以 app 用户运行但写不进去日志,如何排查和修复?
sudo 执行的命令日志记录在哪里?如何查看某个用户最近用了哪些 sudo 命令?
小结一句话
Linux 权限是三道门(u/g/o)配三把锁(r/w/x),最小权限是原则,chmod 777 是红线——读懂 ls -l 的每一列,服务器安全就守住了大半。
延伸