我接手过一个项目,前任运维为了省事儿,把 Web 目录权限直接 chmod 777,"反正能跑就行"。三个月后,攻击者往 /var/www/html 里写了个 webshell,整台机器彻底沦陷。
权限这东西,不出事感觉没用,出事了悔断肠。今天从 SRE 视角把这套系统捋清楚,以后配权限不再靠"感觉"。
Linux 不认识你的名字,只认识数字。每个用户有一个 UID,每个组有一个 GID。系统对着这两个数字决定你能碰哪些文件、能跑哪些命令。
用户分类非常清晰:
【重点提醒】系统用户是最容易被忽视的风险点。Nginx、MySQL、Redis 这些服务,跑起来都是系统用户身份,给这些用户配权限要格外小气,能只读就绝不给写权限。
查一个用户的全部信息,一条命令搞定:
id nginx
# 输出示例:uid=998(nginx) gid=996(nginx) 组=996(nginx)
Linux 用户、组、密码的核心数据,都存在这三个文件里:
grep nginx /etc/passwd /etc/group /etc/shadow
日常创建系统服务账号,有个标准固定套路——指定 UID、禁止登录、不创建家目录,避免冗余权限:
# 创建 Nginx 专用账号,系统用户标准写法
useradd -u 998 -s /sbin/nologin -M nginx
# 非交互式设置密码(自动化脚本常用)
echo'S3cur3P@ss' | passwd --stdin nginx
同事用 su deploy 切到部署账号跑脚本,结果 Python 路径、pip 全报错。排查半小时发现,是 su 和 su - 搞混了:
su:只切换用户身份,环境变量、当前目录完全不变su -:完整的登录式切换,重新加载目标用户的环境,PATH、HOME 全量刷新【最佳实践】切换到另一个用户跑程序,**永远用
su -**,直接少踩 90% 的环境变量坑。
ll 命令输出的第一列长这样:-rwxr-xr--。
数字换算不用背,记住核心规则:r=4,w=2,x=1,权限值就是对应数字的和。
⚠️ 【高危红线】关于 chmod 777:只有本地虚拟机测试,且完全清楚风险的场景可以用。生产环境出现 777,一律视为高危配置,必须立即整改。
这是90%的人都会踩的坑,必须记牢:
给 shell 脚本执行了 chmod 100(只有执行权限),运行直接报 Permission denied。
根因:脚本执行时,内核先要读取文件内容确定解释器,没有 r 权限,就读不到 #!/bin/bash 这行,自然无法执行。
【最佳实践】脚本权限最低给
500(属主读+执行),常规场景统一给755。
SUID、SGID、Sticky Bit 这三个特殊权限,大多数教程讲得云里雾里,记住每个权限最核心的典型用途就够了。
普通用户为什么能改自己的密码?因为 /usr/bin/passwd 设了 SUID 位,用户执行这个命令时,会临时拥有文件属主(root)的权限,才能写入 /etc/shadow 密码文件。
⚠️ 【高危提醒】自己的业务二进制文件,绝对不要乱设 SUID,属于极高风险配置。
给协作目录设置 SGID 后,无论谁在目录里创建文件,文件的所属组都会自动继承目录的属组。不用再挨个执行 chown 改权限,团队协作省心又安全。
设置了 Sticky 位的目录,里面的文件只有文件属主、目录属主或 root 才能删除。/tmp 目录人人能写,但互相不能删文件,靠的就是这个权限。
# 查看特殊权限(s/t 出现在原 x 权限的位置)
ls -l /usr/bin/passwd /tmp
# 输出示例:
# -rwsr-xr-x root root /usr/bin/passwd ← SUID(s)
# drwxrwxrwt root root /tmp ← Sticky(t)
【避坑提示】如果看到大写的
S/T,说明设置了特殊权限,但对应的 x 权限没开,这个特殊权限基本没有实际意义,属于无效配置。
有两个核心扩展属性,日志防篡改、系统配置加固场景必须掌握,哪怕攻击者拿到 root 权限,也无法篡改:
a(append only):文件只能追加内容,不能删除、不能修改已有内容。日志文件加上它,攻击者拿到 root 也无法擦除攻击痕迹。i(immutable):文件完全冻结,删、改、重命名、建硬链接全禁止。核心系统配置文件的守护神。# 给日志文件加 a 属性,防篡改
chattr +a /var/log/nginx/access.log
# 给 sshd 核心配置文件加 i 属性,禁止任何修改
chattr +i /etc/ssh/sshd_config
# 查看文件扩展属性
lsattr /etc/ssh/sshd_config
# 输出示例:----i----------- /etc/ssh/sshd_config
运维新人最常犯的错:直接把同事加进 wheel 组,等于直接给了全量 root 权限。
正确的做法是按需最小授权,在 /etc/sudoers 里精确指定允许执行的命令,多一条都不给。
visudo 编辑 /etc/sudoers**:它会在保存前做语法检查。直接用 vim 编辑,一旦写错语法,sudo 会直接失效,连 root 都可能临时无法操作,极度被动。# 只允许 deploy 用户重启 nginx 服务,其他 root 权限全不给
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 开发人员只能查看 nginx 日志,无其他权限
dev_user ALL=(ALL) NOPASSWD: /usr/bin/tail -f /var/log/nginx/*
# 查看 sudo 操作审计日志
grep sudo /var/log/secure
id username | |
useradd -u 998 -s /sbin/nologin -M | |
su - username | |
chmod 755 file | |
chmod 644 file | |
chmod 4755 /usr/local/bin/x | |
chmod 2775 /project/shared | |
chown -R nginx:nginx /var/www | |
chattr +i /etc/ssh/sshd_config | |
chattr +a /var/log/app.log | |
lsattr filename | |
visudo |
权限这件事,最小权限原则 五个字,够用一辈子。
每个用户、每个进程,只给它完成工作必须的那部分权限,多一点都不给。
配错一次权限,可能当下什么事都不会发生;但那条错误的配置就像一颗钉子埋在路上,总有一天会扎到谁。
🔖 往期精彩推荐