本文首发于知乎: 大内网战略(3):穿越跳板机SSH连接、VSCode远程开发 - 知乎

封面图:https://www.pixiv.net/artworks/93447255

情景设置

如果 公司/宿舍/家/实验室 内网有台 服务器/开发机之类的玩意,想外网访问,自己对服务器有完整的控制权,那么直接双方按照 大内网战略(1):使用 Tailscale 搭建 VNet – Eterance的小窝 里安装 tailscale完事。

但是更多情况下,出于安全原因,你在服务器没有足够的权限安装应用、修改网络和防火墙(直接击碎试图在服务器安装 Tailscale 的幻想),也不能通过外网直接访问服务器。不过,网络管理员允许你使用跳板机:先连跳板机,再连服务器。一般在此情况下,跳板机是可以被公网连接的。

但是,如果更极端的情况下,跳板机也不能通过外网连接呢?在以下的图片中,情况就变成:跳板机146、服务器236和237都不能被外网连接(他们的IP是内网IP);跳板机146可以访问两台服务器;你没有两台服务器的管理员权限不能安装 tailscale,但是在跳板机上你有完全的权限。(跳板机可以是你py网络管理员开的虚拟机,也可以干脆自己捡垃圾或者用树莓派在内网设置一台24×7开机的物理机)

一般情况下,这种场景的跳板机会安个向日葵,然后自己的电脑控制跳板机连接服务器干活,但这样一般会很卡,而且跳板机性能得给的比较高。但是我们可以用 tailscale 把自己的电脑和跳板机拉进大内网,然后穿透跳板机连接两台服务器(穿透的意思是实际使用中察觉不到跳板机的存在,当它是透明的)。

跳板机的准备工作

以下我们用 Win 作为跳板机系统。如果你的跳板机是 Linux 或者别的,我相信你有举一反三的能力。

安装 Tailscale

如果你的跳板机不能在公网上访问,这一步只能在跳板机所在内网下操作。如果人不在内网环境,可以叫你同事什么的给你安个向日癸,或者帮你做。

首先,按照 大内网战略(1):使用 Tailscale 搭建 VNet – Eterance的小窝 里在跳板机和自己的电脑安装并授权 tailscale。你可以在跳板机上按照 大内网战略(2):文件共享、远程桌面 – Eterance的小窝 搞远程桌面,方便后续操作。

此时,跳板机146可以使用计算机名或者 Tailscale IP 远程访问了。

为跳板机安装 OpenSSH

以下方法只适用于 Windows 10 1809 ,Server 2019及之后的系统。更老的系统要到 https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH-Using-MSI 中下载安装包自行安装。

在跳板机设置上搜索可选功能

跳板机

安装 openssh 服务器组件。一般 openssh 客户端已经安装,如果没有就顺便安装一下。

跳板机

然后搜索服务并打开

跳板机

找到服务“openssh ssh server”并点开,启动类型选择“自动”,并启动服务,点击确定保存。OpenSSH服务会被启动并开机自启。

跳板机

免密登录(强烈推荐)

如果自己已经弄过免密登录就可以跳过。

为自己的电脑生成公钥

先在自己电脑的 C:\Users\用户名\.ssh 文件夹下看看有没有图里的两个文件。

自己的电脑操作

如果没有,或者没有 .ssh 文件夹,说明这台机器还没生成公钥-密钥对,需要生成。方法:搜索并打开 CMD,输入 ssh-keygen -t rsa,然后一路回车。出现框框长得像俄罗斯方块,并且 .ssh 文件夹出现两个文件就是生成成功。(如果已经有了这两个文件,不要重新生成!

实现 自己的电脑->服务器 免密登录

如果已经有了两个 id_rsa 文件或者生成完毕,在 .ssh 文件夹中用记事本打开 id_rsa.pub,全选并复制里面的内容(也就是自己电脑的公钥)

自己的电脑操作

然后在跳板机中开个cmd什么的,ssh上你的服务器(我这里是237),在用户目录下输入 vim .ssh/authorized_keys (没有 vim 自行安装,报错文件找不到就 mkdir .ssh),回车

服务器操作

(记得切换成英文输入法)用键盘方向键把光标拉到最末尾,然后按 i 键进入输入模式,粘贴刚刚复制的 id_rsa.pub 内容,按 esc ,输入 :wq 保存并关闭。

服务器操作,粘贴后应该像这样,我之前已经有好几个公钥在许可文件里了

到这里, 自己的电脑->服务器 免密登录就完成了。如果你有多台内网服务器,自行依葫芦画瓢把自己电脑的公钥粘贴到不同服务器的许可文件里。

实现 自己的电脑->跳板机 免密登录

首先,像上一步那样,在自己的电脑上用记事本打开 id_rsa.pub,全选并复制里面的内容(也就是自己电脑的公钥)

用记事本打开跳板机的 C:\Users\用户名\.ssh\authorized_keys 文件,把自己电脑的公钥粘贴到最后面(记得另开新行),保存并关闭

跳板机操作

然后在跳板机的 C:\ProgramData\ssh\下(首次启动 openssh 服务后会生成该文件夹),打开sshd_config文件,修改文件:

确保以下3条没有被注释
PubkeyAuthentication yes
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication no

确保以下2条有注释掉
#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

保存后,在跳板机的服务面板重启 openssh 服务(如果你不会,重启跳板机也行)。

Xshell 穿越跳板机连接服务器

原始内容来自:使用XShell结合跳板机直接访问内网服务器文件及执行命令 - Joe_du - 博客园

设置跳板机代理会话

在自己电脑的xshell上,新建一个会话,填入名称(自己取个能一眼认出的名字)和主机(跳板机的计算机名,当然你也可以填跳板机的 Tailscale IP)

自己电脑

填上跳板机的用户名。因为之前设置了免密登录,所以接下来要设置密钥。嫌麻烦可以用密码登录,只需要做1 2步,然后在密码中填入跳板机的用户密码。

自己电脑

导入之前生成的密钥(别导入错成公钥了)

选择导入的密钥,点确定

在隧道中添加对服务器的代理。目标主机就是服务器的内网IP,这条规则就是把236服务器的22端口(也就是ssh端口)代理到本机的23622端口。

如果有多台服务器,就依葫芦画瓢添加多条规则。设置完后点击连接,并且不要关闭这个jumper会话。

设置服务器会话

在自己电脑的xshell上,再次新建一个会话。主机填localhost,端口号填映射后的端口号(因为跳板机代理把服务器ssh映射到本地了)

填入服务器上的用户名,并设置密钥文件,然后点击连接。

如果有多台服务器,就新建多个会话。

以后,xshell连接服务器时,都要要先开启跳板机代理会话并不要关闭。

VSCode 穿越跳板机远程开发

首先确保自己电脑的vscode上安装了远程开发的扩展

点击远程连接,选择 config 文件打开

添加图片注释,不超过 140 字(可选)

在config文件中添加:

Host JumpMachine
  HostName 跳板机计算机名或者IP
  Port 22
  User 跳板机用户名

Host 237服务器
  HostName 服务器IP
  Port 22
  User 服务器用户名
  ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -W %h:%p JumpMachine

有多台服务器就添加多个 host,如下图。添加完保存关闭

然后你就可以vscode穿越跳板机在服务器上远程开发了。