ssh本地端口转发,远程端口转发,隧道(这个解释不饶) 您所在的位置:网站首页 怎么打开网关 ssh本地端口转发,远程端口转发,隧道(这个解释不饶)

ssh本地端口转发,远程端口转发,隧道(这个解释不饶)

2023-09-21 13:17| 来源: 网络整理| 查看: 265

目录

创建隧道时的常用选项

本地端口转发

命令

原理

远程转发

命令

原理

隧道

命令

创建隧道时的常用选项

“-L选项”:表示使用本地端口转发创建ssh隧道

“-R选项”:表示使用远程端口转发创建ssh隧道

“-N选项”: 表示创建隧道以后不连接到sshServer端,通常与”-f”选项连用

“-f选项”:表示在后台运行ssh隧道,通常与”-N”选项连用

“-g选项”:表示ssh隧道对应的转发端口将监听在主机的所有IP中,不使用”-g选项”时,转发端口默认只监听在主机的本地回环地址中,”-g”表示开启网关模式,远程端口转发中,无法开启网关功能。

本地端口转发 命令

# 所有访问本机9090端口都会访问172.16.12.131上的3306

ssh -fCNg -L 9090:172.16.12.131:3306 [email protected] # 所有访问本机9090端口都会访问172.16.12.131上的3306 原理

首选,将实验环境准备好,两台主机的信息如下

ServerA:10.1.0.1ServerB:10.1.0.2

ServerA中并不存在mysql服务。

ServerB中已经安装了mysql服务,mysql服务已经启动并监听了3306端口。

现在,我们只要在ServerA中执行如下命令,即可在ServerA与ServerB之间建立一条ssh隧道,执行如下命令时会提示输入ServerB的密码

如上图所示,执行上图中的命令后,我们直接从主机A连接到了主机B,这条连接就是我们创建的”ssh隧道”。

我们先来简单的解释一下上图中命令的含义,为了方便解释,我们把命令分成3部分理解,如下图所示。

第1部分为-L选项,-L 选项表示使用”本地转发”建立ssh隧道,本地转发是什么意思呢?

“本地转发”表示本地的某个端口上的通讯数据会被转发到目标主机的对应端口,你可以把它抽象的理解成一种”映射”,注意,我们把执行上述命令的主机称为”本地主机”。

比如,访问本地(当前主机)的端口A,就相当于访问目标主机的端口B,因为当你访问本地的端口A时,通讯数据会被转发到目标主机的端口B,这就是本地转发,其实,”本地转发”是与”远程转发”相对应的,但是我们还没有介绍到远程转发,所以并不用在意那么多,我们只要先了解本地转发的作用就行了。

刚才说过,”本地转发”表示本地的某个端口上的通讯数据会被转发到目标主机的对应端口,那么你一定能够理解上述命令中第2部分的含义了

第2部分表示:通讯数据会从本地的9906端口上被转发,最终被转发到10.1.0.2的3306端口。

第3部分表示:我们创建的ssh隧道是连接到10.1.0.2上的root用户的,其实,第3部分可以与之前的ssh连在一起去理解,比如,ssh [email protected],其实就是使用ssh命令从ServerA中连接到ServerB的root用户,这就是为什么执行上述命令以后,会提示我们输入10.1.0.2中root用户的密码,当然,如果你已经在ServerB中配置好了ServerA对应用户的公钥,那么则可以省去输入密码的步骤直接连接,此时,ServerA的角色是ssh的客户端,ServerB的角色是ssh的服务端,而这条ssh隧道就是建立在ServerA与ServerB之间的。

了解完上述命令的3个部分,我们来把它当做一个整体去理解一下

ssh -L 9906:10.1.0.2:3306 [email protected]

上述命令表示从本机(ServerA)建立一个到ServerB(10.1.0.2)的ssh隧道,使用本地端口转发模式,监听ServerA本地的9906端口,访问本机的9906端口时,通讯数据将会被转发到ServerB(10.1.0.2)的3306端口。

好了,命令解释完了,现在我们来试试实际的使用效果,注意,此刻我们已经创建了ssh隧道,从serverA中已经连接到了ServerB,不要退出这个ssh连接,否则刚才创建的ssh隧道将会消失(稍后会介绍怎样后台建立连接),此刻,我们再打开一个新的ssh连接,连接到ServerA,如下图所示

在新链接中查看对应的端口号,本地回环地址的9906端口已经被监听了(稍后介绍怎样监听ServerA中指定的IP,即非本地回环地址)。

此时,我们直接在ServerA中通过mysql命令访问127.0.0.1的9906端口,就相当于访问ServerB的mysql服务了,我们来试试。

执行mysql命令时需要指定IP与端口号,因为我的ServerB中的mysql只是用于测试,所以没有为用户设置密码,如下图即可连接

如上图所示,已经可以正常在ServerA中连接到数据库,但是连接的数据库其实是ServerB中的mysql服务。

这就是通过ssh隧道访问远程主机的mysql服务的示例,这样做就是利用ssh的安全特性加密了mysql的通讯数据。

在没有使用ssh隧道时,直接从ServerA跨越公网访问ServerB的mysql服务时,如果在ServerB中通过抓包工具对通讯网卡进行抓包,可以直接从抓到的数据包中看到mysql的传输数据。

但是如果使用了ssh隧道,并且在ServerB中仅对通讯网卡进行抓包时,则只能看到经过加密的ssh数据包,此时,如果对ServerB的本地回环网卡同时进行抓包,则可以看到未加密的mysql传输数据,不过,这并不影响mysql通讯数据跨越公网时的安全性,因为这时已经是ServerB本机中的数据传输了,也就是说,mysql通讯数据在跨越公网时,是经过ssh隧道加密的,mysql通讯数据到达ServerB本机以后,是明文传输的。

不过,当我们执行上述命令创建ssh隧道时,总会从ServerA中连接到ServerB中,而通常,我们只希望建立ssh隧道,并不会使用到这个新建立的ssh连接,而且在实际使用中,我们往往会在建立隧道以后,退出当前的ssh会话,所以,上述命令并不能满足我们的需求,因为,我们一旦退出对应的ssh会话,相应的ssh隧道也会消失,所以,我们还需要配合另外两个选项,”-N选项”与”-f选项”,我们一一道来。

首先来试试”-N选项”,当配合此选项创建ssh隧道时,并不会打开远程shell连接到目标主机,我们来试试,如下图所示,配合-N选项创建隧道,输入ServerB的密码以后,并没有连接到ServerB,而是停留在了如下图的位置

此时,再打开一个新的ssh会话连接到ServerA,可以看到,9906端口已经被监听。

但是,这样仍然不能满足我们的要求,虽然建立隧道时并没有连接到ServerB,但是,我们仍然不能关闭创建ssh隧道时所使用的ssh会话。

这时,只要配合”-f”选项即可,”-f”选项表示后台运行ssh隧道,即使我们关闭了创建隧道时所使用的ssh会话,对应的ssh隧道也不会消失,”-f”选项需要跟”-N”选项配合使用,所以通常,我们会使用如下命令创建ssh隧道

ssh -f -N -L 9906:10.1.0.2:3306 [email protected]

配合上述选项创建ssh隧道时,即使我们完全关闭了执行命令时的ssh会话,对应创建的隧道也可以完全正常运行。

不过,当我们使用上述命令建立隧道时,只有127.0.0.1这个回环地址的9906端口会被监听,这样就会出现一个小问题,也就是说,我们只能在ServerA本机上访问9906端口,并不能通过其他主机访问ServerA的9906端口,因为ServerA其他IP的9906端口并未被监听,那么怎么办呢?很简单,使用如下命令,即可让9906端口监听在ServerA中指定的IP上

ssh -f -N -L 10.1.0.1:9906:10.1.0.2:3306 [email protected]

在ServerA中执行上述命令时,ServerA的10.1.0.1的9906端口会被监听,此刻,我们可以通过其他主机访问10.1.0.1的9906端口,即可访问到ServerB中的mysql服务,其实,与之前的命令相比,只是在9906前增加了ServerA中对应的IP地址罢了,很简单吧。

如果你觉得这还不够,希望ServerA中的所有IP地址的9906端口都被监听,那么可以在建立隧道时开启”网关功能”,使用”-g”选项可以开启”网关功能”,开启网关功能以后,ServerA中的所有IP都会监听对应端口,示例如下

好了,说了这么多,终于把ssh隧道(本地转发)给解释明白了,不过,我们也只是说明了本地转发,现在,我们来聊聊远程转发。 

远程转发 命令

公司内部

# 开启web服务:python -m SimpleHTTPServer 80

ssh -fCNg -R 9002:172.16.12.131:80 [email protected] # 开启web服务:python -m SimpleHTTPServer 80

公司外部

# 缺点,只能在131机器上访问127.0.0.1,需要在公网IP上再建立一层端口转发

ss -pantulo|grep 9002 访问 curl http://127.0.0.1:9002 # 缺点,只能在131机器上访问127.0.0.1 原理

在了解远程转发之前,请先确定你已经理解了”本地转发”。

老规矩,为了方便理解,我们先来描述一个场景。

公司有一台服务器ServerB,ServerB处于公司的内网中,公司内网中的所有主机都通过路由器访问互联网(典型的NAT网络),ServerB中有提供mysql服务,如果此时,我们想要通过外网访问到ServerB中的mysql服务,该怎么办呢?通常的做法是,通过路由器或者防火墙,将公司的固定外网IP上的某个端口映射到ServerB内网IP的3306端口上,这样,我们只要访问公司外网IP的对应端口,即可访问到内网ServerB中的mysql服务了,但是,如果你没有权限控制公司的防火墙或者路由器呢,这时该怎么办呢?

假设,你无法控制防火墙去进行端口映射,但是,公司在公网上有另外一台服务器ServerA,ServerA有自己的公网IP,你有权控制ServerA,这时,我们就可以利用ServerA达到我们的目的,聪明如你,一定想到了解决方案,没错,我们可以在ServerA与ServerB之间创建一条SSH隧道,利用这条隧道将ServerA中的某个端口(假设仍然使用9906端口)与ServerB中的3306端口连接起来,这样,当我们访问ServerA的9906端口时,就相当于访问到内网ServerB中的mysql服务了,那么,我们能不能使用之前的”本地转发”的方式,在ServerA中创建SSH隧道呢?我们来模拟一下,看看会不会遇到什么问题,如果想要使用之前的命令创建SSH隧道,那么我们则需要在ServerA中执行如下命令。

ssh -f -N -L AIP:9906:BIP:3306 root@BIP

问题来了,ServerA有自己的公网IP,我们只要把上述命令中的AIP替换成ServerA的公网IP即可,但是ServerB是内网主机,虽然ServerB能够通过公司内的路由器访问到互联网,但是ServerB并不持有任何公网IP,ServerB只有内网IP,所以,我们并不可能把上述命令中的BIP替换成B主机的内网IP,所以,使用上述命令是无法在ServerA中创建ssh隧道连接到ServerB的,那么该怎么办呢?

虽然我们无法从ServerA中使用ssh命令连接到ServerB,但是,我们可以从ServerB中使用ssh命令连接到ServerA啊,虽然ServerB是没有公网IP的内网主机,但是它仍然可以依靠公司的路由器访问互联网,所以,我们只要在ServerB中执行如下命令,即可从ServerB中连接到ServerA中。

ssh root@AIP

那么,按照这个思路,我们似乎找到了方向,我们现在需要一种方法,能够从ServerB中创建SSH隧道连接到ServerA,并且,隧道创建后,ServerA中会监听9906端口,以便别人能够通过外网访问,也就是说,我们需要一种方法,能够满足如下两个条件

条件1:从ServerB中主动连接到ServerA,即在ServerB中执行创建隧道的命令,连接到ServerA。条件2:隧道创建后,转发端口需要监听在ServerA中,以便利用ServerA访问到内网的ServerB。

这种方法就是”远程转发”。

你可能还是不太明白,没有关系,我们先来实际动手操作一下,稍后,我们会对比本地转发与远程转发的具体区别。

为了方便,我们仍然使用之前的实验环境,假设ServerA是外网主机,ServerB是内网主机,ServerA的IP为10.1.0.1(假设此IP为公网IP),ServerB的IP为10.1.0.2,并且已经将之前本地转发的进程关闭,相当于一个没有任何隧道的新的实验环境。

使用”-R选项”,可以创建一个”远程转发”模式的ssh隧道,我们在ServerB中,执行如下命令即可

上述命令在ServerB中执行,执行后,即可在ServerA与ServerB之间建立ssh隧道,此时,ServerB是ssh客户端,ServerA是ssh服务端,隧道建立后,ServerA中的9906端口会被监听,在ServerA中查看对应端口,如下图所示从图中可以看出,ServerA中的9906端口已经被监听,此刻,我们通过外网IP登录到ServerA,在ServerA中访问本地回环地址的9906端口,即可访问到内网ServerB中的mysql服务,如下图所示。

不过你肯定注意到了,当使用远程转发的命令时,我并没有指定监听ServerA的外网IP,也没有使用”-g选项”开启网关功能,这是因为,即使你在命令中指定了IP地址,最终在ServerA中还是会只监听127.0.0.1的9906端口,你可以在ServerB中尝试一下如下命令

ssh -f -N -R 10.1.0.1:9906:10.1.0.2:3306 [email protected]

即使在ServerB中执行上述命令时指定了IP或者开启了网关功能,ServerA的9906端口仍然只监听在127.0.0.1上,当然,如果你一心想要通过别的主机访问ServerA的9906端口,也可以使用其他程序去反代ServerA的9906端口,还有,我在实际的使用过程中,如果使用远程转发穿透到内网,ssh隧道将会非常不稳定,隧道会莫名其妙的消失或者失效,特别是在没有固定IP的网络内,网上有些朋友提供了autossh的解决方案,不过我并没有尝试过,如果你有兴趣,可以试一试。

隧道 命令 ssh -fCNg -D 127.0.0.1:6060 [email protected]

配置代理

socks5 127.0.0.1 6060

注:如果使用nmap扫描要用 sT 参数完成三次握手,否则数据不准确



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有