适用场景Windows 本地电脑通过 SSH 登录裸金属服务器通过跳板机访问内网机器让远端服务器使用 Windows 本地代理用 VS Code Remote-SSH 连接远端服务器。0. 当前网络与目标机器关系名称IP / Host说明Windows 本地电脑C:\Users\24385本地开发机本地代理端口为127.0.0.1:7897跳板机10.42.206.102Windows 可直接 SSH 登录目标机10.20.2.5/bms-25只能经跳板机访问其他服务器192.168.206.112用户pcljgy其他服务器192.168.206.140/192.168.206.140_jgy用户pcljgy目标 1Windows 直接登录目标机ssh bms-25实际路径Windows 本地电脑 → 10.42.206.102 → 10.20.2.5目标 2让远端服务器使用 Windows 本地代理远端服务器 127.0.0.1:10240 ↓ SSH 隧道 Windows 本地 127.0.0.1:78971. SSH 免密登录基础1.1 公钥应该放在哪里SSH 免密登录的规则是你用哪个用户登录服务器就去哪个用户的家目录找authorized_keys。登录命令服务器读取的公钥文件ssh root10.42.206.102/root/.ssh/authorized_keysssh root10.20.2.5/root/.ssh/authorized_keysssh pcljgy192.168.206.112/home/pcljgy/.ssh/authorized_keys所以不是“必须上传到 root 文件夹”而是因为你登录的是root用户。1.2/和/root的区别/ 是 Linux 系统根目录 /root 是 root 用户的家目录1.3 公钥和私钥你的 Windows 公钥是C:\Users\24385\.ssh\id_rsa.pub私钥是C:\Users\24385\.ssh\id_rsa只能上传公钥id_rsa.pub不要上传私钥id_rsa。2. 通过跳板机访问内网目标机2.1 为什么ssh -J失败曾尝试ssh-J root10.42.206.102 root10.20.2.5报错channel 0: open failed: administratively prohibited: open failed stdio forwarding failed Connection closed by UNKNOWN port 65535含义Windows 成功连上了跳板机但跳板机的 SSH 服务不允许 TCP forwarding所以ProxyJump被禁止。常见原因是跳板机/etc/ssh/sshd_config中有AllowTcpForwarding no或存在PermitOpen/Match限制。2.2 如何查询-J的含义ssh --help不一定可用因为 OpenSSH 通常不支持--help。可以用ssh-h21|grep---J或manssh进入手册后输入/-J-J是ProxyJump格式ssh-J跳板机用户跳板机IP 目标用户目标IP2.3 使用ProxyCommand nc代替ProxyJump先在跳板机确认存在ncwhichnc结果/usr/bin/nc测试跳板机到目标机的 22 端口nc-vz10.20.2.522结果Ncat: Connected to 10.20.2.5:22.说明10.42.206.102 → 10.20.2.5:22 是通的Windows 本地可以这样直接测试ssh-oProxyCommandssh root10.42.206.102 /usr/bin/nc %h %proot10.20.2.5这里不要写nc -vz因为-vz只是测试端口。真正代理 SSH 流量时应该使用/usr/bin/nc %h %p其中%h 目标 HostName例如 10.20.2.5 %p 目标端口默认 223. 将 Windows 公钥写入内网目标机3.1 成功的一条 PowerShell 命令在 Windows PowerShell 中执行$pub(Get-Content$env:USERPROFILE\.ssh\id_rsa.pub-Raw).Trim();ssh-oProxyCommandssh root10.42.206.102 /usr/bin/nc %h %proot10.20.2.5mkdir -p /root/.ssh touch /root/.ssh/authorized_keys grep -qxF $pub /root/.ssh/authorized_keys || echo $pub /root/.ssh/authorized_keys; chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys作用读取 Windows 本地id_rsa.pub通过ProxyCommand nc连接10.20.2.5在目标机创建/root/.ssh将公钥写入/root/.ssh/authorized_keys如果公钥已存在则不重复添加设置正确权限。权限要求chmod700/root/.sshchmod600/root/.ssh/authorized_keys3.2 为什么“管道传公钥 内层 ssh”容易失败之前类似命令Get-Content$env:USERPROFILE\.ssh\id_rsa.pub|ssh root10.42.206.102ssh root10.20.2.5 mkdir -p /root/.ssh cat /root/.ssh/authorized_keys失败原因外层 SSH 正在接收管道输入内层ssh root10.20.2.5又需要交互式输入密码管道和交互式密码输入容易冲突。改用ProxyCommand nc后Windows 本地直接建立到目标机的 SSH 会话所以可以正常输入密码并写入公钥。4. Windows SSH config 推荐配置打开配置文件notepad$env:USERPROFILE\.ssh\config推荐写法Host bms-gateway HostName 10.42.206.102 User root IdentityFile C:/Users/24385/.ssh/id_rsa IdentitiesOnly yes ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes Host bms-25 HostName 10.20.2.5 User root IdentityFile C:/Users/24385/.ssh/id_rsa IdentitiesOnly yes ProxyCommand ssh -q bms-gateway /usr/bin/nc %h %p ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes之后可以直接ssh bms-25ProxyCommand中加-q的作用是减少跳板机登录 banner 等输出避免干扰 VS Code Remote-SSH。5. VS Code Remote-SSH 连接问题5.1 先判断是否真的 SSH 失败如果日志里有Found existing installation at /root/.vscode-server... Starting VS Code CLI... Remote server is listening on socket /tmp/code-...或Found running server... listeningOn34713说明 SSH 已经连上VS Code Server 也已启动。失败通常发生在后续 tunnel / socket 通信。5.2 socket 模式问题如果看到remote.SSH.remoteServerListenOnSocket true Remote server is listening on socket /tmp/code-... Exec server failed: Error: read ECONNRESET可以先关闭 socket 模式。打开 VS Code 用户设置notepad$env:APPDATA\Code\User\settings.json加入或合并{remote.SSH.remoteServerListenOnSocket:false,remote.SSH.useExecServer:false,remote.SSH.useLocalServer:false,remote.SSH.showLoginTerminal:true,remote.SSH.remotePlatform:{bms-25:linux}}然后在 VS Code 中执行Ctrl Shift P Remote-SSH: Kill VS Code Server on Host... 选择 bms-25再重新连接。5.3 目标机禁止 TCP forwarding如果日志里出现channel 3: open failed: administratively prohibited: open failed检查目标机sshd-T|grep-Eiallowtcpforwarding|permitopen|allowstreamlocalforwarding曾出现allowtcpforwarding no allowstreamlocalforwarding yes permitopen any这说明目标机禁止 TCP forwarding。VS Code Remote-SSH 需要 SSH tunnel因此会失败。5.4 开启目标机 TCP forwarding在目标机10.20.2.5上执行cp-a/etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date%Y%m%d_%H%M%S)修改或追加grep-qEi^[[:space:]]*AllowTcpForwarding[[:space:]]/etc/ssh/sshd_config\sed-i-Es/^[[:space:]]*AllowTcpForwarding[[:space:]].*/AllowTcpForwarding yes/I/etc/ssh/sshd_config\||echoAllowTcpForwarding yes/etc/ssh/sshd_config检查配置sshd-t无输出表示语法正确。重载服务systemctl reload sshd如果 reload 不可用systemctl restart sshd确认sshd-T|grep-Eiallowtcpforwarding|permitopen|allowstreamlocalforwarding期望allowtcpforwarding yes allowstreamlocalforwarding yes permitopen any5.5 注意Match块覆盖如果改完仍然是allowtcpforwarding no检查grep-nEiAllowTcpForwarding|PermitOpen|AllowStreamLocalForwarding|Match/etc/ssh/sshd_config如果看到Match User root AllowTcpForwarding no则需要修改Match块内部配置。6. 远程端口转发让远端使用 Windows 本地代理6.1 这是远程端口转发-R命令ssh-N-T-R 127.0.0.1:10240:127.0.0.1:7897 bms-25含义bms-25 上的 127.0.0.1:10240 ↓ SSH 隧道 Windows 本地的 127.0.0.1:7897所以在远端访问127.0.0.1:10240实际会访问 Windows 本地127.0.0.1:78976.2 临时启动代理隧道在 Windows PowerShell 执行ssh-N-T-R 127.0.0.1:10240:127.0.0.1:7897 -o ServerAliveInterval30 -o ServerAliveCountMax6 -o TCPKeepAliveyes -o ExitOnForwardFailureyes -o ConnectTimeout15 bms-25保持这个窗口不关闭。6.3 测试远端代理在远端执行curl-xhttp://127.0.0.1:10240 https://github.com-I如果返回 HTTP 响应头说明转发成功。6.4 设置远端代理环境变量exporthttp_proxyhttp://127.0.0.1:10240exporthttps_proxyhttp://127.0.0.1:10240exportHTTP_PROXYhttp://127.0.0.1:10240exportHTTPS_PROXYhttp://127.0.0.1:10240测试curlhttps://github.com-I6.5 Git 代理设置gitconfig--globalhttp.proxy http://127.0.0.1:10240gitconfig--globalhttps.proxy http://127.0.0.1:10240取消gitconfig--global--unsethttp.proxygitconfig--global--unsethttps.proxy7. 将远程代理转发写进 SSH config7.1 不建议直接写进普通 Host可以直接写Host 192.168.206.112 HostName 192.168.206.112 User pcljgy RemoteForward 127.0.0.1:10240 127.0.0.1:7897但不推荐用于 VS Code因为 VS Code Remote-SSH 会开多条 SSH 连接。每条连接都会尝试占用远端127.0.0.1:10240容易冲突、卡住或出现remote port forwarding failed for listen port 10240更稳的方式是分成两个 Host普通 Host给 VS Code / 普通 SSH 使用 -proxy Host专门维持代理隧道7.2 bms-25 推荐配置Host bms-gateway HostName 10.42.206.102 User root IdentityFile C:/Users/24385/.ssh/id_rsa IdentitiesOnly yes ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes Host bms-25 HostName 10.20.2.5 User root IdentityFile C:/Users/24385/.ssh/id_rsa IdentitiesOnly yes ProxyCommand ssh -q bms-gateway /usr/bin/nc %h %p ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes Host bms-25-proxy HostName 10.20.2.5 User root IdentityFile C:/Users/24385/.ssh/id_rsa IdentitiesOnly yes ProxyCommand ssh -q bms-gateway /usr/bin/nc %h %p RemoteForward 127.0.0.1:10240 127.0.0.1:7897 ExitOnForwardFailure yes ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes RequestTTY no SessionType none使用ssh bms-25# 普通登录 / VS Codessh bms-25-proxy# 代理隧道7.3 192.168.206.112 推荐配置Host 192.168.206.112 HostName 192.168.206.112 User pcljgy ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes Host 192.168.206.112-proxy HostName 192.168.206.112 User pcljgy RemoteForward 127.0.0.1:10240 127.0.0.1:7897 ExitOnForwardFailure yes ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes RequestTTY no SessionType none使用ssh 192.168.206.112# 普通登录 / VS Codessh 192.168.206.112-proxy# 代理隧道7.4 192.168.206.140_jgy 推荐配置Host 192.168.206.140_jgy HostName 192.168.206.140 User pcljgy ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes Host 192.168.206.140_jgy-proxy HostName 192.168.206.140 User pcljgy RemoteForward 127.0.0.1:10240 127.0.0.1:7897 ExitOnForwardFailure yes ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes RequestTTY no SessionType none使用ssh 192.168.206.140_jgy# 普通登录 / VS Codessh 192.168.206.140_jgy-proxy# 代理隧道7.5 为什么 VS Code 不能连接-proxyHost-proxyHost 里有RequestTTY no SessionType none含义是该连接只做隧道不启动远程 shell。VS Code 需要远程执行脚本、安装和启动 VS Code Server因此不适合连接-proxyHost。正确用法用途HostVS Code 远程开发bms-25bms-25 代理隧道bms-25-proxyVS Code 远程开发192.168.206.112192.168.206.112 代理隧道192.168.206.112-proxy7.6 如果坚持直接写进普通 Host可以这样写但要降低冲突影响Host 192.168.206.112 HostName 192.168.206.112 User pcljgy RemoteForward 127.0.0.1:10240 127.0.0.1:7897 ExitOnForwardFailure no ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes这里建议用ExitOnForwardFailure no不要用ExitOnForwardFailure yes否则 VS Code 多连接时如果第二条连接发现远端10240已被占用可能直接失败。8. 后台启动代理隧道8.1 前台启动ssh bms-25-proxy或ssh 192.168.206.112-proxy窗口无输出、不进入 shell、一直挂着是正常现象。8.2 后台隐藏启动Start-Process-WindowStyle Hidden-FilePathssh.exe-ArgumentListbms-25-proxyStart-Process-WindowStyle Hidden-FilePathssh.exe-ArgumentList192.168.206.112-proxyStart-Process-WindowStyle Hidden-FilePathssh.exe-ArgumentList192.168.206.140_jgy-proxy如果ssh.exe不在 PATH 中Start-Process-WindowStyle Hidden-FilePathC:\Program Files (x86)\OpenSSH-Win64\ssh.exe-ArgumentListbms-25-proxy8.3 查看 SSH 进程Get-Processssh8.4 关闭所有 SSH 进程Stop-Process-Name ssh注意这会关闭所有名为ssh的进程包括普通 SSH 和隧道。9. 保活参数解释ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yes整体含义每 30 秒检查一次 SSH 连接连续 6 次无响应则断开大约 3 分钟。9.1ServerAliveInterval 30如果 30 秒内没有收到服务器任何数据SSH 客户端向服务器发送 SSH 协议层保活包。9.2ServerAliveCountMax 6连续 6 次保活探测无响应后SSH 客户端断开连接。30 秒 × 6 180 秒9.3TCPKeepAlive yes启用操作系统 TCP 层面的 keepalive。它更底层但检测通常更慢。9.4 区别参数层级作用ServerAliveIntervalSSH 协议层定期发送 SSH 保活包ServerAliveCountMaxSSH 协议层连续多少次无响应后断开TCPKeepAliveTCP 系统层操作系统检测 TCP 连接这些参数只能检测坏连接并退出不能自动重连。若要自动重连可考虑autossh、Windows 任务计划程序或 PowerShell 循环脚本。10. 常见报错速查10.1unknown option -- -命令ssh--help原因OpenSSH 通常不支持--help。替代ssh-hmanssh10.2channel 0: open failed: administratively prohibited常见于ssh-J root10.42.206.102 root10.20.2.5原因跳板机禁止 TCP forwarding。解决改用ProxyCommand nc或在跳板机开启AllowTcpForwarding yes。10.3channel 3: open failed: administratively prohibited常见于 VS Code Remote-SSH。原因目标机禁止 TCP forwarding导致 VS Code tunnel 建立失败。解决在目标机开启AllowTcpForwarding yes10.4 VS Code 连接-proxyHost 卡住现象设置 SSH 主机 192.168.206.112-proxy: 正在初始化 VS Code 服务器原因-proxyHost 是隧道不适合 VS Code 远程开发。解决VS Code 连接普通 Host代理隧道用 PowerShell 单独启动。10.5remote port forwarding failed for listen port 10240原因远端127.0.0.1:10240已被其他 SSH 隧道占用。排查ss-lntp|grep10240解决关闭已有隧道或换端口例如10241。11. 速查命令测试普通 SSHssh bms-25 ssh 192.168.206.112 ssh 192.168.206.140_jgy测试 ProxyCommandssh-oProxyCommandssh -q root10.42.206.102 /usr/bin/nc %h %proot10.20.2.5启动 bms-25 代理ssh bms-25-proxy后台启动 bms-25 代理Start-Process-WindowStyle Hidden-FilePathssh.exe-ArgumentListbms-25-proxy远端设置代理exporthttp_proxyhttp://127.0.0.1:10240exporthttps_proxyhttp://127.0.0.1:10240远端测试代理curl-xhttp://127.0.0.1:10240 https://github.com-I检查 sshd 转发能力sshd-T|grep-Eiallowtcpforwarding|permitopen|allowstreamlocalforwarding|gatewayports12. 安全注意事项只上传公钥id_rsa.pub不要上传私钥id_rsa推荐远程转发只绑定远端本机RemoteForward 127.0.0.1:10240 127.0.0.1:7897不建议随意开放到内网RemoteForward 0.0.0.0:10240 127.0.0.1:7897因为这会把代理暴露给远端内网其他机器并且需要远端 sshd 允许GatewayPorts yes或GatewayPorts clientspecified13. 最终推荐工作流VS Code 远程开发连接普通 Hostbms-25 192.168.206.112 192.168.206.140_jgy不要用 VS Code 连接bms-25-proxy 192.168.206.112-proxy 192.168.206.140_jgy-proxy代理隧道用 PowerShell 单独启动ssh bms-25-proxy或后台启动Start-Process-WindowStyle Hidden-FilePathssh.exe-ArgumentListbms-25-proxy远端使用代理exporthttp_proxyhttp://127.0.0.1:10240exporthttps_proxyhttp://127.0.0.1:10240curlhttps://github.com-I14. 核心结论1. 公钥放在哪里取决于你登录哪个远端用户。 2. Windows 本地只保留私钥 id_rsa服务器只放公钥 id_rsa.pub。 3. ProxyJump 失败时可以用 ProxyCommand nc 代替。 4. VS Code Remote-SSH 需要目标机允许 AllowTcpForwarding yes。 5. 远程代理转发使用 -R / RemoteForward。 6. 不建议把 RemoteForward 直接写进 VS Code 使用的普通 Host。 7. 最稳方案是普通 Host 用于 VS Code-proxy Host 用于代理隧道。 8. ServerAliveInterval / ServerAliveCountMax / TCPKeepAlive 用于检测坏连接但不会自动重连。