使用 `systemd-analyze security` 加固 Linux 服务:从评分到可执行策略
I’m happy to translate the article for you, but I’ll need the full text of the post (the content you’d like translated). Could you please paste the article’s content here? Once I have it, I’ll keep the source line unchanged and translate the rest into Simplified Chinese while preserving all formatting, markdown, and technical terms.
引言
如果你在 Linux 上运行长期服务,硬化工作常常被推迟,因为它看起来风险很大:“如果我把生产环境弄坏了怎么办?”
一种实用的避免猜测的方法是先使用 systemd-analyze security 作为基线,然后在小的、可测试的 drop‑in 中逐步应用硬化。本指南演示了一套可重复使用的工作流程,适用于运行 systemd 的 Debian/Ubuntu/Fedora/Arch 主机。
systemd-analyze security 会根据沙箱和特权相关设置对单元进行评估,并给出一个暴露评分以及详细的发现。它帮助你确定先硬化哪些部分。
重要提示: 该评分是一种启发式指标,而非安全性的证明。请将其用于指导改进,然后通过服务级别的测试来验证行为。
前提条件
- 带有 systemd 的 Linux 主机
- root 或 sudo 权限
- 首先选择一个非关键服务进行练习
检查你的版本:
systemd --version
systemd-analyze --version
检查当前暴露
选择一个服务(例如:nginx.service),并检查其当前的暴露情况:
sudo systemd-analyze security --no-pager nginx.service
捕获输出,以便比较前后:
sudo mkdir -p /var/log/systemd-hardening
sudo systemd-analyze security --no-pager nginx.service \
| sudo tee /var/log/systemd-hardening/nginx.before.txt
创建 Drop‑In
切勿直接编辑供应商单元。请使用 drop‑in:
sudo systemctl edit nginx.service
将以下内容粘贴到打开的编辑器中:
[Service]
# Privilege/sandbox basics
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=full
ProtectHome=read-only
ProtectControlGroups=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
LockPersonality=yes
RestrictSUIDSGID=yes
# Networking/process constraints (keep AF_INET/AF_INET6 if web‑facing)
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes
# Resource guardrails (tune for your workload)
CPUQuota=80%
MemoryHigh=400M
MemoryMax=600M
TasksMax=512
重载并测试
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
sudo systemctl --no-pager --full status nginx.service
sudo journalctl -u nginx.service -n 100 --no-pager
curl -I http://127.0.0.1
如果出现问题,快速恢复:
sudo rm -f /etc/systemd/system/nginx.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
比较前后
sudo systemd-analyze security --no-pager nginx.service \
| sudo tee /var/log/systemd-hardening/nginx.after.txt
diff -u /var/log/systemd-hardening/nginx.before.txt \
/var/log/systemd-hardening/nginx.after.txt || true
您应该会看到更少的风险发现和更低的暴露分数。
自动审计
创建 /usr/local/sbin/systemd-security-audit.sh:
#!/usr/bin/env bash
set -euo pipefail
OUT_DIR="/var/log/systemd-hardening"
mkdir -p "$OUT_DIR"
UNITS=(
nginx.service
ssh.service
docker.service
)
for u in "${UNITS[@]}"; do
echo "==> Auditing $u"
if systemctl list-unit-files --type=service | awk '{print $1}' | grep -qx "$u"; then
TS="$(date -u +%Y%m%dT%H%M%SZ)"
systemd-analyze security --no-pager "$u" > "$OUT_DIR/${u}.${TS}.txt" || true
else
echo "WARN: unit not found: $u"
fi
done
使其可执行并运行:
sudo install -m 0755 /usr/local/sbin/systemd-security-audit.sh /usr/local/sbin/systemd-security-audit.sh
sudo /usr/local/sbin/systemd-security-audit.sh
可选的每日计时器
创建服务单元 /etc/systemd/system/systemd-security-audit.service:
[Unit]
Description=Run systemd security audit for selected services
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/systemd-security-audit.sh
创建计时器单元 /etc/systemd/system/systemd-security-audit.timer:
[Unit]
Description=Daily systemd security audit
[Timer]
OnCalendar=daily
RandomizedDelaySec=20m
Persistent=true
[Install]
WantedBy=timers.target
启用并启动计时器:
sudo systemctl daemon-reload
sudo systemctl enable --now systemd-security-audit.timer
sudo systemctl list-timers --all | grep systemd-security-audit
实用技巧
- 在尝试更严格的设置之前,先使用
ProtectSystem=full。 - 不要盲目为网络服务设置
PrivateNetwork=yes。 - 建议将
MemoryHigh作为主要限制阈值,MemoryMax作为硬性上限。 - 加固是针对具体服务的:逐步应用、验证每一次更改,并随时准备回滚步骤。
参考文献
- Systemd‑analyze(1) – 安全命令
- systemd.exec(5) – 沙箱和执行选项
- systemd.resource-control(5) – CPU/内存/任务限制
- systemd.unit(5) 与 drop‑ins(systemctl edit 工作流)
- Red Hat 文档关于 cgroups v2 + systemd 资源控制