chmod 与 Linux 文件权限详解:755、644 和 rwx 到底是什么意思
2026-08-11
每个在 Linux 服务器上部署过东西的开发者都遇到过:运行脚本时 Permission denied、Web 服务器读不了自己的文件,或者好心人建议”直接 chmod 777 就行了”——症状是消失了,安全漏洞也打开了。文件权限是 Unix 最古老的设计之一,模型小到可以永久装进脑子里。这篇文章把这个模型讲透:三组字符分别管谁、755 为什么是这个意思,以及让多用户系统保持安全的几条规则。
每个文件都要回答的三个问题
Linux 判断访问权限时按顺序问三个问题:
- 你是文件的所有者吗? 是,则应用 user(所有者)权限。
- 你在文件的属组里吗? 是,则应用 group(属组)权限。
- 都不是,则应用 other(其他人)权限。
第一个命中的问题直接决定结果——三组权限不会叠加。如果你是所有者但所有者权限写着”不可读”,那么你即使在一个可读的属组里也没用。无数人在这里踩坑:把所有者权限撤掉却留着组权限,等于把所有者自己锁在门外。
用 ls -l 可以查看任何文件的所有者和属组:
-rwxr-xr-- 1 alice developers 4096 Aug 11 09:00 deploy.sh
这里 alice 是所有者,developers 是属组,开头的 -rwxr-xr-- 就是权限串。
读懂 rwxr-xr—:权限字符串
文件类型短横线之后的九个字符是三个三元组:所有者、属组、其他人。每个三元组依次是读(r)、写(w)、执行(x)——没有该权限的位置是短横线。所以 rwxr-xr-- 翻译过来是:
- 所有者:
rwx—— 可读、可写、可执行 - 属组:
r-x—— 可读可执行,不可写 - 其他人:
r--—— 只读
“执行”对不同文件类型含义不同。对普通文件,它是”可以作为程序运行”。对目录,x 是”可以进入并访问里面的文件”,r 是”可以列出里面的文件名”,w 是”可以在里面创建、删除、重命名条目”。这就是为什么一个能列出却进不去的目录行为那么诡异——r 而没有 x,只能看到名字,什么都碰不了。
八进制记法:为什么 755 等于 rwxr-xr-x
每个三元组是三个比特,恰好映射到一个八进制数字:读 = 4,写 = 2,执行 = 1,组内相加。rwx = 4+2+1 = 7,r-x = 4+1 = 5,r-- = 4 = 4。几个经典组合:
755(rwxr-xr-x)—— 所有者全权,其他人可读可执行。脚本、程序和目录的标准权限。644(rw-r--r--)—— 所有者可编辑,所有人可读。网页内容、配置、源码文件的标准权限。600(rw-------)—— 仅所有者。私钥、.env文件、凭据存储就该用它。700(rwx------)—— 仅所有者可执行。~/.ssh和私有脚本目录的归宿。
工作中想不起某个组合时,chmod 计算器可以在八进制和 rwx 字符串之间双向转换,并清楚展示每一方得到什么权限——比在心里数比特快得多。
符号模式:只改一处,不用重算全部
八进制模式一次设置全部九个比特。符号模式只调整你点名的部分,语法是”谁”(u/g/o/a)加操作符(+ 添加,- 移除,= 精确设定)加权限字母:
chmod u+x deploy.sh # 给所有者加执行权限
chmod go-w config.ini # 去掉属组和其他人的写权限
chmod o= secrets.txt # 移除其他人的所有权限
chmod -R u=rwX,go=rX site/ # 递归:文件 644,目录 755
最后一条用了条件性的 X(大写):只对目录和已有执行位的文件加执行权限。这是一遍修好整棵目录树的安全做法——目录变得可进入,普通文件保持不可执行。
为什么 777 几乎总是错的
chmod 777 把读、写、执行给了机器上的每一个账户。在共享服务器或容器宿主机上,任何一个被攻破的进程——有漏洞的 Web 应用、恶意的 cron 任务、其他租户——现在都能改你的文件。最经典的惨案是一个既可写又可执行的上传目录:攻击者上传脚本,攻击者运行脚本。
777 之所以诱人,是因为它能瞬间消除 Permission denied。但真正的问题几乎从来不是”所有人都需要所有权限”,而是以下几种之一:
- 所有者不对:Web 服务器以
www-data运行,文件却属于你的账号。用chown修,不是 chmod。 - 组策略不对:把协作的用户放进同一个组,用
664/775配合属组解决。 - 路径上游某个目录缺执行位——可能是
/home/alice本身挡住了穿越。
把 777 当诊断手段用(“报错消失了?那确实是权限问题”),永远不要当修复方案用。
特殊位:setuid、setgid 和粘滞位
八进制的第四位(前导位)还藏着三个特殊位:
- setuid(4):可执行文件运行时获得文件所有者的权限,而不是调用者的。
passwd(属主是 root)就是这样让普通用户修改自己密码的。不要随便给自己写的脚本设这个位。 - setgid(2):对可执行文件,运行时获得文件属组的身份;对目录,里面新建的文件继承目录的属组,而不是创建者的主属组。目录的这个行为是共享项目目录的基石——配合
2775,团队成员新建的文件天然保持组内可访问。 - 粘滞位(1):对目录,即使其他人有写权限,也只有文件所有者能删除或重命名自己的文件。
/tmp就是1777——人人可写,但只有创建者能删。
在 ls -l 里它们显示为替代执行位的 s、s 和 t(-rwsr-xr-x、drwxrwsr-x、drwxrwxrwt)。
服务器加固清单
- 网页内容:文件
644,目录755,属主是部署账号——Web 服务器只需要读。 - 上传目录:
755或更严,属主是 Web 用户,并配置noexec——可写但永远不可执行。 - 私钥和密钥文件:
600仅所有者;~/.ssh目录本身700。 - 团队共享目录:
2775配专用属组(setgid 位让新文件留在组内)。 - 脚本:别人也要运行就
755,只有你自己跑就700。 - 生产环境永远不要
777;心动的时候,去找真正的属主/属组问题。
执行前拿不准某个权限组合展开后是什么,先在 chmod 计算器里过一遍——五秒钟的检查好过一次线上递归事故。如果你调权限是为了保护凭据,记住权限只是第二道防线,强密码才是第一道——密码生成器在本地就能生成。