ssh端口转发实例

案例1

在SoftLayer里的一台机器 10.121.196.144 需要访问github,但是无法直接访问。

网络连通性如下:

github <== SVL SDS server ==> SL jumper ==> 10.121.196.144

由于SDS server能连通github,所以可以借助SDS serverSL jumper,从而让 10.121.196.144 能够连通github。

 

具体实现如下:

SL jumper上:

ssh -qTfnN -R 60000:localhost:60000 idcuser@10.121.196.144

这条命令表示,建立一个ssh远程转发,把发到 10.121.196.144 的60000端口的请求,转发到localhost的60000端口。

注意,这里的localhost,实际上指的是SL jumper

 

注:远程转发(-R)与本地转发(-L)的区别:

ssh连接分为client和server,建立的tunnel也分client和server,如果希望二者方向是一致的,就用Local;如果相反,就用remote。

本例中,ssh client是SL jumper,ssh server是10.121.196.144,而想要建立的tunnel,是反过来的,从10.121.196.144SL jumper,所以用remote。

如果想用local,则应以10.121.196.144为ssh client。但是,从10.121.196.144无法ssh到SL jumper,所以只能把SL jumper作为ssh client,并用remote。

 

不管是-L还是-R,后面的<port1> : <host> : <port2>里面:

  • port1:都是tunnel client的端口;
  • port2:都是目的地的端口;
  • host:转发的目的地。如果是localhost,都是指tunnel server本身(因为也可以转发到其它机器上去);

也就是说,这个ssh tunnel,会把tunnel client的指定端口的请求,转发到“host”(可以是tunnel server,也可以是tunnel server能够access的其它机器)的指定端口。

注意,这个tunnel里指定了tunnel client的端口,但并没有指定tunnel server的端口。

 

接下来,因为SL jumper无法ssh到SDS server,所以同理,要从SDS server上建立一个反向tunnel。

SDS server上:

ssh -qTfnN -R 60000:github.rtp.raleigh.ibm.com:22 sljump

可见,这是一个remote转发,会把发到SL jumper的60000端口的请求,转发到github的22端口。

注意:这里tunnel server不是localhost(指的是SDS server),而是github。

当然,ssh tunnel只是从SL jumperSDS server,从后面从SDS server到github,并不是ssh,而是tunnel client本身的请求而定。ssh tunnel只是代理了从tunnel client到tunnel server这一段。

 

实现效果:

现在,在10.121.196.144上,可以把localhost的60000端口视为github的22端口,即可以通过ssh方式访问了:

[idcuser@cdsmon-wei-01 cdsmon-e2e]$ git remote -v
origin    ssh://git@localhost:60000/cds-delivery/cdsmon-e2e.git (fetch)
origin    ssh://git@localhost:60000/cds-delivery/cdsmon-e2e.git (push)

 

我觉得不管用local还是remote方式,都是实现了一个反向代理。

  • 所谓正向代理,proxy代理的是client。client知道自己被代理,client把请求通过proxy发送到server,server只知道proxy不知道client;
  • 所谓反向代理,proxy代理的是server。client只知道proxy不知道server,client把请求发给proxy,proxy再转发给server;

对于SSL tunnel,不管用local还是remote方式创建,最终都是实现了从tunnel client访问localhost的某端口时,转发到了指定的server和端口,显然代理的是server。因此,这是一个反向代理。

 

案例2

有些网站无法直接访问。

既然SDS server可以访问,就可以建立ssh tunnel,实现一个正向代理(这回又变成正向了。。。)。

以我的Mac为例,网络连通性如下:

Mac ==> SDS server ==> 网站

可以利用Mac 到 SDS server 的连通性,建立一个动态转发(-D)。

在Mac上:

ssh -o ExitOnForwardFailure=yes -qTfN -D 8888 kaiding@sdsvm902066.svl.ibm.com

该命令在本地建立了一个SOCKS代理服务,当有请求连接到该端口(本例中是8888)时,就会转发到remote server(本例中是 sdsvm902066.svl.ibm.com )。然后从remote server,那个请求本身再被用起来(比如请求的服务器地址、端口、协议等)。

说白了就是建立了一个正向代理(SOCKS代理)。在浏览器里设置好该代理,就能访问网站了。

比如我的Mac的Chrome浏览器,使用了SwitchyOmega插件,其设置的代理为SOCKS 5,server是127.0.0.1,端口是8888。

Firefox浏览器的代理设置如下图所示:

注:如果希望使用代理服务器的DNS,则需勾选“Proxy DNS when using SOCKS v5”选项。

 

案例3

想要在Mac上访问http://10.xx.xx.xx的URL。该案例和案例2非常类似,唯一不同是中间多了一层。网络连通性如下:

Mac ==> SDS server ==> sljumper ==> 10.xx.xx.xx

首先,在SDS server上建立一个到SL jumper的动态转发。

ssh -o ExitOnForwardFailure=yes -qTfnN -D 6666 sl

然后,在Mac上建立一个到SDS server的local tunnel。

ssh -o ExitOnForwardFailure=yes -qTfnN -L 6666:localhost:6666 sdsvm902066.svl.ibm.com

最后在浏览器里设置代理为 localhost:6666 即可。

 

注:本来我想,不需要第2步了,直接在浏览器里面,设置代理为sdsvm902066.svl.ibm.com:6666不就行了吗。

但是这个方法不可行,因为在Mac上SDS server的6666端口nc不通(在SDS server上可以nc通本地的6666端口)。

➜  ~ nc -zv sdsvm902066.svl.ibm.com 6666
nc: connectx to sdsvm902066.svl.ibm.com port 6666 (tcp) failed: Connection refused

但这并不是防火墙的问题,因为我在SDS server上用nodejs起一个HTTP server,比如起到3000端口,则在Mac上也能ncSDS server的3000端口。但是若把ssh tunnel开在3000端口,则在Mac上就nc不通了。

所以,只好用第2步,在本地和SDS server之间建立一个tunnel,然后把代理设置成本地。

 

注:对这个案例,如果不用浏览器代理,也不用动态转发,也有一个笨办法。假设要访问的URL是http://10.107.28.250:8080/seyren

首先在SDS server上:

ssh -qTfnN -L 7777:10.107.28.250:8080 sl

即:把访问SDS server的7777端口的请求,通过tunnel,转发到10.107.28.250的8080端口上来;

然后在Mac上:

ssh -qTfnN -L 7777:localhost:7777 sdsvm902066.svl.ibm.com

即:把访问Mac的7777端口的请求,通过tunnel,转发到SDS server(即上面的localhost)的7777端口上来;

现在,只需打开浏览器,访问 http://localhost:7777/seyren ,就相当于在SL jumper上访问 http://10.107.28.250:8080/seyren 了。

但是这个方法不具有通用性,对每个URL都要维护2个tunnel和1个端口。

 

案例4

有些网站在家庭的台式机上无法访问。

解决办法跟案例3非常相似。前提是Mac也处于家庭局域网,并且通过VPN连接到公司内网。网络连通性如下:

台式机 ==> Mac ==> SDS server ==> 网站

首先,在Mac上建立一个到SDS server的动态转发:

ssh -o ExitOnForwardFailure=yes -qTfN -D 8888 kaiding@sdsvm902066.svl.ibm.com

此时,在Mac的浏览器里面设置代理为localhost:8888,就可以在Mac上访问网站了。这其实就是案例2的解决办法。

然后,在台式机上建立一个到Mac的local tunnel:

ssh -o ExitOnForwardFailure=yes -qTfnN -L 8888:localhost:8888 kaiding@192.168.1.8

  • 注:192.168.1.8是Mac在局域网的IP地址。
  • 注:台式机如果是Win10,则需要一个能运行ssh的工具,比如 Git Bash 。

最后,在台式机的浏览器里设置代理为 localhost:8888 即可。

注:如果希望使用代理服务器的DNS,则需勾选“Proxy DNS when using SOCKS v5”选项。

另外,对于Win10里面的的VMware虚拟机(我用的是Ubuntu),也能通过这个方法访问那些网站。我使用的网络是桥接方式,所以相当于VM也是在同一个局域网内的,其IP地址是 192.168.1.56 。(BTW:Win10的IP地址是 192.168.1.9 )

 

参考

  • https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/
  • https://w3-connections.ibm.com/wikis/home?lang=en-us#!/wiki/Wffbb09234a7a_47cd_bc19_fbbad15fd493/page/Two-layer%20SSH%20reverse%20tunnel

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值