当前位置:首页>Linux>Linux 文件权限、用户与 sudo:搞不清楚就别动生产

Linux 文件权限、用户与 sudo:搞不清楚就别动生产

  • 2026-10-11 05:39:02
Linux 文件权限、用户与 sudo:搞不清楚就别动生产

W2:Linux 文件权限

上一篇把 30 个核心命令过了一遍,这一篇钻进新人最容易翻车的一个点——文件权限。

实习生第一周改 Nginx 配置发现「Permission denied」一脸懵,二周看见同事 chmod -R 777 /var/www 学着用,三周给某个目录设错权限把网站搞挂。权限不懂就动生产,是早晚要还的债。

这一篇把 user/group/other、chmod、chown、sudo、特殊位、umask 一次梳理清楚。


一、ls -l 输出每一段都在说啥

$ ls -l /var/log/nginx/access.log-rw-r--r-- 1 nginx adm 12345 Jun 25 14:23 access.log│└─┬─┘└┬┘└┬┘│ └─┬─┘ └┬┘ └─┬─┘  └───┬───┘  └────┬────┘│ │   │  │ │   │    │    │       │           ││ │   │  │ │   │    │    │       │           └─ 文件名│ │   │  │ │   │    │    │       └─ 修改时间│ │   │  │ │   │    │    └─ 文件大小(字节)│ │   │  │ │   │    └─ 所属组│ │   │  │ │   └─ 属主│ │   │  │ └─ 硬链接数│ │   │  └─ other 权限│ │   └─ group 权限│ └─ user(属主)权限└─ 文件类型:- 普通文件 / d 目录 / l 软链接 / c 字符设备 / b 块设备 / s socket

记住三件事:

  1. 三段权限
    :rw- / r-- / r--,分别对应属主 / 属组 / 其他人
  2. 每段三位
    :分别是 r(读)/ w(写)/ x(执行),用 - 占位表示无此权限
  3. 第一个字符是类型
    ,不是权限

二、数字权限:把 rwx 当二进制看就秒懂

每一段 rwx 三位,每一位有 / 无对应 1/0,三位刚好是 0-7:

权限
二进制
八进制
---
000
0
--x
001
1
-w-
010
2
-wx
011
3
r--
100
4
r-x
101
5
rw-
110
6
rwx
111
7

三段拼起来就是三位数字。最常见的几个:

755 = rwxr-xr-x   # 目录默认 / 可执行脚本644 = rw-r--r--   # 普通文件默认600 = rw-------   # 私钥、证书、密码文件(**只属主可读写**)700 = rwx------   # 私人脚本目录777 = rwxrwxrwx   # 全开(**几乎永远不要这么设**)

文件和目录上的 x 含义完全不同

文件的 x:能不能执行(脚本 / 二进制)目录的 x:能不能进入这个目录(cd 进去 / 看里面的子文件)

这是新人最容易栽的一个坑:

bash
# 给一个目录 644,看似没问题chmod 644 mydircd mydir          # ❌ Permission deniedls mydir          # ✅ 能列出文件名cat mydir/file    # ❌ Permission denied(要 x 才能访问目录里的具体文件)

目录的 x 是「能不能用这个目录」的开关,没有 x 等于这个目录是个黑洞——能看到名字,进不去。


三、符号权限:增量修改用它最顺手

数字法是「整段重写」,符号法是「在原基础上加减」:

bash
chmod u+x script.sh        # 给属主加可执行chmod g-w file.txt         # 收回属组的写权限chmod o=r file.txt         # 把 other 权限设成只读(覆盖式)chmod a+r file.txt         # all(u+g+o)都加读权限chmod u+x,g-w,o-rwx file   # 多个一起改,逗号分隔chmod -R 755 mydir         # **-R 递归改子目录**

何时用数字、何时用符号:

  • 新建文件 / 一次性设全:用数字(chmod 755 script.sh)
  • 已有文件加 / 减某个位:用符号(chmod +x deploy.sh)

四、特殊权限位:setuid / setgid / sticky

除了 rwx,每段还有一个「特殊位」,分别叫 s、s、t,挂在 x 那一位上显示。

bash
ls -l $(which passwd)# -rwsr-xr-x 1 root root 68208 ... /usr/bin/passwd#    ↑#    属主 x 位变成 s,就是 setuid

setuid(4xxx):执行时临时变身属主

bash
chmod 4755 myprog# rwsr-xr-x

最经典例子是 /usr/bin/passwd:普通用户改自己密码要写 /etc/shadow,但 shadow 只有 root 能写。setuid 让 passwd 执行时短暂以 root 身份跑。

安全风险:自己写的脚本千万别 setuid,shell 脚本的 setuid 在多数现代 Linux 已经被内核屏蔽,硬要绕的话等于开后门。

setgid(2xxx):用在目录上,新建文件自动继承组

bash
chmod 2775 /shared# rwxrwsr-x# 任何用户在 /shared 下创建的文件,所属组都是 /shared 的组# 团队共享目录最常用

sticky(1xxx):用在目录上,只能删自己创建的文件

bash
ls -ld /tmp# drwxrwxrwt 17 root root 12288 ... /tmp#          ↑#          other 的 x 位变成 t# 1777 意味着:所有人可读写执行,但 **只能删自己创建的东西**

/tmp 是 1777 的经典代表。如果不加 sticky,任何用户都能删别人在 /tmp 里的文件,那就是灾难现场。

特殊位速查表:

权限
数字前缀
显示
适用场景
setuid
4
rwsr-xr-x
系统命令需临时提权(passwd)
setgid
2
rwxr-sr-x
共享目录文件自动继承组
sticky
1
rwxrwxrwt
共享可写目录防互删(/tmp)

五、umask:新建文件的默认权限怎么来的

新建文件默认是 644、新建目录默认是 755,这是怎么算的?

文件最大权限 666(不给 x)  -  umask  =  实际权限目录最大权限 777            -  umask  =  实际权限默认 umask = 022文件:666 - 022 = 644目录:777 - 022 = 755
bash
umask# 看当前 umask# 0022umask 027              # 改成更严格(属主全权、组只读、其他无权限)# 文件变 640、目录变 750

生产服务器推荐 027,避免 other 默认能读到敏感配置。改完写到 /etc/login.defs 或 /etc/profile 持久化。


六、用户与组:三张表的结构

Linux 用户信息存在三个文件里,新人必须看一遍每个字段什么意思:

/etc/passwd

$ cat /etc/passwd | head -2root:x:0:0:root:/root:/bin/bashnginx:x:101:101:nginx user,,,:/var/cache/nginx:/usr/sbin/nologin

冒号分隔的 7 段:

用户名 : 密码占位 : UID : GID : 描述 : 家目录 : 登录 shell

/usr/sbin/nologin 表示该用户不能 SSH 登录——所有系统服务账号都应该是 nologin。

/etc/shadow(密码哈希,root 只读)

$ sudo cat /etc/shadow | head -1root:$6$xyz...$abc...:19500:0:99999:7:::
用户名 : 加密密码 : 上次改密时间 : 最短间隔 : 最长有效期 : 提醒提前几天 : 失效宽限 : 账号失效日 : 保留

$6$ 开头是 SHA-512 哈希;! 或 * 表示账号被锁。

/etc/group

$ cat /etc/group | head -2root:x:0:sudo:x:27:user1,user2docker:x:998:user1
组名 : 密码占位 : GID : 组成员列表

把人加进 sudo 组就能 sudo、加进 docker 组就能不加 sudo 跑 docker(这也是安全风险,docker 组等于 root)。


七、用户管理:useradd / usermod / userdel

bash
# 新建用户(带家目录、默认 shell 是 bash)sudo useradd -m -s /bin/bash alicesudo passwd alice                       # 设密码# 加入额外组(**-a 不可省,不然会覆盖原有组**)sudo usermod -aG sudo,docker alice# 改 shellsudo usermod -s /usr/sbin/nologin servicebot# 锁定 / 解锁账号sudo usermod -L alice                   # 锁sudo usermod -U alice                   # 解# 删用户(**-r 才删家目录,不加只删账号**)sudo userdel -r alice

给新人开账号的完整序列(背下来):

bash
USER=newbiesudo useradd -m -s /bin/bash $USERsudo passwd $USER# 给临时初始密码sudo passwd -e $USER# 强制下次登录改密sudo usermod -aG sudo,docker $USER# 加入需要的组# 设 SSH 公钥sudo -u $USERmkdir -p /home/$USER/.sshsudo -u $USERchmod 700 /home/$USER/.sshsudotee /home/$USER/.ssh/authorized_keys <<< "ssh-ed25519 AAAAC3Nz... newbie@laptop"sudochown$USER:$USER /home/$USER/.ssh/authorized_keyssudochmod 600 /home/$USER/.ssh/authorized_keys

注意 .ssh 必须 700、authorized_keys 必须 600,权限错一位 SSH 直接拒绝公钥认证,且不报具体原因(只看 sshd 日志才看得到 Authentication refused: bad ownership or modes)。


八、sudo:永远用 visudo 改配置

sudo 让普通用户按需以 root(或其他用户)身份跑命令,是 Linux 安全的核心。

配置文件

/etc/sudoers              # 主配置/etc/sudoers.d/*          # 分文件配置(推荐自定义放这里)

永远不要直接 vim /etc/sudoers。一旦语法写错,整个 sudo 会瘫痪,连 root 都进不去(除非你保留了 root 直接登录)。

正确姿势:

bash
sudo visudo                           # 编辑主配置,保存时自动语法校验sudo visudo -f /etc/sudoers.d/devops  # 编辑分文件

visudo 在保存时会跑 visudo -c 校验,发现错误会问「Q 退出、E 重编、R 强存」,永远选 E 不要选 R。

常用 sudoers 写法

# 用户   主机=(目标用户:目标组)  允许的命令alice    ALL=(ALL:ALL) ALL                          # 全权alice    ALL=(ALL) NOPASSWD: ALL                    # 全权 + 免密(**慎用**)%sudo    ALL=(ALL:ALL) ALL                          # sudo 组所有成员全权# 限定命令(推荐生产用法)deploy   ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, \                              /usr/bin/systemctl reload nginx# 拒绝某些命令(黑名单)alice    ALL=(ALL) ALL, !/bin/su, !/usr/bin/passwd root

日常 sudo 技巧

bash
sudo -l                       # 看自己能跑哪些命令(强烈建议每个 sudoer 都会这条)sudo -u nginx ls /var/log     # 以 nginx 用户身份跑sudo -i                       # 切到 root 交互 shell(**会加载 root 环境**)sudo su -                     # 同上,但更老派sudo !!                       # 上一条命令前面加 sudo 重跑(神技)sudo -k                       # 立即作废 sudo 凭证缓存

sudo 默认会缓存 15 分钟,所以连续敲 sudo 不需要每次输密码。需要更严格的场景把 Defaults timestamp_timeout=0 加到 sudoers 强制每次都问。


九、chmod 777 /etc 翻车实录

某次实习生帮人调 PHP,遇到「目录权限不够」,他想都没想:

bash
sudochmod -R 777 /etc

5 分钟后:

  • SSH 登录开始报警告 bad ownership or modes
  • sudo 直接拒绝执行:/etc/sudoers is mode 0777, should be 0440
  • cron 不再执行任何任务
  • 下次重启起不来

为什么这么致命:

  1. /etc/sudoers
     必须 440,777 会被 sudo 直接拒绝读
  2. /etc/shadow
     必须 600,777 等于把密码哈希给所有人看
  3. /etc/ssh/sshd_config
     之类配置 777 后,sshd 拒绝启动
  4. cron 拒绝执行权限过宽的 crontab 文件

恢复路径只有:用救援盘 / live CD 进单用户模式,手动 chmod 把每个关键文件改回正确权限——一台机器恢复一两小时,几十台机器…就等着写复盘吧。

记住三条铁律:

  1. 永远不要 chmod 777
    ——99% 的「权限不够」其实是属主 / 属组不对,应该 chown 不是 chmod 777
  2. 永远不要 chmod -R 到 /etc、/usr、/var
     这种系统目录
  3. 改权限前先 getfacl 备份一下
    :getfacl -R /path > /tmp/perms.bak,万一翻车能 setfacl --restore

十、安全实践小结

进入一台新服务器,先把这几件事做了:

bash
# 1. 不要用 root 日常操作,建自己的账号sudo useradd -m -s /bin/bash $USER && sudo passwd $USERsudo usermod -aG sudo$USER# 2. SSH 禁 root 直接登录(编辑 /etc/ssh/sshd_config)PermitRootLogin noPasswordAuthentication no         # 禁密码,强制密钥(W15 详讲)sudo systemctl restart sshd# 3. sudo 配限定命令,不要无脑 NOPASSWD ALLsudo visudo -f /etc/sudoers.d/deploy# deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp# 4. 重要文件权限收紧sudochmod 600 /etc/ssh/ssh_host_*_keysudochmod 644 /etc/ssh/ssh_host_*_key.pub

写在最后

  • 数字权限就是二进制:rwx 三位拼成 0-7,背熟 644/755/600/700 四个常用值
  • chown 改属主、chmod 改权限
    ,新人最容易混淆的两个动词
  • 目录的 x 是「能不能进」,没有 x 等于黑洞
  • 改 sudoers 永远 sudo visudo
    ,直接编辑出错锁死全机
  • chmod -R 777 是问题创造机,不是问题解决方案
  • 设错 SSH 公钥权限(.ssh 必须 700、authorized_keys 必须 600)会让密钥认证默默失败,先检查权限再查公钥内容

最新文章

随机文章