Linux 权限不再靠背:chmod、chown、umask 一次算明白

Linux 权限不再靠背:chmod、chown、umask 一次算明白

Linux 权限chmodchownumask文件系统
📶 入门 🧩 Ubuntu · chmod · chown · umask

新手在服务器上最常见的三类报错——网页 403、脚本 Permission denied、SSH 密钥被拒——排查到最后十有八九落在同一个东西上:权限位。多数教程只会让你背「目录 755、文件 644、密钥 600」,背完还是不知道为什么。这篇把 rwx 的真实语义、数字的来历、umask 怎么决定新文件权限讲透,再补上误操作后的修复命令。做完这一次,以后不用再背。

先把 ls -l 第一列读对

ls -l /var/www
drwxr-xr-x 3 www-data www-data 4096 Oct 17 09:30 html
-rw-r--r-- 1 deploy   deploy    512 Oct 17 09:12 index.html

第一列共 10 个字符,含义拆开看:

位置示例含义
第 1 位d文件类型:d 目录,- 普通文件,l 软链接
第 2-4 位rwx属主(owner)权限
第 5-7 位r-x属组(group)权限
第 8-10 位r-x其他人(others)权限

r、w、x 对文件和对目录是两套语义,口诀背不通的根源在这里:

权限对文件对目录
r (4)读文件内容列出目录里的文件名(ls)
w (2)修改文件内容在目录里新建、重命名、删除文件
x (1)执行该文件进入该目录(cd)、访问其中的文件

注意目录的 w:删除一个文件只需要对所在目录有 w,文件本身只读照样能被删。想保护文件,光锁文件没用,得锁目录。

目录的 x 位:被忽略的通行证

目录的 x 位是整条路径的通行证——路径上任何一级目录缺 x,后面的文件权限再宽松也访问不到。四个状态对比如下,以属主视角为例:

目录权限ls 列目录新建文件cd 进去读已知名字的文件
rwx (7)✓✓✓✓(还受文件自身权限限制)
r-x (5)✓✗✓✓
-wx (3)✗✓✓✓
--x (1)✗✗✓✓

排查「文件明明 644 却读不了」这类问题,用 namei -l 沿路径逐级查一遍,比逐层 ls -ld 快得多:

namei -l /var/www/html/index.html
f: /var/www/html/index.html
drwxr-xr-x root     root     /
drwxr-xr-x root     root     var
drwxr-xr-x root     root     www
drwxr-x--- root     www-data html
-rw-r--r-- deploy   deploy   index.html

输出里 html 这一级是 drwxr-x---,属组 www-data 有 x。如果 Nginx 以 www-data 运行就能进;换成其他用户运行,即便文件本身 644,也会收到 403。问题出在路径上的目录,与文件无关。

数字法 755/644:算术代替背诵

三位数字从左到右对应属主、属组、其他人,每位是三种权限的和:r=4、w=2、x=1。

数字权限典型用途
7rwx目录;可执行脚本(属主)
6rw-普通数据文件(属主)
5r-x目录或脚本(属组/其他人)
4r--纯只读文件
0---不给任何权限

于是「目录 755、文件 644」根本不用背:目录需要 x 才能进,所以是 7 和 5;普通文件不需要 x,所以是 6 和 4。反过来,chmod 755 index.html 给一个网页文件加上 x 位,属于典型误操作——多出来的 x 没有功能意义,还会让某些安全扫描工具报警。

查看某个文件当前权限的数字形式:

stat -c '%a %U:%G %n' /var/www/html/index.html
644 deploy:deploy /var/www/html/index.html

数字法一次设齐三位,适合恢复默认;只调整其中一位时,符号法更稳:chmod g+w file(给属组加写)、chmod o-rwx file(把其他人的权限全部拿掉)、chmod u=x file(属主只留执行)。= 会覆盖该角色的全部权限,漏写一个字母就是真丢权限,混合使用时留意。

umask:新文件权限出厂默认从哪来

新建文件的权限由 umask 决定。内核对普通文件的权限上限是 666、目录是 777,创建时减去 umask 位就是最终结果:

对象上限默认 umask实际结果
普通文件666022644
目录777022755

Ubuntu 24.04 默认 umask 是 022(配置在 /etc/login.defs 的 UMASK 项),所以新建文件天然 644、目录天然 755。验证方法:

umask
touch /tmp/umask-test && mkdir /tmp/umask-dir
stat -c '%a %n' /tmp/umask-test /tmp/umask-dir
0022
644 /tmp/umask-test
755 /tmp/umask-dir

想让某个用户创建的文件默认不给其他人读(比如放敏感数据),把 umask 027 写进该用户的 ~/.profile,重新登录生效。两点提醒:umask 只影响之后新建的文件,已有文件不动;目录上限 777 减 umask 后总保留 x,文件上限 666 里没有 x,这就是脚本新建后永远要手动 chmod +x 的原因。

chown:改归属比改权限更快

很多时候权限位没错,错的是归属。典型场景:用 root 把数据拷到新目录,目录归 root,业务用户写不进去。改一次归属,比重排一堆权限位省事:

sudo chown deploy:deploy /data/app
sudo chown -R www-data:www-data /var/www/html

冒号后是属组,-R 递归整棵目录树。两个容易踩的细节:

  1. chown 会清掉 setuid/setgid 位。对设置了特殊位的文件改归属后,记得核对。
  2. 普通用户不能把文件「送」给别人。chown 改成别人需要 root;用户之间传文件,先挪到共享目录再改组。

配套的 chgrp 只改属组,chown :www-data file 等价。

chmod -R 777 为什么是灾难,以及怎么修回去

sudo chmod -R 777 /某目录 是网上答案区的高频毒方:所有用户可写可执行,等价于对全系统开放篡改权,而且 x 位泼到每个普通文件上。更危险的是 chmod -R 作用到 ~——~/.ssh 和里面的密钥一旦变成 777,sshd 判定权限过宽,密钥登录直接被拒。加固基线见服务器安全加固,密钥文件该是什么权限见 SSH 密钥认证。

已经误操作的,按类型分别修回。目录和文件的目标权限不同,不能用同一条命令一锅端,用 find 分开处理:

sudo find /var/www/html -type d -exec chmod 755 {} +
sudo find /var/www/html -type f -exec chmod 644 {} +

~/.ssh 被误改的修复:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

改完用 ssh -v user@host 重连,日志里 Permissions 0777 for ... are too open 的报错消失即恢复。

特殊权限位:setuid、setgid、sticky

三位数字之外还有第四位,管三件特殊事,写法是四位数字的首位:

位数值作用现成例子
setuid4执行者临时获得文件属主身份/usr/bin/passwd(普通用户改密码要写 /etc/shadow)
setgid2目录下新建文件自动继承目录属组团队共享目录常用 2770
sticky1目录下的文件只有属主能删/tmp 是 1777
ls -l /usr/bin/passwd /tmp
-rwsr-xr-x 1 root root 59976 Nov 23  2023 /usr/bin/passwd
drwxrwxrwt 15 root root 40960 Oct 17 10:02 /tmp

属主位的 s 是 setuid,其他位的 t 是 sticky。共享目录一条命令配齐:

sudo mkdir -p /srv/shared
sudo chgrp deploy /srv/shared
sudo chmod 2770 /srv/shared

setgid 让组内新文件自动归 deploy 组,2770 又挡住组外的人。多用户协作目录照这个模板配即可。另外,chattr +i 能给文件加不可修改位,连 root 都改不了,适合锁定关键配置,lsattr 查看、chattr -i 解除。

常见问题(FAQ)

为什么文件是 644,Nginx 还是 403? 按 namei -l 沿路径查。九成是路径上某一层目录缺 x,或 Nginx 运行身份(www-data)不在目录的属组里。

chmod -R 777 之后再改回来,有没有安全残留? 权限位本身能修回,但暴露期间写入的文件、被篡改的内容无法靠 chmod 恢复。暴露窗口长的按入侵处理,查登录记录和异常文件。

umask 000 是什么意思? 新建文件直接拿满上限:文件 666、目录 777。等于把默认防线拆掉,服务器账号别这么配。

为什么我改了 umask,已有文件的权限没变? umask 只在文件被创建那一刻起作用。已有文件用 chmod 逐个或批量改。

chown 之后服务还是读不了文件? 先确认服务进程的真实运行用户(ps -o user= -p <pid>),再检查该用户对整条路径的 x。还读不了就看 ACL:getfacl file。

最小可行清单:只记 4 件事

  1. 目录 755、文件 644、私钥 600——数字由 r=4, w=2, x=1 加出来,推导优先于背诵。
  2. 排查 403 先跑 namei -l——问题多半在路径上某层目录,与目标文件无关。
  3. 拒绝一切 -R 777——批量修复用 find 分开处理目录(755)和文件(644)。
  4. 共享目录用 2770 + setgid——新文件自动继承属组,权限管理交给目录而不是每个文件。