强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

systemd 教程 / 安全沙箱(Security Sandboxing)

安全沙箱(Security Sandboxing)

systemd 提供了强大的安全沙箱机制,通过在 Unit 文件中设置各类保护参数,可以有效地限制服务进程的权限,减少攻击面。即使服务被攻破,攻击者也难以在系统中横向移动。


1. 安全沙箱参数总览

以下是 systemd 提供的主要安全沙箱参数分类:

分类参数作用
文件系统保护ProtectSystem保护系统目录只读
ProtectHome保护用户主目录
ReadWritePaths指定可写路径
ReadOnlyPaths指定只读路径
隔离PrivateTmp独立的 /tmp 目录
PrivateDevices隔离设备文件
PrivateNetwork隔离网络
PrivateUsers隔离用户命名空间
权限控制NoNewPrivileges禁止提权
CapabilityBoundingSet限制 Linux Capabilities
SystemCallFilter系统调用过滤
网络限制RestrictAddressFamilies限制可用的 socket 地址族
RestrictNamespaces限制命名空间类型
SELinux/AppArmorSELinuxContext设置 SELinux 上下文
AppArmorProfile指定 AppArmor 配置文件

2. 文件系统保护

2.1 ProtectSystem

ProtectSystem 用于保护系统关键目录:

[Service]
ProtectSystem=strict    # 最严格:/usr, /boot, /efi, /etc 完全只读
ProtectSystem=full      # 中等:/usr, /boot, /efi 只读,/etc 仍可写
ProtectSystem=true      # 同 full

级别对比:

级别/usr/boot/efi/etc
strict只读只读只读只读
full只读只读只读可写
true只读只读只读可写

2.2 ProtectHome

[Service]
ProtectHome=true           # /home, /root, /run/user 完全不可见
ProtectHome=tmpfs          # 使用 tmpfs 伪装,进程看到的是空目录
ProtectHome=read-only      # 只读挂载

2.3 ReadWritePaths / ReadOnlyPaths

ProtectSystem=strict 时,某些路径需要例外:

[Service]
ProtectSystem=strict
ReadWritePaths=/var/lib/myapp /var/log/myapp
ReadOnlyPaths=/etc/myapp

⚠️ 注意:路径支持通配符,如 /var/lib/*,但不支持递归通配。


3. 环境隔离

3.1 PrivateTmp

为服务提供独立的 /tmp/var/tmp

[Service]
PrivateTmp=true

服务进程看到的 /tmp 实际位于 /tmp/systemd-private-<uuid>-<service>.service-<pid>/tmp

💡 提示:几乎所有面向网络的服务都应启用 PrivateTmp,防止临时文件竞态攻击。

3.2 PrivateDevices

隔离设备文件,服务只能访问 /dev/null, /dev/zero, /dev/random 等基础设备:

[Service]
PrivateDevices=true

3.3 PrivateNetwork

完全隔离网络,服务无法访问任何网络:

[Service]
PrivateNetwork=true

⚠️ 注意:启用后服务无法绑定端口或发起网络连接,仅适用于纯本地服务。

3.4 PrivateUsers

隔离用户和组命名空间:

[Service]
PrivateUsers=true

进程内部看到的 UID/GID 映射与宿主不同,有效防止提权攻击。


4. 权限控制

4.1 NoNewPrivileges

禁止进程获得新权限(如 setuid、setgid):

[Service]
NoNewPrivileges=true

这是安全加固的基础选项,几乎所有服务都应启用。

4.2 CapabilityBoundingSet

精确控制服务可以使用的 Linux Capabilities:

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH

常用 Capabilities:

Capability说明
CAP_NET_BIND_SERVICE绑定 < 1024 端口
CAP_NET_RAW使用原始套接字
CAP_SYS_ADMIN系统管理操作(危险)
CAP_DAC_READ_SEARCH绕过文件读权限检查
CAP_CHOWN修改文件所有者

⚠️ 注意CAP_SYS_ADMIN 权限范围极大,应尽量避免授予。

4.3 SystemCallFilter

限制服务可以调用的系统调用:

[Service]
# 白名单模式:仅允许列出的系统调用
SystemCallFilter=@system-service

# 黑名单模式:禁止列出的系统调用
SystemCallFilter=~@mount @reboot @swap

预定义组:

组名包含的系统调用
@system-service常规服务所需的系统调用
@file-system文件系统操作
@network-io网络 I/O
@process进程管理
@mount挂载操作
@reboot重启/关机
@swap交换空间操作

5. 网络限制

5.1 RestrictAddressFamilies

限制服务可以使用的 socket 地址族:

[Service]
RestrictAddressFamilies=AF_INET AF_INET AF_UNIX

常用地址族:

地址族说明
AF_INETIPv4
AF_INET6IPv6
AF_UNIXUnix 域套接字
AF_NETLINKNetlink 套接字

5.2 RestrictNamespaces

限制服务可以创建的命名空间类型:

[Service]
RestrictNamespaces=user mnt net ionic

6. SELinux / AppArmor 集成

6.1 SELinux

[Service]
SELinuxContext=system_u:system_r:myapp_t:s0

需要配合 SELinux 策略模块使用。

6.2 AppArmor

[Service]
AppArmorProfile=myapp

对应的 AppArmor 配置文件位于 /etc/apparmor.d/myapp


7. Seccomp 过滤

systemd 支持通过 SystemCallFilter 使用 BPF 进行 seccomp 过滤:

[Service]
SystemCallFilter=@system-service
SystemCallArchitectures=native  # 仅允许原生架构系统调用
MemoryDenyWriteExecute=true     # 禁止 W+X 内存映射
LockPersonality=true            # 锁定执行域

8. 实际案例

8.1 加固 Nginx 服务

# /etc/systemd/system/nginx.service.d/security.conf
[Service]
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
NoNewPrivileges=true
ReadWritePaths=/var/log/nginx /var/lib/nginx /run
ReadOnlyPaths=/etc/nginx
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH
SystemCallFilter=@system-service @network-io @file-system
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=true
RestrictSUIDSGID=true
RestrictRealtime=true

8.2 加固 Redis 服务

[Service]
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/redis /var/log/redis /run/redis
CapabilityBoundingSet=
SystemCallFilter=@system-service @network-io @file-system
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

8.3 加固 Docker 服务

[Service]
ProtectHome=read-only
PrivateTmp=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/docker /var/run/docker.sock
ReadOnlyPaths=/etc/docker
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_ADMIN
SystemCallFilter=@system-service @mount @file-system
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK

9. 安全加固清单

以下是一份服务安全加固检查清单:

检查项推荐值说明
ProtectSystemstrict保护系统目录
ProtectHometrue隐藏主目录
PrivateTmptrue隔离临时目录
PrivateDevicestrue隔离设备文件
NoNewPrivilegestrue禁止提权
CapabilityBoundingSet最小化仅授予必要 capabilities
SystemCallFilter白名单使用 @system-service
RestrictAddressFamilies最小化仅允许需要的地址族
RestrictNamespacestrue限制命名空间
RestrictSUIDSGIDtrue限制 SUID/SGID
RestrictRealtimetrue限制实时调度
MemoryDenyWriteExecutetrue禁止 W+X 内存
LockPersonalitytrue锁定执行域
SystemCallArchitecturesnative限制系统调用架构

10. 验证安全配置

使用 systemd-analyze security 评估服务安全等级:

# 查看服务安全评分
systemd-analyze security nginx.service

# 输出示例(评分 0-10,越低越安全)
# Overall exposure level for nginx.service: 1.8 OK 🙂

💡 提示:目标是将评分控制在 2.0 以下。评分 > 5.0 的服务需要重点加固。


扩展阅读