Linux 用户、组与权限:chmod、chown、sudo、umask 一文搞懂
运维学习路线系列 · 阶段一 Linux 地基 · 第 3 篇
适用环境:Ubuntu 24.04 LTS,普通用户(有 sudo)
阅读前提:《S1-01》《S1-02》
前言:Permission denied 到底怪谁
新人排错三大错觉之一:“我明明是 root 怎么还 Permission denied?”
场景:nginx 起不来,日志报 Permission denied。你 sudo 都试了还是不行——因为 nginx 的 worker 进程是 www-data 用户跑的,它读不了你放在 /root/ 下的网站文件。你有没有权限 ≠ 程序有没有权限。
这篇把"谁能做什么"这套体系一次理顺:先看懂 rw-r--r--,再学会发权限(chmod/chown),最后用 sudo 收权、用 umask 控默认。权限是 Linux 安全的地基,也是阶段二 SSH 加固的前置课。
一、用户与组:身份的两层结构
whoami # 我是谁
id # uid、gid、所属组全览(排权限问题第一步)
cat /etc/passwd # 所有用户(一行一个:name:x:uid:gid:home:shell)
cat /etc/group # 所有组
cat /etc/shadow # 密码哈希(仅 root 可读)
- UID 0 = root;普通用户从 1000 起;1~999 是系统账号(
www-data、mysql这类"不能登录、只用来跑服务"的用户)。 - 一个用户必须有一个主组(gid),可以加入多个附加组(比如
sudo组、docker组)。
# 用户管理四板斧(Ubuntu 推荐 adduser,交互式更安全)
sudo adduser deploy # 建用户(自动建同名主组、家目录)
sudo usermod -aG sudo deploy # 加入 sudo 组(-aG:追加,千万别忘 -a!)
sudo usermod -aG docker deploy # 免 sudo 用 docker(能摸 docker.sock = 近 root,慎给)
sudo deluser deploy # 删用户(家目录另删)
getent group sudo # 查 sudo 组里都有谁
🚨 usermod -G docker deploy(漏了 -a)会把 deploy 的附加组整个替换成 docker——sudo 权限瞬间没了一半,人还在机器前却干不了活。这个坑每年都有人踩。
二、读懂 rwx:那串字母的完整规则
-rw-r--r-- 1 root root 1070 nginx.conf
├─类型 ├─属主u ├─属组g └─其他o
每三位的含义(对文件和目录不一样,这是最大的理解陷阱):
| 权限 | 对文件 | 对目录 |
|---|---|---|
| r | 读内容 | 能 ls 列出文件名 |
| w | 改内容 | 能新建/删除里面的文件 |
| x | 可执行 | 能 cd 进入、能访问里面文件 |
💡 关键领悟:删除文件改的是"目录",不是文件本身。所以"我能删 /tmp 里 root 建的文件"(/tmp 有 Sticky 位但你自己建的你能删)这类"怪事",根源都在目录的 w。
数字表示(r=4, w=2, x=1,相加):
| 数字 | 字母 | 典型用途 |
|---|---|---|
| 7 | rwx | 属主全权 |
| 6 | rw- | 普通文件 |
| 5 | r-x | 目录、可执行程序 |
| 4 | r– | 只读配置、证书 |
常用组合:644(文件默认)、755(目录/脚本默认)、600(密钥文件,如 ~/.ssh/id_rsa)、700(~/.ssh 目录)。
三、chmod:改权限
chmod 644 app.conf # 数字法(推荐,一眼明确终态)
chmod u+x deploy.sh # 符号法:给属主加执行
chmod g-w,o-r app.conf # 组去掉写,其他人去掉读
chmod -R 755 /data/app # 递归(🚨 大目录慎用,先想清楚)
chmod a=rwx 不可取时想想下面……
🚨 两个高频错误:
chmod -R 777是"以毒攻毒":它没解决"哪个用户该访问"的问题,只是把门全拆了。生产出现 777 基本等于安全告警。- 目录递归不能一刀切:网站常见需求是"目录 755、文件 644",正确写法:
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
四、chown:换主人
sudo chown www-data:www-data /var/www/html -R # 属主:属组 递归
sudo chown deploy file.txt # 只改属主
sudo chown :deploy file.txt # 只改属组(也可 chgrp)
💡 权限排错第一反应:程序报 Permission denied 时,问三个问题——① 进程以哪个用户跑(
ps -ef | grep nginx);② 文件/目录每一层的属主与权限(namei -l /var/www/html/index.html,这个命令能打印路径上每一层的权限);③ 有没有 SELinux/AppArmor 这类额外管控(Ubuntu 24.04 默认 AppArmor)。90% 的 denied 十分钟内定位。
namei -l 是本篇最值钱的命令,路径上任何一层目录没有 x,你就进不去里面的文件——"文件权限明明对却访问不了"的元凶。
五、特殊权限:SUID、SGID、Sticky
ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root ... /usr/bin/passwd
↑ s 就是 SUID
| 特殊位 | 显示 | 作用 | 典型例子 |
|---|---|---|---|
| SUID | 属主位变 s | 执行者临时获得文件属主身份 | passwd(普通用户能改 /etc/shadow) |
| SGID | 属组位变 s | 目录下新文件自动继承目录的组 | 团队共享目录 |
| Sticky | 其他位变 t | 目录里每人只能删自己的文件 | /tmp(drwxrwxrwt) |
chmod u+s program # 设 SUID(数字 4000)
chmod g+s /data/share # 设 SGID(数字 2000)
chmod +t /data/share # 设 Sticky(数字 1000)
🚨 审计视角:find / -perm -4000 -type f 2>/dev/null 找出全盘 SUID 文件——黑客拿到权限后最爱埋 SUID 后门,这条命令是基线检查必跑项(阶段二加固篇还会见)。
六、sudo:不是"变成 root",是"被授权做某事"
sudo -l # 我被授权了哪些命令(先跑这个再说别的)
sudo -i # 完整 root shell(环境变量也切过去)
sudo -u www-data ls /var/www # 以指定用户执行——排查"程序视角"权限的神器
visudo # 🚨 永远用 visudo 改 sudoers,别直接 vi(有语法检查防锁死)
精细授权示例(运维账号只许执行备份相关命令):
# /etc/sudoers.d/backup-admin(visudo -f 编辑)
backupadmin ALL=(root) NOPASSWD: /usr/local/bin/db-backup.sh, /usr/bin/tar
- 格式:
谁 在哪台机器=(以谁的身份) 是否要密码: 命令列表 - 用
/etc/sudoers.d/下单文件管理,别都堆进主 sudoers; NOPASSWD只给脚本化需要的命令,不要全量 NOPASSWD。
七、umask:新文件的"出厂权限"
为什么新建文件是 644、目录是 755?因为默认权限减去 umask:
文件:666 - umask(022) = 644
目录:777 - umask(022) = 755
umask # 查看当前值
umask 027 # 临时改(文件 640 / 目录 750,更严格的团队默认)
生产上常见需求:应用目录只允许同组读,就把 umask 写进 systemd 服务或用户 ~/.bashrc。
八、综合实战:给部署账号"恰好够用"的权限
需求:新建 deploy 账号,能部署 /data/app、能重启 nginx,但不能自由切 root。
# ① 建号(不进 sudo 组)
sudo adduser deploy
# ② 应用目录交给 deploy
sudo mkdir -p /data/app && sudo chown deploy:deploy /data/app
# ③ 精细 sudo:只允许 systemctl 控制 nginx
echo "deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx" \
| sudo tee /etc/sudoers.d/deploy
sudo chmod 440 /etc/sudoers.d/deploy # sudoers.d 文件必须 440
sudo visudo -c # 语法校验
# ④ 验证:deploy 能 reload nginx,但 sudo -i 被拒
sudo -u deploy sudo -l
验收标准:能独立完成上面四步,并能解释为什么 /etc/sudoers.d/ 的文件权限必须是 440、usermod -aG 漏 -a 的后果是什么。
九、🚨 避坑清单
| # | 坑 | 后果 | 正确姿势 |
|---|---|---|---|
| 1 | chmod -R 777 治 Permission denied | 安全裸奔 | 查属主链路(namei -l)→ chown 到位 → 最小权限 |
| 2 | usermod -G 忘加 -a | 附加组被清空,权限丢失 | 永远 usermod -aG |
| 3 | 目录递归一刀切 755 | 文件也有了执行位 | find 分 -type d / -type f 处理 |
| 4 | 直接 vi /etc/sudoers | 语法写错 = 全员(含 root)sudo 失效 | 只用 visudo 与 sudoers.d |
| 5 | 加 docker 组不眨眼 | docker 组 ≈ 免密 root | 仅给需要的人,或用 rootless |
| 6 | 密钥文件权限 644 | ssh 直接拒绝使用该密钥 | ~/.ssh 700、私钥 600 |
| 7 | 忽略目录 x 权限 | 文件权限对了还是进不去 | 用 namei -l 看全链路 |
| 8 | 全量 NOPASSWD / sudo 组随手加 | 审计时说不清谁干了什么 | 精细授权 + sudo 日志在 /var/log/auth.log |
十、一句话总结
排权限问题先问"进程是谁"(ps),再看"路径每一层"(namei -l),最后才轮到 chmod——权限的正确姿势是"把文件交给对的人",而不是"把门拆了"。
💬 互动
你见过最离谱的 chmod -R 777 是在什么场景?以及有没有被 usermod -G 坑过?评论区见。
下一篇预告:《S1-04 Vim 从入门到够用:生存必备的 20 个操作》——服务器上没有图形界面,改配置全靠它,"怎么退出 Vim"这个梗我们先终结掉。
本文系统讲解Linux用户与组体系、rwx权限规则、chmod/chown命令用法、sudo精细化授权机制、umask默认权限控制,以及SUID/SGID/Sticky等特殊权限。重点强调权限排错逻辑:先确认进程运行用户,再逐层检查路径权限(namei -l),避免盲目使用777。内容覆盖生产环境部署账号权限设计、安全基线审计(如find / -perm -4000)及常见避坑实践。

248

被折叠的 条评论
为什么被折叠?



