systemd的Limit指令通过MemoryMax、CPUQuota等配置项实现服务级资源硬限制,依托cgroups v2管控,比ulimit更可靠且支持热重载,是防御DoS的核心机制。

Limit 指令(通常指 systemd 的 ResourceLimit 配置项)是 Linux 系统中控制服务资源使用边界的核心机制,能有效防止单个服务过度消耗 CPU、内存、文件描述符等资源,从而降低因异常或恶意请求引发的 DoS 风险。
关键资源限制项及作用
在服务单元文件(如 /etc/systemd/system/myapp.service)的 [Service] 段中,常用限制项包括:
- MemoryMax=512M:硬性限制进程组最大内存使用量,超限后内核 OOM Killer 会终止该服务进程
- CPUQuota=50%:限制服务最多占用一个 CPU 核心的 50% 时间(即平均 0.5 核),防止单服务长期霸占 CPU
- TasksMax=200:限制服务可创建的最大进程/线程数,阻断 fork bomb 类攻击
- LimitNOFILE=1024:限制打开文件数(含 socket 连接),直接抑制连接耗尽型 DoS
- LimitNPROC=100:限制所属用户下该服务可派生的进程总数,增强隔离性
与系统级 ulimit 的区别
systemd 的 Limit 指令作用于服务实例级别,由 cgroups v2 统一管控,比传统 shell 层面的 ulimit 更可靠:
- ulimit 只影响启动时的 shell 环境,子进程可能绕过;而 systemd 限制随 cgroup 生效,无法被进程自身解除
- MemoryMax、CPUQuota 等高级限制仅在 systemd + cgroups v2 下可用,ulimit 不支持
- systemd 限制可热重载(systemctl daemon-reload && systemctl kill --signal=SIGUSR2 myapp.service),无需重启服务
防御 DoS 的典型配置建议
针对 Web 类或网络服务,推荐组合设置以兼顾稳定性与安全性:
- 设 MemoryMax=1G 并开启 MemoryAccounting=true,便于监控实际内存走势
- 对高并发服务,LimitNOFILE=8192 足够支撑数千并发连接;若需更高,同步调大 fs.file-max 内核参数
- 启用 Restart=on-failure 和 RestartSec=5,使服务在 OOM 或崩溃后自动恢复,避免人工干预空窗期
- 搭配 PrivateTmp=yes 和 ProtectSystem=strict,限制服务对文件系统的访问范围,减少横向影响
验证与调试方法
配置生效后,可通过以下方式确认和排查:
- 运行 systemctl show myapp.service | grep -i limit 查看实际加载的限制值
- 用 systemd-cgtop 实时观察各服务的 CPU、内存、IO 实时占用
- 检查 journalctl -u myapp.service -n 50,留意 “Killed process” 或 “Out of memory” 日志线索
- 模拟压测时,用 cat /sys/fs/cgroup/myapp.service/memory.max_usage_in_bytes(cgroup v2 路径)核对峰值内存是否触顶

















