核心是启动即隔离:设PrivateNetwork=yes使服务仅见lo接口;再用RestrictAddressFamilies限定协议、IPAddressAllow/IPAddressDeny控制IP、PrivateUsers+NoNewPrivileges防逃逸。

直接对网络服务做沙箱隔离,核心不是加一层“防护罩”,而是让它从启动那一刻起就只拥有最小必要权限——看不见不该看的网络、打不开不该开的端口、读不到不该读的文件、也升不了不该升的权限。
用 systemd 私有网络命名空间切断默认联网能力
这是最基础且关键的一步。在服务单元文件中设置 PrivateNetwork=yes,服务就会运行在独立的网络命名空间里:只有 lo 回环接口可用,真实网卡(如 eth0、wlan0)和主机上其他服务的端口完全不可见。
- 纯本地处理类服务(比如日志压缩、配置校验)开这个选项就够了
- 若需对外提供 HTTP 或连接数据库,必须配合后续的 IP 白名单或端口映射,不能只靠它
- 注意 journal 日志可能变慢,可加 StandardOutput=journal+console 缓解
限制协议族与地址类型防绕过
即使开了私有网络,进程仍可能通过 AF_UNIX socket 或 AF_NETLINK 与内核通信,进而探测宿主机状态或提权。用 RestrictAddressFamilies 显式收窄可用协议:
- 仅允许 IPv4 通信:RestrictAddressFamilies=AF_INET AF_UNIX
- 彻底禁用网络(仅 IPC):RestrictAddressFamilies=AF_UNIX
- 绝对避免写
AF_UNSPEC——它等于不设防
按需放行 IP 和端口,而非靠黑名单堵漏
在私有网络基础上,用 IPAddressAllow 和 IPAddressDeny 做白名单控制:
- 只连内网数据库:IPAddressAllow=192.168.5.0/24 + IPAddressDeny=any
- 若服务要监听端口,必须加 CapabilityBoundingSet=CAP_NET_BIND_SERVICE,否则 bind() 会失败
- IPAddressDeny 只管出向连接,入向流量仍需防火墙(如 nftables)配合
绑定用户隔离 + 权限锁死防逃逸
光隔离网络不够,攻击者可能借 /proc/net 或 netlink 获取宿主机信息。启用 PrivateUsers=yes 并配 NoNewPrivileges=yes:
- systemd 自动分配临时 UID/GID 映射(需提前配置
/etc/subuid和/etc/subgid) - 服务以 root 身份运行,但该 root 对宿主机无真实权限
- 结合 DynamicUser=yes,实现账户“用完即焚”,大幅压缩横向移动空间









