使用SSH实现内网穿透

参考

前言

这两天又要做微信公众号开发,之前为了方便测试,用了内网穿透工具Ngrok,前一段调研加密代理时了解到SSH也可以做内网穿透,因此特意研究了一下具体流程,这里记录一下。

服务器配置

是的,虽然是内网穿透,但你需要一台有公网IP的服务器用来做转发,临时用的话,可以考虑用阿里的抢占式实例,具体请看上面的参考3

  • 首先需要确保服务器的映射端口是可以访问的。确保本机的防火墙里打开了该端口。如果是阿里云,那就要修改ECS实例的安全组添加规则。
  • 服务端的sshd后台服务默认是不允许远程主机连接本地的转发端口的,因此需要修改sshd配置文件:
    编辑/etc/ssh/sshd_config,找到GatewayPorts配置项,默认是注释起来的,取消注释,并把后面的值改成clientspecified
  • 重启sshd:systemctl restart sshd

客户端配置

  • 客户端需要有SSH。Windows 10里面已经自带了OpenSSH,可以直接使用,可以在命令行窗口里运行ssh验证一下
  • 如果客户端没有,可以用Cygwin安装,或者Windows版的Git等工具里也自带
  • 打开命令行窗口执行如下命令:
    ssh -fCNR 0.0.0.0:<远程映射端口>:localhost:<本地监听端口> root@<远程主机>

    1. 执行此命令后需要手动输入远程服务器上root用户的密码
    2. 注意这里的0.0.0.0不能省略,否则服务端的映射端口只允许本机访问
    3. <本地监听端口>就是内网主机的本地服务所监听的端口,比如80,用这个命令可以把公网服务器的<远程映射端口>监听到的请求转发到本地服务上
  • 如何断开内网映射:

    1. 简单点直接执行taskkill /im ssh.exe /f即可杀掉所有ssh进程
    2. 如果怕误杀,可以用wmic process where "name='ssh.exe'" get commandline,processid来查询所有的ssh.exe进程,根据启动命令行找到对应的进程号,然后用taskkill /pid <进程ID> /f来点杀进程
  • 通常杀掉内网机器上的ssh进程,也会自动结束服务器上对应的sshd进程,如果没有,则需要在服务器上手动清理

    1. 在服务器上执行netstat -antp | grep <远程映射端口>即可找到对应的sshd进程,然后用kill -9 <PID>点杀之

保持连接

用SSH实现的内网穿透长时间没有数据传输会断掉,需要进行一些配置,让客户端和服务端保持连接。几个方案:

  • 安装autossh,这个软件能够自动重连
  • 让SSH客户端定时发送消息保持连接

    1. 永久方案:修改SSH客户端配置文件。在Windows上,这个文件位于<用户目录>\.ssh\config,默认是没有这个配置文件的,需要手动创建一个。内容如下:
    Host *
      ServerAliveInterval 240  
    1. 一次性方案:启动SSH客户端时添加参数:-o ServerAliveInterval=240
  • 让SSH服务端定时发送消息保持连接
    修改/etc/ssh/sshd_config,添加下面两行:

    ServerAliveInterval 30
    ServerAliveCountMax 60

SSH免登录

请参见文首的参考4

阅读 2k

推荐阅读
玩儿编程
用户专栏

编程也是可以玩儿的!微信公众号“玩儿编程”

62 人关注
33 篇文章
专栏主页