ssh -A 等于把本地钥匙交到黑客手上,因其赋予远程服务器实时调用本地 ssh-agent 的权限,可绕过校验发起恶意签名请求,CVE-2023-38408 即利用此漏洞加载恶意模块执行代码。

ssh -A 为什么等于“把本地钥匙交到黑客手上”
启用代理转发(ssh -A)不是单纯“多转一次请求”,而是让远程服务器获得对你本地 ssh-agent 的**实时调用权**——它能随时发起签名请求,而你的 agent 默认不校验“谁在调用、想签什么”。CVE-2023-38408 就是利用这个信任链,诱使 agent 加载本地恶意 .so 库,直接执行代码。
- 只要攻击者控制了你连的那台服务器(比如伪装成跳板机或 CI 环境),就能通过转发套接字发送构造请求
- 漏洞触发不依赖远程主机权限,只取决于你本地
ssh-agent是否加载了 PKCS#11/FIDO 模块(OpenSSH 默认启用) - 修复后(OpenSSH ≥9.3p2)仍允许本地加载模块,但禁止远程动态添加;不过旧版存量巨大,Shodan 曾扫出超 4.6 万台暴露代理的服务器
SSH_AUTH_SOCK 转发后,哪些操作会意外触发风险
SSH_AUTH_SOCK 环境变量一出现,所有能访问它的进程(包括 git、rsync、甚至远程 shell 里起的 curl 脚本)都可能悄悄调用你的 agent。这不是功能缺陷,而是设计如此——但很多人没意识到“自动生效”背后没有白名单机制。
-
ssh -T git@github.com成功 ≠ 安全:它只验证基础连通性,不检测是否被中间人劫持签名请求 - CI/CD 流水线中用
ssh -A拉私有仓库?等同于授权构建机对你本地密钥“无限次签名” - VSCode Remote-SSH 默认启用代理转发,如果你连的是不可信开发机,编辑器后台任务(如 Git 插件自动 fetch)也会走这条通道
不用 ssh-agent 转发,怎么安全拉私有 Git 仓库
核心思路是:让远程机器拥有“有限、单次、可审计”的认证能力,而不是长期持有你的 agent 控制权。
- 用
ssh-add -c添加密钥,每次签名前强制弹窗确认(需图形环境或SSH_ASKPASS配合) - 对 CI 场景,改用部署密钥(deploy key)+ 限制权限(GitHub/GitLab 可设只读/仅特定 repo)
- 更彻底的方案:换用
sga-ssh(Guardian Agent),它把“允许哪台服务器执行哪个命令”变成显式策略,连git clone都要过用户审批 - 禁用全局转发:
ssh -o ForwardAgent=no user@host,再单独用LocalForward做端口映射,和认证解耦
检查当前 SSH 连接是否已暴露 agent
别只看有没有 -A 参数——某些配置文件或 IDE 插件会静默开启,且连接建立后无法动态关闭。
- 登录远程主机后立即执行:
echo $SSH_AUTH_SOCK,若输出非空路径(如/tmp/ssh-XXXXX/agent.XXXX),说明已转发 - 进一步验证是否可达:
ssh-add -l如果列出本地密钥,证明远程端真能调用你的 agent - 检查服务端限制:登录后运行
sshd -T | grep -E "(allowtcpforwarding|gatewayports)",确认未被管理员禁用(但客户端侧仍可主动开启)
真正难防的不是技术开关,而是“我只连一次测试机,应该没事”这种判断——只要 agent 进程活着、转发通道建过,风险就持续存在,哪怕你已经登出。










