最小权限原则:账号、令牌与文件权限的落地
MidnightDeal
5 分钟阅读
最小权限原则一句话讲清:任何主体(人、进程、令牌)只拿到完成当前任务所必需的最小权限,且只在必需的时间窗口内持有。超出这一条,再多的隔离和审计都补不回来——攻击者拿到的凭据本身就是高权限的。
账号层面:别用 root 干活
Linux 上日常操作绝不该用 root 登录。用 sudo 做单条提权,并精确限制可被提权的命令,而非把账号塞进全权限组:
# /etc/sudoers.d/deploy (用 visudo -f 编辑)
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart app, /usr/bin/journalctl
即使 deploy 凭据泄露,攻击者能执行的命令也被钉死在两条之内。比"deploy 属 sudo 组可跑一切"安全得多。
边界条件:sudoers 规则有顺序优先级,通配符用错会绕过限制。例如 /usr/bin/* 会允许 sudo /usr/bin/vim 后再 :!bash 提权。改完务必用 visudo -c 校验语法,避免把自己锁死在 sudo 之外。
令牌与密钥:按用途拆分、按最短时间发放
CI/CD 里的部署令牌、云厂商的 access key,常常被赋予远超需要的权限。经验上,很多凭据泄露事件的根因不是密钥被偷,而是密钥本身就能读写整个项目乃至整个账号。
落地做法:
- 按用途拆分令牌,一条流水线一支,绝不共用。
- 赋予"只读"或"仅写指定资源"的策略,而非 * 通配。
- 能用临时凭证(STS / OIDC 短期令牌)就不落长期 key。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::build-artifacts/*"
}]
}
这个策略只让令牌往 build-artifacts 这一个桶写对象,拿去读数据库或删别的桶都会拒绝。
踩坑:把长期 key 写进仓库的 .env 再"后来删掉",历史提交里依然能翻出来。正确动作是密钥扫描 + 立即轮换,而不是相信删除能抹掉痕迹。
文件权限:独立低权用户 + 收紧默认
多数发行版默认 umask 022,新建文件对其他用户不可写,但组权限常被忽略。服务进程应以独立的低权用户运行,数据目录仅该用户可读:
chown -R appuser:appuser /var/lib/app
chmod 700 /var/lib/app
find /var/lib/app -type f -exec chmod 600 {} \;
边界条件:日志轮转工具(如 logrotate)可能以 root 重建文件并改掉属主和权限,使原本收紧的 700 被悄悄放宽。要在配置里显式指定 su appuser appuser 与 create 0600 appuser appuser,让轮转产物继承正确的属主与权限。
权限是会"漂移"的
最小权限不是一次性配置,而是持续约束。新增脚本、新接第三方、临时排障时开的宽权限,事后很少被收回。建议把权限声明写进基础设施即代码,每次变更走评审,让"谁在什么范围有什么权限"始终可审计、可回滚。
数据库与服务的权限同样收紧
应用连接数据库用的账号常被授予过高权限,远超业务只需的增删改查。应按表、按操作拆分:读写业务走仅含必要权限的专用账号,运维操作走另一个高权账号且不在应用配置里出现。经验上,一次 SQL 注入能造成的破坏上限,就是该连接账号的权限范围——把它钉在最小集,注入的影响面也跟着被钉死。
权限会随演进悄悄膨胀
新功能往往"先给宽权限跑通再说",事后没人收回。把权限声明写进评审清单,每次新增能力都问一句它真的需要这个权限吗,并定期复核实际授予与使用的差值,把长期未用到的权限收回。最小权限是动态维持的状态,不是一次性开关。
落地时还有常被忽略的一点:给人配权限要走同样的收敛逻辑。临时授权(如排障窗口)必须带到期时间,到点自动回收,而不是靠人记得收回。把"临时"做成系统强制的过期,比"记得撤销"可靠得多。
浏览 0
点赞 0
评论 0