防范高权限进程越权访问的关键是让进程启动时仅能访问必需资源,通过systemd沙箱(protecthome=true、rootdirectory、readonlypaths、nonewprivileges)、无权服务账号(nologin、非特权组)、精细化capabilities(如cap_net_bind_service)及selinux/apparmor强制访问控制实现纵深防御。

防范高权限进程越权访问,关键不是“禁止提权”,而是让进程从启动那一刻起,就只能看到、读到、写到它真正需要的那几样东西——既不给多余能力,也不留多余路径。
用systemd沙箱切断系统可见性
现代服务应优先通过systemd单元文件做运行时隔离,而不是依赖账号密码或文件权限硬拦:
- ProtectHome=true:自动屏蔽 /home、/root、/run/user,服务进程连 ls /home 都会 Permission denied;
- RootDirectory=/srv/myapp-root 或 RootImage=/var/lib/myapp.img:把整个运行环境锁进独立根目录,HOME 自然被限定在 jail 内;
- ReadOnlyPaths=/usr /etc + RWPaths=/var/lib/myapp /run/myapp:显式声明只读区和可写区,其余路径一律不可见、不可访问;
- NoNewPrivileges=true:禁用 setuid/setgid 和 capability 提权路径,防止二进制漏洞绕过限制。
服务账号本身必须“无权可越”
即使进程跑在沙箱里,账号本身也得是“空壳”,不能留任何交互入口或继承通道:
- shell 设为 /usr/sbin/nologin 或 /bin/false,禁止登录、禁止执行交互命令;
- /etc/passwd 中该账号的 home 字段必须指向真实隔离路径(如 /var/lib/myapp),且该路径属主为账号、属组为 root、权限为 700;
- 确保该账号不在 wheel、sudo 等特权组中,/etc/sudoers 里无匹配行;
- 用 auditctl -w /var/lib/myapp -p rwxa 监控异常读写,尤其关注 execve 和 openat 系统调用。
用Linux capabilities替代root全权
很多服务其实只需要一两个特权(如绑定1024以下端口、修改时间、发送信号),没必要给 root:
- 查清服务真正需要的能力,用 cap_net_bind_service,cap_sys_time 等精确授予;
- 用 setcap 'cap_net_bind_service+ep' /usr/local/bin/myserver 设置二进制能力;
- 配合 systemd 的 CapabilityBoundingSet 和 LimitNOFILE 等限制,堵死能力滥用出口;
- 避免使用 cap_sys_admin —— 它几乎等价于 root,应拆解为更细粒度能力。
强制访问控制补最后一道防线
当所有机制都失效时,SELinux 或 AppArmor 能靠策略兜底:
- 启用 enforcing 模式,为服务定义专用域(如 myapp_t),只允许访问明确声明的类型(myapp_var_lib_t、myapp_log_t);
- 用 semanage fcontext -a -t myapp_var_lib_t '/var/lib/myapp(/.*)?' 标记路径上下文;
- 搭配 audit2why 分析拒绝日志,持续收敛策略,避免过度宽松;
- 不推荐仅用 permissive 模式“观察”,那等于没开保护。











