使用 Ssh 命令建立网络隧道

0X00 前言 & 简介

说起来但凡各位用过 Linux 就应该用过 ssh 了吧,所以怎么使用 ssh 去连接一台服务器、怎么去配置 key 登陆而非密码、怎么允许/禁止 root 用户使用这种问题就不再过多讨论了,这篇文章来介绍一下 ssh隧道 这个东西。

说起来各位在生活工作中肯定遇到过这么一个情况,如图所示:我(A)自己想要访问一台机器(C)但是A和C是不通的,这时候有一台中间的机器(B),A可以访问到B且B和C也是通的(比如说梯子的应用场景)。r当然了你在中间的B机器上开一个 OpenVPN 肯定是可行的,但是一旦你的A连上了 VPN 之后所有流量也就都从B上走了,绝大多数情况下我们其实并不是很需要一个 VPN 而是需要一个轻量化的解决方案。这时候 ssh 隧道就是我们的一个很好的比较轻量化的解决方案,首先它不需要你在客户端和服务器上安装额外的软件(如果你连 ssh 都没装那就不说了);其次它不需要配置文件,为数不多的配置直接写在命令行里;最后它不需要额外的守护进程,你不用了就直接 Ctrl + C 干掉当前进程就行了。

ssh-tunnel

ssh 隧道其实本质上来说就是转发,那我们来依次介绍一下这四种隧道(转发)方法

0X01 动态转发

动态转发是在本地建立一个通往另一台机器的隧道,然后网络监听在本地的某端口,使用 socks5 协议。使用对应的协议和端口的出口流量都会被转发到另一台机器,再由它访问后转发给你。比如你在墙内是无法访问 wikipedia 的,但是你“恰好”有一台在海外的服务器,那么你就可以通过这种方式建立一个简单且临时的小梯子。

命令格式是:ssh -D local-port username@tunnel-host -N,比如说 ssh -D 1080 shawn@123.1.2.3 -N

-D 是绑定后面的本地端口
-N 是说非交互环境,不需要执行命令,挂着就好

这样一来就可以在浏览器上配置代理了,配上 socks5://127.0.0.1:1080 之后就可以访问更广阔的互联网了 YOU ARE FREEDOM !!!

这种动态转发其实平时用到的机会并没有很多,因为开发过程中用代理还是比较麻烦的,并不是所有软件/工具都支持独立配置代理,直接配置在浏览器或者操作系统上的话又很容易误伤到其他的进程。如果想要更细致的管理还是需要用下面的本地和远程转发方案。

0X02 本地转发

本地转发也是在本地建立隧道,监听在本地端口,一切发往本地该端口的流量都会根据配置转发到另一台机器上。比如我前几天工作中遇到的一个情景:开发机是 macOS 的,客户用来联调的服务器在他们内网需要 VPN 才行,但是他们用的 VPN 客户端没有 macOS的。所以我在 macOS 上装了个虚拟机,虚拟机起连上了他们的 VPN 也就可以访问联调环境了,但是我的 macOS 还是不能直接访问。这时候就可以用 ssh 隧道来解决问题了。

命令格式是:ssh -L local-port:target-host:target-port username@tunnel-host,比如说 ssh -L 8080:123.123.123.123:80 shawn@123.1.2.3

-L 指的是建立一条本地隧道 local

这样一来我再curl -XGET http://127.0.0.1:8080的时候,流量就会顺着 ssh 的隧道一路直接到最终客户的联调环境了。这种本地转发的情况是非常常用的,这样一来本来没有通的两个机器也就通过这样一条隧道连接起来了。最重要的是我们只占用了本地机器的一个端口,并不影响其他任何的系统配置和任何进程。

0X03 远程转发

远程转发是在中转的服务器上建立隧道,跟本地转发最大的不同是:本地转发只是本地用户自己建立了一条隧道给自己用,但是远程转发可以将端口共享出来给多台设备使用。还是说上面我的那个联调环境,如果说只有我一个人自己联调就用本地转发是刚刚好的,而且不用再登录到远程环境上去,也不需要远程用户比较高的权限。但是说如果我们全公司都在进行这个联调,那就可以用远程转发,在中转服务器上把自己的端口开放出来让所有用户一起使用。

命令格式是:ssh -R local-port:target-host:target-port -N local,例如 ssh -R 8080:123.123.123.123:80 -N local

-R 建立一条远程隧道 remote

这样建立起来的隧道就可以给其他机器使用了,现在所有可以访问中转机的机器都可以通过中转机的 8080 端口访问到客户的联调机。所以说这里的远程转发和本地转发除了命令执行地不同、可用的机器不同以外就没有什么比较大的区别了。

0X04 其它参数

这里再介绍几个额外的参数

-f 后台运行,这样 ssh 隧道就不用占用你当前的 shell 了
-C 压缩内容,原则上就是用 CPU 换带宽
-g 开放本地端口,如果本地转发的时候加了这个参数,那就跟远程转发差不多了