修复OpenSSH 10.4 seccomp问题
2026-07-16
3 分钟阅读 (641 字)
Alpine Linux 下 OpenSSH 10.4 seccomp 沙箱兼容性问题排查记录
环境信息
| 项目 | 详情 |
|---|---|
| 系统 | Alpine Linux (chroot 环境) |
| 内核 | 不支持 CONFIG_SECCOMP |
| OpenSSH | 10.4_p1-r0 (edge 源) |
| 问题表现 | SSH 连接被重置,无法登录 |
问题现象
执行 ssh user@host 连接时,服务端立即返回:
shell
kex_exchange_identification: read: Connection reset by peerConnection reset by 10.0.0.1 port 22
排查过程
1. 查看服务端调试日志
bash
# 先停止sshd服务rc-service sshd stop# 启动一个前台debug服务便于查看连接过程中的具体错误/usr/sbin/sshd -D -d
另一个窗口ssh连接这个服务,
查看之前的debug查看
关键报错:
shell
ssh_sandbox_child: prctl(PR_SET_SECCOMP): Invalid argument [preauth]fatal: ssh_sandbox_child: prctl(PR_SET_SECCOMP): Invalid argument [preauth]
2. 检查内核 seccomp 支持
bash
zcat /proc/config.gz | grep CONFIG_SECCOMP
输出:
shell
# CONFIG_SECCOMP is not set
确认内核未编译 CONFIG_SECCOMP。
3. 确认 OpenSSH 版本变更
查阅 OpenSSH 10.4 Release Notes:
Potentially-incompatible changes
sshd(8): on Linux systems with the seccomp sandbox enabled, failures to enable SECCOMP or NO_NEW_PRIVS are now fatal. Previously sshd(8) would log the error but continue operation.
根本原因
| 层级 | 问题 |
|---|---|
| 内核 | 未开启 CONFIG_SECCOMP,prctl(PR_SET_SECCOMP) 返回 EINVAL |
| OpenSSH 10.4 | 将沙箱启动失败从警告升级为致命错误,直接终止连接 |
| Alpine edge 源 | 仅提供 10.4 版本,无法降级到 9.9 或 10.3 |
解决方案
实现步骤
1. 编译伪装库
bash
apk add gcc libc-dev
bash
cat > /tmp/fake_seccomp.c << 'EOF'#define _GNU_SOURCE#include <stddef.h>#include <dlfcn.h>#include <sys/prctl.h>#include <stdarg.h>int prctl(int option, ...) {static int (*real_prctl)(int, ...) = NULL;if (!real_prctl) real_prctl = dlsym(RTLD_NEXT, "prctl");// 拦截 PR_SET_SECCOMP 和 PR_SET_NO_NEW_PRIVSif (option == PR_SET_SECCOMP ||option == PR_SET_NO_NEW_PRIVS ||// 修复sftpoption == PR_SET_DUMPABLE) {return 0; // 假装成功}// 转发其他调用,保留可变参数va_list args;va_start(args, option);int result = real_prctl(option, args);va_end(args);return result;}EOF
bash
gcc -shared -fPIC /tmp/fake_seccomp.c -o /tmp/fake_seccomp.so -ldlcp /tmp/fake_seccomp.so /usr/local/lib/chmod 644 /usr/local/lib/fake_seccomp.so
2. 修改 OpenRC 启动脚本
编辑 /etc/init.d/sshd,
在 #!/sbin/openrc-run 下方添加:
bash
export LD_PRELOAD=/usr/local/lib/fake_seccomp.so
修改后文件顶部示例:
bash
#!/sbin/openrc-runexport LD_PRELOAD=/usr/local/lib/fake_seccomp.sodescription="OpenSSH Daemon"
3. 重启服务并验证
bash
rc-service sshd restartssh -p 2222 user@host
未来维护
未来更新openssh-server版本需检查/etc/init.d/sshd文件是否变更
总结
在 Alpine Linux chroot 环境下,由于内核不支持 CONFIG_SECCOMP,OpenSSH 10.4 的强制沙箱机制导致连接被拒绝。通过 LD_PRELOAD 劫持 prctl 系统调用,伪装沙箱启用成功,使 OpenSSH 10.4 在旧内核上正常运行。
此方案在保证使用最新版本的同时,绕过了内核兼容性问题,适用于无法升级内核的容器或 chroot 环境。
提示
安全性未知,尽量不要在生产环境使用