你的Linux服务器真的安全吗?权限混乱是最大的后门

别信“装了防火墙就万事大吉”这种话。上周我帮一个朋友排查慢速SSH登录,结果发现他 /home/deploy/.ssh/authorized_keys 权限是 644——连普通用户都能读,SSH直接拒绝连接,但错误提示藏在日志里,他硬是查了两天。很多“神不知鬼不觉”的入侵,根本不是从外网打进来,而是从一个写错权限的配置文件、一个被忽略的临时脚本开始的。

你真的懂那9个字符吗?从读懂权限开始

-rwxr-xr-- 这串字符不是密码,它就是三组人+一个身份标记:

  • 第一个 - 是文件类型(d 表示目录,l 表示软链接)
  • 接着三个字母是属主能干啥(rwx = 能读、能写、能执行)
  • 再三个是属组能干啥(r-x = 能读、能执行、不能写)
  • 最后三个是其他人能干啥(r-- = 只能读)

数字权限只是速记法:r=4, w=2, x=1,加起来就是 754640 这类值。重点不是背数字,而是想清楚:这个文件谁该碰?谁绝对不能碰?
比如 /etc/shadow 通常是 640 —— root 可读写,shadow 组的人能读,其他所有人连看都不让看。这不是玄学,是“最小权限”最朴素的落地。

真实翻车现场:某次上线后网站被挂马,溯源发现是 Nginx 日志目录 /var/log/nginx 权限设成了 777,攻击者顺着日志轮转机制往里面塞了个恶意 .php 文件。别笑,这事儿我见过三次。

如何用chmod和chown精准设置权限?

chmod 改权限,chown 换主人——就这两条命令,够用了。
少用 777666 这类数字,多用符号模式,一眼看懂:

  • chmod g-w config.yml → 去掉组的写权限
  • chmod o-rx secrets.env → 其他人连读和执行都禁止

更关键的是配合用户组。别把所有运维都塞进 root 组。
举个例子:你用 nginx 用户跑 Web 服务,网站代码归 deploy 用户管,那目录可以这样设:

chown deploy:nginx /var/www/myapp  
chmod 750 /var/www/myapp  

效果是:deploy 能改代码,nginx 用户能读能执行(保证网页能打开),其他用户连目录都进不去。功能没打折,风险砍掉一大半。

特殊权限SUID、SGID、Sticky Bit是利器还是隐患?

这三个位(分别对应 4xxx2xxx1xxx)不是装饰品,用错等于送钥匙:

  • SUID(如 /usr/bin/passwd):普通用户执行时,暂时获得文件属主(root)权限。好处是改密码,坏处是——如果某个带 SUID 的脚本有命令注入漏洞,攻击者直接提权到 root。
    定期扫一遍:find / -type f -perm /4000 2>/dev/null | grep -v "Permission denied"
  • SGID(常用于目录):在该目录下新建的文件,自动继承目录的所属组。适合开发团队共用代码库,不用每次手动 chgrp
  • Sticky Bit(如 /tmp):目录里加了 tdrwxrwxrwt),用户只能删自己创建的文件,别人建的碰都碰不了。

记住:SUID 和 SGID 不是默认需要的。除非你明确知道为什么加,否则先别加。

如何用umask决定文件的默认“出生”权限?

umask 不是“设权限”,是“扣权限”。系统默认 umask 022,意思是:

  • 新建文件(默认666)→ 扣掉 022 → 得 644(属主读写,组/其他人只读)
  • 新建目录(默认777)→ 扣掉 022 → 得 755(属主全权,组/其他人可读可进)

对普通用户,建议改成 umask 027

  • 新文件变成 640(组可读,其他人彻底无权)
  • 加到 ~/.bashrc 末尾就行:echo "umask 027" >> ~/.bashrc && source ~/.bashrc

对生产环境的服务账户(比如 www-datanginx),直接上 umask 077 —— 新建的临时文件、日志、缓存,默认只有自己能碰。别等出事了才想起补救。

哪些关键目录和文件的权限必须锁死?

这些地方,权限松一寸,风险长一丈:

  • /etc/shadow/etc/sudoers/etc/ssh/sshd_config:必须 600644,绝不能 644 以外的开放权限
  • ~/.ssh/ 目录:必须 700id_rsaauthorized_keys:必须 600。SSH 客户端会严格校验,错了直接报错 Bad permissions
  • /var/log/ 下的日志:尤其 auth.logsecure,泄露登录行为和失败尝试,权限建议 640,属组设为 adm
  • 数据库配置文件(如 config/database.yml)、.env:哪怕只是本地测试,也请立刻 chmod 600。密码明文躺在 755 文件里?等于贴在公司门口的便签纸。

如何定期审计,不让权限悄悄“变质”?

权限会漂移。一次 cp -r、一个没加 -ptar 解压、甚至某些编辑器保存时重写文件,都可能重置权限。
每天花30秒跑这条命令,加进 crontab

# 每天早上8点检查Web目录下“其他人可写”的文件  
0 8 * * * find /var/www -type f -perm /o=w -ls 2>/dev/null | mail -s "⚠️ Web目录权限告警" your-email@company.com  

再补一刀:

# 手动快速扫一遍高危项(执行一次就行)  
find /etc /home /var -type f \( -perm 777 -o -perm 666 -o -perm 644 -name "*.key" \) -ls 2>/dev/null  

看到 .key 文件权限是 644?马上 chmod 600。看到 777 配置文件?先备份,再收紧。

今天下班前就能做的1个安全检查

现在,就打开你的服务器终端,执行这一行:

find /home /var/www -type f \( -perm -o=w -o -perm -g=w \) -ls 2>/dev/null  

它会列出所有用户家目录和网站目录里,“其他人”或“所属组”能写的文件。

逐个看:

  • 是日志?→ 改成 640,属组设为 admwww-data
  • 是上传目录里的临时文件?→ 确认是否真需要组写权限,否则 chmod go-w
  • 是某个脚本?→ 如果它含密码或密钥,立刻 chmod 600

做完这一步,关掉终端前喝口水——你刚亲手拧紧了一个可能已松动数月的螺丝。