核心是“动态身份+环境约束+权限最小化”三位一体:启用dynamicuser实现账户生命周期管控,配合restrictnamespaces、privatetmp、protectsystem、nonewprivileges等沙箱选项强化运行时隔离,并通过restrictaddressfamilies、ipaddressallow/deny、memorymax等策略实现网络与资源细粒度控制。

实施系统服务账号的安全沙箱隔离,核心在于“动态身份 + 环境约束 + 权限最小化”三位一体。不是给服务配一个固定用户再加点限制,而是让每次启动都生成专属、短暂、受限的执行上下文。
启用 systemd DynamicUser 实现账户生命周期管控
这是最直接有效的起点——消除静态账户带来的长期攻击面。
- 在服务单元文件(如
/etc/systemd/system/myapp.service)中添加:DynamicUser=yesStateDirectory=myappCacheDirectory=myappLogsDirectory=myapp - systemd 会自动从
/etc/subuid和/etc/subgid分配 UID/GID,不写入/etc/passwd,服务停止即销毁 - 配合
RestrictNamespaces=yes和RestrictSUIDSGID=yes可进一步封堵提权路径
叠加运行时沙箱强化(PrivateTmp / ProtectSystem / ReadOnlyPaths)
DynamicUser 解决身份问题,这些选项解决环境可控性问题。
-
PrivateTmp=true:为服务提供独立的/tmp,避免临时文件被其他进程窥探或污染 -
ProtectSystem=strict:挂载/usr、/boot、/etc为只读,防止配置篡改 -
ReadOnlyPaths=/var/log(若无需写日志)或ReadWritePaths=/var/log/myapp(仅放开必要路径) -
NoNewPrivileges=true:禁止服务进程通过execve获取额外权限,阻断 setuid 逃逸
结合网络与资源策略实现细粒度访问控制
服务不该默认拥有全网访问能力,也不该无上限消耗资源。
-
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6(按需保留,禁用AF_NETLINK等高危协议) -
IPAddressDeny=any+IPAddressAllow=127.0.0.1或指定内网段,显式放行而非默认开放 -
MemoryMax=512M、CPUQuota=50%、TasksMax=100,防止单个服务拖垮整机 - 如需调用外部 API,建议搭配 eBPF 或 MXC 类策略引擎,在内核层做域名/路径级白名单(非 iptables 粗粒度拦截)
认证与审计闭环:让每个动作可追溯、可验证
沙箱不是黑盒,所有关键操作必须留下可信痕迹。
- 启用
LogLevel=notice并确保journald配置了持久日志(Storage=persistent) - 使用
Delegate=yes+ManagedOOM=kill,使 cgroup 事件可被 systemd 监控并记录 - 对敏感服务启用
SecureBits=keep-caps+CapabilityBoundingSet=CAP_NET_BIND_SERVICE,只授必要能力,拒绝隐式继承 - 定期用
journalctl -u myapp.service --since "1 hour ago" | auditlog-filter关联 SELinux 或 systemd-audit 日志,验证策略是否真实生效











