反向 SSH 隧道:让云服务器控制家里的电脑
用 SSH 从家里连云服务器是家常便饭,但反过来——想让云服务器主动连回家里那台 Windows 电脑——就没那么直接了。家里电脑在内网、没有公网 IP,方向正好反了。这就要用到上一篇的内网穿透思路,做一条"反向 SSH 隧道"。
思路:用 frp 反向映射 22 端口
核心想法很简单:既然内网设备可以主动向外连,那就让家里的 Windows 把它的 SSH 端口(22)"贡献"出来,通过 frpc 反向隧道映射到云服务器的某个高位端口上。之后在云服务器上执行:
ssh -p 10222 用户名@127.0.0.1
就能登录回家里那台电脑。流量路径是:云服务器本地端口 → frps → frpc → 家里 Windows 的 SSH 服务。
为什么不用更"原生"的方案?我也评估过另一种基于节点配对的思路,但它存在跨设备审批同步的 bug,命令经常被拒。相比之下,frp 反向隧道 + SSH 这条链路纯粹、稳定、可控,最终选了它。
踩坑重灾区:Windows 自带的 OpenSSH
整件事最折磨人的部分,是在 Windows 上把 SSH 服务跑起来。系统其实自带 OpenSSH Server,但按官方方式启用后,它**就是起不来**。
症状
用服务方式启动会超时;切到前台调试运行,进程直接以退出码 0xC0000139 挂掉——这个码的意思是"找不到入口点",本质是二进制依赖的 DLL 不兼容。
我试过、但都没用的修复
- 重新生成主机密钥(
ssh-keygen -A); - 把
sshd_config里的__PROGRAMDATA__占位符替换成真实路径; - 手动开启
HostKey配置行; - 修正
administrators_authorized_keys的权限。
这些都做对了依然失败,问题根本不在配置,而在**系统自带的二进制本身**。
正解:换独立版 Win32-OpenSSH
从 GitHub 下载独立的 Win32-OpenSSH 发行版(Win32-OpenSSH-v9.x.x),解压后运行它自带的安装脚本:
powershell -ExecutionPolicy Bypass -File install-sshd.ps1
这个脚本会帮你做好权限修正并注册 Windows 服务。装完后服务能正常启动,版本号也和系统自带的不同。折腾一圈的结论就是:系统自带的 OpenSSH 在这个环境下就是坏的,别跟它死磕,换独立版最省事。
免密登录与安全
服务起来后,把云服务器的 ed25519 公钥放进家里电脑的 administrators_authorized_keys 文件,实现免密。这里有两个容易忽略的点:
- 该文件的权限必须严格收紧(仅 SYSTEM 和 Administrators 可读),且不能继承父目录权限,否则 SSH 会拒绝使用它;
- 反向隧道暴露的端口虽然公网可达,但只开了密钥认证、密码登录是关的,所以安全性依赖密钥本身。
# 客户端 frpc 反向隧道配置(片段)
[[proxies]]
name = "ssh-reverse"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 10222
再给 frpc 配一个开机自启的计划任务,家里电脑开机后隧道自动建立。
验证与使用
端到端验证通过后,就能在云服务器上直接对家里电脑执行命令、双向传文件(scp)。这让很多自动化脚本有了落地的地方——比如云端的定时任务可以远程触发家里这台机器的某些操作。
小结
反向 SSH 隧道本身没多少新概念,难的是 Windows 侧的环境坑。复盘下来最大的教训是:遇到系统组件莫名失败,别急着怀疑配置,先怀疑组件本身,换个来源干净、专门维护的独立版本,往往比逐行排查快得多。