深色模式
权限不足排查
摘要:
Permission denied和403至少有五种完全不同的成因。本文先用一个判断树把范围缩小到"文件权限 / 强制访问控制 / 容器用户 / API 鉴权",再逐项给出验证命令。
适用环境
bash
id
umask
getenforce 2>/dev/null
kubectl auth can-i --help >/dev/null 2>&1 && echo kubectl-ok1
2
3
4
2
3
4
排障步骤
第 1 步:先分清是哪一类权限问题
- 报
Permission denied且涉及文件路径 → 文件系统或 MAC - 报
403 Forbidden且是 HTTP/API → 鉴权或 RBAC - 报
401 Unauthorized→ 认证未通过(没带凭据),不是权限问题
第 2 步:文件系统权限逐层检查
bash
namei -l /data/app/logs/access.log
id1
2
2
父目录缺执行权限会导致整条路径不可访问
目录需要 x 权限才能进入。中间任意一级目录没有 x,即使目标文件是 777 也访问不到。namei -l 可以一次看完整条路径。
第 3 步:确认进程的真实用户
bash
ps -o user,pid,args= -p <PID>
cat /proc/<PID>/status | grep -E 'Uid|Gid'
umask1
2
3
2
3
容器场景还要看 securityContext:
bash
kubectl get pod <pod> -n <ns> -o jsonpath='{.spec.securityContext} {.spec.containers[*].securityContext}'1
第 4 步:检查 SELinux / AppArmor
bash
getenforce
ls -Z /data/app 2>/dev/null
ausearch -m avc -ts recent 2>/dev/null | head -20
journalctl -t setroubleshoot --no-pager | tail -201
2
3
4
2
3
4
移动文件会丢失 SELinux 上下文
用 mv 把文件移入受控目录时上下文不会继承目标目录,导致权限正常但仍被拒绝。应使用 cp 后删除原件,或用 restorecon 修正。
第 5 步:K8s RBAC 权限
bash
kubectl auth can-i get pods -n <ns> --as=system:serviceaccount:<ns>:<sa>
kubectl describe rolebinding,clusterrolebinding -n <ns> | head -401
2
2
403 的具体缺失权限默认不显示
kubectl 默认只输出 Forbidden,加 -v=8 可以看到请求的具体 resource/verb,从而精确定位缺哪个权限。
第 6 步:能力集与 sudo
bash
grep CapEff /proc/<PID>/status
sudo -l -U <user> 2>/dev/null1
2
2
绑定 1024 以下端口、修改系统时间等需要具体 capability,不是 root 就能做(容器中尤其明显)。
验证
bash
sudo -u <运行用户> test -r <文件> && echo readable
sudo -u <运行用户> test -w <目录> && echo writable
kubectl auth can-i <verb> <resource> -n <ns> --as=system:serviceaccount:<ns>:<sa>1
2
3
2
3
常见坑
用 root 测试通过不等于服务能访问
一定要用服务的运行用户验证(sudo -u <user>),两者结果常常不同。
chmod 777 不是解决方案
放全权限会掩盖真实问题并带来安全风险,应修正属主或组权限。
容器以非 root 运行但卷属主是 root
需通过 fsGroup 或初始化容器修正属主,仅改镜像内用户不够。
直接关闭 SELinux 验证
setenforce 0 会让整机关闭强制访问控制,等于全局降低安全基线。应使用审计日志定位规则并精确放行。