
由 strace 分析引导的自动 systemd 服务加固。
SHH 可以为你的每个服务生成一组最优的加固选项,让你无需担心因沙箱限制过严而在生产环境中引发随机错误,即可提升系统的安全级别。
需要安装 Strace,并确保其可执行文件位于 PATH 中。目前要求 Strace 版本 >= 6.6。
你需要一个 Rust 构建环境,例如通过 rustup 获取。
在当前仓库中运行:
cargo build --release
install -Dm 755 -t /usr/local/bin target/release/shh
crates.io 安装sudo cargo install --root /usr/local systemd-hardening-helper
查看 GitHub releases 获取为每个标记版本构建的 Debian 软件包。
Arch Linux 用户可安装 shh AUR 软件包。
NixOS/Nix 用户可以从 unstable 分支 安装最新软件包。
要加固名为 SERVICE.service 的系统单元:
shh service start-profile SERVICE。服务将以 strace 分析模式重启。shh service finish-profile SERVICE -a。服务将使用根据之前的运行时分析构建的加固配置重启,以使其能按分析期间观察到的行为安全运行,并拒绝其他危险的系统操作。运行 shh -h 获取完整的命令行参考,或在子命令后附加 -h 获取帮助。
[!WARNING]
shh生成的加固选项在构造上不具备跨系统可移植性。 它们依赖于许多因素,如果其中任何一项发生变化,都可能导致服务故障:
- 分析期间覆盖的代码路径
- Linux 内核版本
- 所使用的 libc
- systemd 版本
在环境不同(即不同的 Linux 发行版)的系统上复用
shh生成的选项,极有可能导致服务故障。
如果你想快速测试一下会生成哪些选项,可以使用 shh run -- COMMAND。
当前目录和 PATH 环境变量都会影响程序的执行,请先重置它们:
$ cd /
export PATH=/usr/local/bin:/usr/bin:/bin
然后,查看为 curl https://www.example.com 调用生成的选项:
$ shh run -- curl https://www.example.com
...
-------- Start of suggested service options --------
ProtectSystem=strict
ProtectHome=true
PrivateTmp=disconnected
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectProc=ptraceable
LockPersonality=true
RestrictRealtime=true
ProtectClock=true
MemoryDenyWriteExecute=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
SocketBindDeny=ipv4:tcp
SocketBindDeny=ipv4:udp
SocketBindDeny=ipv6:tcp
SocketBindDeny=ipv6:udp
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_BPF CAP_CHOWN CAP_MKNOD CAP_NET_RAW CAP_PERFMON CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_MODULE CAP_SYS_NICE CAP_SYS_PACCT CAP_SYS_PTRACE CAP_SYS_TIME CAP_SYSLOG CAP_WAKE_ALARM
SystemCallFilter=~@aio:EPERM @chown:EPERM @clock:EPERM @cpu-emulation:EPERM @debug:EPERM @ipc:EPERM @keyring:EPERM @memlock:EPERM @module:EPERM @mount:EPERM @obsolete:EPERM @pkey:EPERM @privileged:EPERM @raw-io:EPERM @reboot:EPERM @resources:EPERM @sandbox:EPERM @setuid:EPERM @swap:EPERM @sync:EPERM @timer:EPERM
-------- End of suggested service options --------
或者,尽可能进行沙箱隔离:
$ shh run --mode aggressive --filesystem-whitelisting --network-firewalling -- curl https://www.example.com -o /dev/null
...
-------- Start of suggested service options --------
ProtectSystem=strict
ProtectHome=true
PrivateTmp=disconnected
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectProc=ptraceable
LockPersonality=true
RestrictRealtime=true
ProtectClock=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native
ReadOnlyPaths=-/
ReadWritePaths=-/dev
InaccessiblePaths=-/boot -/home -/lost+found -/media -/mnt -/opt -/root -/srv -/sys -/tmp -/var
TemporaryFileSystem=/usr:ro
BindReadOnlyPaths=-/usr/bin -/usr/lib -/usr/lib64 -/usr/local -/usr/share
NoExecPaths=-/
ExecPaths=-/usr/bin/curl -/usr/lib/x86_64-linux-gnu
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
SocketBindDeny=ipv4:tcp
SocketBindDeny=ipv4:udp
SocketBindDeny=ipv6:tcp
SocketBindDeny=ipv6:udp
IPAddressDeny=any
IPAddressAllow=[redacted]
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_BPF CAP_CHOWN CAP_MKNOD CAP_NET_RAW CAP_PERFMON CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_MODULE CAP_SYS_NICE CAP_SYS_PACCT CAP_SYS_PTRACE CAP_SYS_TIME CAP_SYSLOG CAP_WAKE_ALARM
SystemCallFilter=~@aio:EPERM @chown:EPERM @clock:EPERM @cpu-emulation:EPERM @debug:EPERM @ipc:EPERM @keyring:EPERM @memlock:EPERM @module:EPERM @mount:EPERM @obsolete:EPERM @pkey:EPERM @privileged:EPERM @raw-io:EPERM @reboot:EPERM @resources:EPERM @sandbox:EPERM @setuid:EPERM @swap:EPERM @sync:EPERM @timer:EPERM
-------- End of suggested service options --------