不能强行注入已运行sshd进程到systemd cgroup,因其由systemd生命周期管理,手动写入cgroup.procs会被内核拒绝或自动清理;唯一可靠方式是通过systemd原生接管sshd.service并配置MemoryMax、MemoryHigh等参数实现高安全内存隔离。

不能强行“注入”已运行的 sshd 进程到 systemd 管理的 cgroup,但可以通过 systemd 服务单元原生配置高安全内存隔离,这是唯一可靠、符合设计规范的方式。
为什么不能“强行注入”sshd进程
systemd 的 cgroup 层级(如 /sys/fs/cgroup/system.slice/sshd.service)由其自身生命周期管理。手动将一个已在运行、且非由 systemd 启动的 sshd 进程写入 cgroup.procs 会失败或被立即踢出,原因包括:
- 进程必须由同一 cgroup 父控制器创建,否则内核拒绝归属
- systemd 持续监控其托管服务的 cgroup 成员,发现非法加入会自动清理
- sshd 主进程(PID 1)若为传统 SysV 启动,不归属任何 systemd scope,无法稳定绑定
正确做法:用 systemd 原生接管并加固 sshd.service
确保 sshd 由 systemd 管理(现代发行版默认如此),然后通过单元文件强化内存边界:
- 检查当前状态:
systemctl status sshd,确认 Active: active (running) 且 Loaded 行含vendor preset或enabled - 创建覆盖配置:
sudo systemctl edit sshd,填入:
[Service] MemoryMax=256M MemoryHigh=192M MemoryLow=128M MemorySwapMax=0 OOMScoreAdjust=-900
-
MemoryMax=256M:硬上限,超限后新内存分配阻塞,OOM Killer 可能触发(但因OOMScoreAdjust极低,几乎不会选中它) -
MemoryHigh=192M:软限,内核主动回收其 page cache 和匿名页,避免逼近硬限 -
MemorySwapMax=0:禁用 swap,防止攻击者利用交换空间绕过物理内存限制 -
OOMScoreAdjust=-900:大幅降低被 OOM Killer 选中的优先级,保护 sshd 不被误杀
执行 sudo systemctl daemon-reload && sudo systemctl restart sshd 生效。
验证与加固效果
重启后确认配置落地:
- 查当前 cgroup 路径:
cat /proc/$(pgrep -f "sshd.*@")/cgroup | grep system.slice - 看内存限制:
cat /sys/fs/cgroup/system.slice/sshd.service/memory.max应输出268435456(即 256MiB) - 实时观察内存压力:
systemctl show --property=MemoryCurrent,MemoryPeak sshd
此时即使 sshd 子进程(如用户登录会话)因漏洞触发异常内存分配,也会在到达 256MB 时被内核阻断,无法耗尽系统内存,也难以通过 mmap 或 fork 扩展攻击面。
补充建议:配合其他纵深防护
仅靠 cgroup 内存限制不够,需叠加以下措施:
- 关闭未使用的认证方式:编辑
/etc/ssh/sshd_config,设PasswordAuthentication no、KerberosAuthentication no - 限制并发连接数:
MaxSessions 10、MaxStartups 5:30:10 - 启用 systemd 的
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6,禁止套接字滥用 - 结合 SELinux 策略(如
sshd_t域限制 execmem、mmap_low),从内核层拦截可疑内存操作











