作者:小康,C/C++编程博主
关键词:chmod、chown、umask、ACL、文件权限、特殊权限位、setuid
你一定敲过这行命令:
chmod 777 some_file报权限错误了,加个 777 完事。快是快,但这可能是服务器被入侵的起点。
Linux 的文件权限系统看起来简单——不就是 rwx 三个字母吗?但藏在里面的细节,足够让很多工作多年的开发者在面试时哑口无言:
chmod 4755 里那个 4 是什么意思?x 权限和文件的 x 权限一回事吗?644,新建目录自动是 755?rwxrwxrwx 还不够用,怎么办?一篇文章,全部讲清楚。
ls -l 那一行,到底在说什么?$ ls -l /etc/passwd-rw-r--r-- 1 root root 2847 Mar 10 09:12 /etc/passwd第一列 -rw-r--r-- 共 10 个字符,每一位都有含义:

这里有一个很多人忽略的细节:目录的 x 权限和文件的 x 完全不同。
对目录来说,x 不是"能执行",而是能进入(cd)。一个目录哪怕你有 r 权限(能看到里面有哪些文件),但没有 x 权限,你进不去,也无法访问里面的任何文件。
这就是为什么目录的默认权限是 755 而不是 644——少了 x,目录就成了摆设。
chmod 755 怎么算出来的?权限还有另一种写法:数字。每个权限位对应一个数值:

chmod 755 的意思就是:
7 = rwx(读写执行)5 = r-x(读和执行)5 = r-x(读和执行)而 chmod 777 的意思是:任何人都可以读、写、执行——包括服务器上的所有其他用户和所有运行中的进程。这就是它危险的地方,下文细说。
# 符号方式(更直观,适合只改某一位)chmod u+x file # 给所有者加执行权限chmod g-w file # 去掉所属组的写权限chmod o=r file # 其他人只保留读权限chmod a+x script.sh # 所有人加执行权限(a = all)# 数字方式(适合设置完整权限)chmod 644 config.jsonchmod 755 /usr/local/bin/mytoolchmod 600 ~/.ssh/id_rsa # 私钥必须 600,否则 ssh 拒绝使用chmod 777 为什么危险?来看一个真实场景:
# 某开发者遇到权限问题,图省事chmod 777 /var/www/html/uploads/# 这意味着:# - 任意用户可以往里写文件# - Web 服务器进程(www-data)可以往里写任意文件# - 如果网站有文件上传漏洞,攻击者可以上传 PHP 木马# - 木马具有执行权限(x),可以直接运行# - 服务器被拿下正确做法:
# 只给 Web 服务器用户写权限,其他人不能写chown www-data:www-data /var/www/html/uploads/chmod 755 /var/www/html/uploads/# 或者如果只有 www-data 需要写:chmod 700 /var/www/html/uploads/最小权限原则:只给必要的权限,不多给一位。
chown:改文件归属权限控制依赖"谁拥有这个文件",改归属用 chown:
# 改所有者chown alice file.txt# 改所有者和所属组chown alice:developers file.txt# 只改所属组chown :developers file.txt# 或者用 chgrpchgrp developers file.txt# 递归修改目录及其下所有文件chown -R www-data:www-data /var/www/html/一个常见坑:用 sudo 创建的文件,所有者是 root,普通用户改不了。记得改完所有权:
sudo cp config.json /etc/myapp/sudo chown myapp:myapp /etc/myapp/config.jsonumask:新文件为什么自动是 644?你有没有想过:为什么 touch newfile 出来的文件自动是 644,mkdir newdir 出来的目录自动是 755?是谁决定的?
答案是 umask——一个"权限遮罩",从最大权限里减掉不需要的位。

umask 是进程继承的属性,每个 shell 和进程都有自己的 umask:
# 查看当前 umask$ umask0022# 改成更严格的(只有所有者可读写)umask 077touch secret.txt # 权限变成 600# 改成更宽松的(组员也可写)umask 002touch shared.txt # 权限变成 664# 永久修改:加到 ~/.bashrc 或 /etc/profileecho"umask 022" >> ~/.bashrcumask 是"减法"——它减掉不应该有的权限,而不是直接设置权限。
4 是什么?你可能见过这样的权限:
$ ls -l /usr/bin/passwd-rwsr-xr-x 1 root root 59976 /usr/bin/passwd注意 owner 那组的 x 位变成了 s——这是 SUID(Set User ID) 特殊权限。
三种特殊权限:
s | |||
s | |||
t |
# /usr/bin/passwd 有 SUID,普通用户改密码时# 临时以 root 身份运行,才能修改 /etc/shadowchmod 4755 /usr/bin/passwd # 4 = SUID# /tmp 有 sticky bit$ ls -ld /tmpdrwxrwxrwt 20 root root 4096 /tmp# ↑ t = sticky bit# /tmp 任何人都能写(rwxrwxrw),# 但 sticky bit 保证你只能删自己创建的文件chmod 1777 /tmp # 1 = sticky bitSUID 是安全敏感的——如果一个 SUID 程序有漏洞,攻击者可以利用它获得 root 权限。所以不要随便给普通程序设 SUID。
# 找出系统中所有 SUID 文件(安全审计必做)find / -perm -4000 -type f 2>/dev/nullrwxrwxrwx 还不够用传统权限只有三组(Owner/Group/Others),遇到这种场景就不够了:
文件属于 alice,组是 dev。现在需要 bob(不在 dev 组)也能读这个文件,但其他所有人不能读。
用传统权限做不到——只能把 Others 的 r 打开,但那样所有人都能读了。
ACL(Access Control List) 解决这个问题,允许为任意用户或组单独设置权限:
# 给 bob 读权限(不影响其他人)setfacl -m u:bob:r-- secret.txt# 给 qa 组只读权限setfacl -m g:qa:r-- secret.txt# 查看 ACL$ getfacl secret.txt# file: secret.txt# owner: alice# group: devuser::rw- ← owneruser:bob:r-- ← bob 单独的权限group::r-- ← dev 组group:qa:r-- ← qa 组单独的权限mask::r-- ← 有效权限上限other::--- ← 其他人无权限# 删除某条 ACLsetfacl -x u:bob secret.txt# 删除所有 ACL,恢复传统权限setfacl -b secret.txtls -l 看到权限后面有个 + 号,说明这个文件有 ACL:
$ ls -l secret.txt-rw-r--r--+ 1 alice dev 1024 secret.txt# ↑ + 号 = 有 ACLQ:目录的 r、w、x 分别代表什么?
r:能用 ls 列出目录内容(知道有哪些文件名)。w:能在目录里创建、删除、重命名文件(改变目录结构)。x:能进入目录(cd),也是访问目录内文件的前提——没有 x,即使有 r也无法访问文件内容。
Q:文件有写权限但没有删除权限,删不掉——这是真的吗?
是的。删除文件的权限由父目录的写权限决定,与文件本身的权限无关。你在目录里删一个文件,其实是在修改目录(移除一条 dentry 记录),所以需要父目录的 w 权限。这就是 sticky bit 的原理:/tmp 的 w 权限任何人都有,但 sticky bit 额外限制"只能删自己的文件"。
Q:chmod 777 的真正风险是什么?
三点:给了 Others 写权限,服务器上任何用户和进程都能修改文件;给了 x 权限,上传的恶意文件可直接执行;违反了最小权限原则,一旦有任何一处漏洞,攻击面最大化。正确做法是精确分配:只有真正需要写的用户/进程才给 w,需要执行的才给 x。
Q:umask 022 和 umask 002 有什么区别?
022:去掉 Group 和 Others 的写权限,新建文件是 644,目录是 755——组员只能读不能写,适合多用户系统。002:只去掉 Others 的写权限,新建文件是 664,目录是 775——组员可以写,适合团队共享目录场景(配合 SGID 使用效果更好)。
Linux 文件权限的核心逻辑从来不复杂:
谁(Owner / Group / Others / ACL)对什么(文件 / 目录)能做什么(r / w / x)chmod 777 不是"快速解决问题",是把这三个维度全部打开——任何人,对这个文件,可以做任何事。
记住一个原则,足以避开 90% 的权限问题:最小权限——只给必要的人,只给必要的权限,不多给一位。
如果你读完这篇还觉得 C、C++、Linux 有些陌生,别急:
感兴趣可以了解一下。
如果你已经有一定基础,想冲击更高的天花板,这些工业级 C++ 项目正是为你准备的:
| 线程池 | |
| 高性能日志库 MiniSpdlog | |
| 高性能内存池 | |
| 多线程下载工具 | |
| MySQL 连接池 | |
| 内存泄漏检测器 | |
| ReactorX | |
| 无锁栈 | |
| 工业级智能指针(shared_ptr) | |
| 高性能网络库 NetCore | |
| 高性能异步日志库 ZephyrLog | |
| 死锁检测工具 | |
| 高性能 HTTP 服务器 | |
| 协程库 CoroForge | |
| 高性能 HTTP 压测工具 | |
| Redis 核心模块实战 |
每个项目都是真实可用的工程代码,不是教学玩具。
详情点击 C++ 项目合集课程链接:为什么同样是"学过C++",有人面试碾压,有人开口就怂?差距在这18个C++硬核项目

觉得有收获,点赞、推荐、转发支持下哦~ 🙏