作为程序员经常会有需要访问某个局域网内的某台机器的需求,例如帮别人调试某个程序,或者远程操作家里的电脑。

之前是使用向日葵 VPN 和 Teamview 的方式在家里通过 ssh 访问公司内网的台式机,速度不是很理想。后来发现 SSH 端口转发可以实现类似的功能,走自己的服务器,果断尝试,这种连接方式的速度非常快,开发效率提高很多。

  • 一台公司和家里都能访问的具有公网 IP 的机器 B,IP 假设为 11.11.11.11
  • 家里的笔记本 C

在机器 A 上执行下面的命令

ssh -oPort=22 -CNfg -R 40000:localhost:22 root@11.11.11.11

-oPort 是指定用于连接 11.11.11.11 的 SSH 的端口。 -C 要求进行数据压缩。 -N 不执行远程命令,用于转发端口。 -f 要求在执行命令前退至后台. 它用于当准备询问口令或密语, 但是用户希望它在后台进行。该选项隐含了 -n 选项。 -g 允许远端主机连接本地转发的端口。 40000 有公网 IP 的机器绑定的端口,该端口的流量会被转发到指定的 Local IP 和 Port。 localhost:22 需要转发的本地 IP 和端口,localhost 可以为 A 机器可访问到的其他机器的 IP 地址。

这样在家里的笔记本 C 通过 SSH 登录 11.11.11.11 主机 B,再通过 ssh 连接本地的 40000 端口,这时候就相当于是连接到了内网的机器 A 的 22 端口,就实现了远程 SSH 连接内网的台式机。

注:需要注意的是如果连接空闲一段时间的话,可能就会断开。

解决空闲连接断开的问题

修改客户端配置

  • 找到所在用户的 .ssh 目录,如 root 用户该目录在:/root/.ssh/
  • 在该目录创建 config 文件 touch /root/.ssh/config
  • 加入下面一句:ServerAliveInterval 60
  • 保存退出,重新开启 root 用户的 shell,则再 ssh 远程服务器的时候,不会因为长时间没有操作而断开。应该是加入这句之后,ssh 客户端会每隔一段时间自动与 ssh 服务器通信一次,保持心跳。

修改服务器端配置

通过修改 /etc/ssh/sshd_config 中的配置解决自动断开的问题。下面是要修改的两个配置项的含义:

ClientAliveInterval 指定了服务器端向客户端请求消息的时间间隔, 默认是 0, 不发送。而 ClientAliveInterval 60 表示每分钟发送一次,然后客户端响应,这样就保持长连接了。这里比较怪的地方是:不是客户端主动发起保持连接的请求(如FTerm, CTerm等),而是需要服务器先主动。 至于 ClientAliveCountMax,使用默认值 3 即可。ClientAliveCountMax 表示服务器发出请求后客户端没有响应的次数达到一定值, 就自动断开。