< 返回博客

ssh端口转发


  上次在第一篇文章中介绍了内网穿透的原理以及实现,用的是frp这个神器。但是其实如果只是为了ssh登录到内网机器上,就没有必要这么大动干戈了,使用Linux的必备工具----SSH,就可以做到内网穿透。接下来就介绍一下基础用法。

  关于ssh在这里就不赘述了,不了解的朋友看这里维基百科:Secure Shell

本地端口转发

直接在这里说用法吧。

ssh -L bindport:host2:port2 host1

这个命令相当于干了两件事。第一,告诉自己所在的主机:localhost,听好了,以后发给你bindport端口的数据,都给我发过来。第二,告诉host1:之后我通过这个连接给你发过去的数据,统统不要过问,直接发给host2:port2,听到了么?

这么说大家能听懂吧。

下面是正经一点的解释:

执行这个命令之后,所有发往本地bindport端口的数据,都会被转发给host1,然后由host1发送到host2的port2端口。其实可以这样理解:bindport是唯一一个关于本地的量,用来指定本地ssh要监听的端口;这行命令的主体,其实是ssh host1,所以我们连接上的,是host1这台主机,剩下的host2:port2会连同我们发送的数据一起发送给host1,host1看到后,会直接转发给host2的port2端口。

下面是个例子:

ssh -L 8000:localhost:22 user@1.1.1.1

成功执行这行命令后,如果在本地机上ssh -p 8000 user@localhost,就可以登录到1.1.1.1。

这里要注意的两点:一是localhost是对于1.1.1.1主机来说的,而不是本地的localhost;二是指定的8000端口是本地端口,要想让远程主机可以连接8000端口的话,可以指定-g选项。

上面的命令等价于ssh -L 8000:1.1.1.1:22 localhost,原因你自己分析一下吧。

sudo ssh -gNTL 10000:localhost:80 localhost

这里-N 和-T选项是不分配shell来登录和执行命令的意思

如果在http web服务器上执行这个命令,就可以通过10000端口访问提供的网页,而不是默认的80端口。这个例子没有什么实际意义,本地端口转发一般是用来突破服务器对连接机的限制,比如服务器只允许指定的主机连接。IBM的这篇文章就是关于,而且人家讲的也比我好,可以看看这个。

远程端口转发

从上面的例子可以看出,本地端口转发是需要转发的目标机器可以直接连接上被转发的端口的,但是如果我们要做内网穿透的话,公网机器是无法主动向内网机发起连接的,我们需要内网机器主动发起连接并保持,这就是远程端口转发。

先看下命令

ssh -NTR port1:host2:port2 host1

这行命令告诉host1:host1!以后啊,如果你见到发送到你port1端口的数据,你就不要管,直接扔给host2:port2,知道了吗?

这就相当于在host1和host2之间开启了一个隧道,所以远程端口转发也被称为ssh隧道。

和本地转发不同,这里的host2如果指定成localhost的话,是对于本机来说的,这样用处就体现出来了。看下面的例子,在内网机器上执行:

ssh -NTR 8000:localhost:22 1.1.1.1

其中1.1.1.1是公网的跳板机。

照着上面的翻译一下:以后发送给1.1.1.1:8000的数据,都发给我(本地localhost)的22端口。

如果我们在另一台主机上执行ssh -p 8000 1.1.1.1就可以登录到内网机器了。

这里需要注意的是,1.1.1.1的8000端口一般默认开放的是本地端口,想要对外开放的话,一种方法是在/etc/ssh/sshd_config文件中加入GatewayPorts yes,然后sudo systemctl reload sshd重启sshd;还可以设置为GatewayPorts clientspecified,然后在连接时远程端口前面加上0.0.0.0:ssh -NTR 0.0.0.0:8000:localhost:22 1.1.1.1

是不是很方便,比配置frp方便多了。通过远程转发,可以反向代理到很多的其他服务器,隐藏主机是一方面,更重要的是———所有的连接都是加密的!!

其他技巧

ssh连接经常会由于各种原因断掉,主机重启、网络故障等等,那每次断掉一回,都手动连接一次不合适,也不现实,解决方式是autossh。

关于ssh连接自动断开,有人说ssh连接有空闲连接超时限制,所以才会断掉,但是其实ssh自身是不会主动断开连接的,是防火墙的原因,参考这篇文章Linux使用ssh超时断开连接的真正原因

  • PS: ssh加上-f选项可以指定在后台运行,所以一般配合-fNT使用。但是加上-f就不能输入密码了,要使用密钥登录 *
autossh -M 9000 -NTR 8000:localhost:22 1.1.1.1

autossh在一般的包管理器中都有,直接装上就行。这里的使用方法只是比ssh多了个-M选项,指定用于监测ssh会话的端口。