ssh-port-redirect-in-linux-system,


SSH端口转发

SSH端口转发也被称作SSH隧道(SSH Tunnel),因为它们都是通过SSH登陆之后,在SSH客户端SSH服务端之间建立了一个隧道,从而进行通信。SSH隧道是非常安全的,因为SSH是通过加密传输数据的(SSH全称为Secure Shell)。

下文参考地址:tuicool
首先看下面这张图,我们所面临的大部分情况都和它类似。我们的电脑在左上角,通过公司带有防火墙功能的路由器接入互联网(当然可能还有交换机什么的在中间连 接着你和路由器,但是在我们的问题中交换机并不起到什么关键性的作用)。右下脚的部分是一个网站的服务器,它是我们公司防火墙策略的一部分,也就是说公司 不希望我们访问这个服务器。在右上角还有一台机器,它也是属于我们的。但是这台机器并不在我们公司里面,换句话说他不受到公司防火墙的限制。最后也是最重 要的一点是,我们能够在公司通过互联网直接访问这台机器。或者说这台位于公司防火墙外面的机器需要拥有一个独立的互联网IP,同时公司的防火墙规则不会屏 蔽这台机器,并且这台机器运行着一个OpenSSH服务器。

现 在,我们清楚地知道了自己所处的网络环境。并且不难理解我们在公司无法访问那个服务器的原因是:线路A-B-C上A-B之间的防火墙屏蔽了对那个服务器的 访问。与此同时,我们也很快注意到,线路A-B-D之间、D-C之间是不受阻碍的。相信你已经想到了,在A-B之间的防火墙不会屏蔽对机器d的访问。因此 我们可以通过机器d建立一个通道A-B-D-C,从而访问到机器c上的数据。
这条通道可以用很多技术来建立,这里我们仅仅介绍如何使用SSH服务器来建立这样一个通道-他被称为SSH隧道。

SSH端口转发的类型和使用场景

SSH有三种端口转发模式,

SSH三种端口转发模式的用处

对于本地/远程端口转发,两者的方向恰好相反。
则可以用于科学上网。

在本文所有示例中,本地主机为SSH客户端,远程云主机为SSH服务端。从本地主机通过SSH登陆远程主机,指定不同的端口转发选项(-L、-R和-D),即可在本地主机与远程主机之间建立SSH隧道,从而进行不同的端口转发。

本地端口转发

应用场景:

远程云主机C运行了一个服务,端口为10086,本地主机A需要访问这个服务。
运行的服务是我之前写的一个js代码在线编辑及运行的平台。
服务的地址及访问端口:wanqing520.cn:10086

由于域名备案还没有审核通过,所以这时候在浏览器中打开,就会有腾讯云的提示信息。

但是,我们通过端口转发的方式,是可以通过访问本地的方式来访问远程的服务的。

为啥需要本地端口转发呢?

一般来讲,云主机的防火墙默认只打开了22端口,如果需要访问10086端口的话,需要修改防火墙。为了保证安全,防火墙需要配置允许访问的IP地址。但是,本地公忘IP通常是网络提供商动态分配的,是不断变化的。这样的话,防火墙配置需要经常修改,就会很麻烦。所以,我们在内测或者发布敏感的私有web服务的时候,可能就需要这种SSH端口转发的功能来允许我们访问目标服务来完成测试或者请求服务。

什么是本地端口转发?

所谓本地端口转发,就是将发送到本地A端口的请求,转发到C目标端口。这样,就可以通过访问本地A:端口,来访问目标C:端口的服务。使用-L属性,就可以指定需要转发的端口,语法是这样的:

-L 本地网卡地址:本地端口:目标地址:目标端口 

通过本地端口转发,可以将发送到本地主机A端口80的请求,转发到远程云主机C的10086端口。

# 在本地主机A登陆远程云主机B,并进行本地端口转发到远程云主机C
# 注意,这里wanqing520.cn 和js.wanqing520.cn是不同的两个主机
$ ssh -L localhost:80:wanqing520.cn:10086 ubuntu@js.wanqing520.cn
ubuntu@js.wanqing520.cn's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-53-generic i686)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

*** System restart required ***
Last login: Mon Jun 12 11:32:06 2017 from 58.19.126.219

这样,在本地主机A1上可以通过访问localhost来访问远程云主机C上的HTTP服务。

实际上,-L选项中的本地网卡地址是可以省略的,这时表示80端口绑定了本地主机A1的所有网卡:

# 在本地主机A1登陆远程云主机B1,并进行本地端口转发。2000端口绑定本地所有网卡
ssh -L 80:wanqing520.cn:10086 ubuntu@js.wanqing520.cn

这样以来,如果本地主机A处在某个局域网中,且本地主机A的防火墙允许本地请求端口80出站的话,那么当前局域网下的所有网络设备都是可以通过访问本地主机A的IP地址来访问远程的服务的。

另外,需要说明的是,为了节省时间,这里我们用的远程服务器都是通过域名来访问的。实际上我们可以使用云主机的内网IP地址来进行访问,但是由于腾讯云等云服务器提供商的约定:只有在同一账户下的同以区域下的服务器才是在同一个局域网下的。我的两个服务器wanqing520.cnjs.wanqing520.cn分别位于广州区域上海区域,因此通过内网地址是无法访问的,所有,这里就直接使用外网地址来访问了,请大家注意的是,这里如果远程主机B和C如果处在同一局域网下,是可以将目标地址设为内网地址的。

提示如果遇到地址被占用的问题,请参考文末的解决方案,或者可以自行百度更具体的方案。

还有值得一提的由于本案例演示的是,有A连接跳板机B(姑且叫做跳板机)来访问云主机C来获取服务,更一般的情况,我们可以直接绑定云主机B的端口和地址,来直接从云主机B来进行服务的获取。
*

远程端口转发

应用场景:

本地主机A运行了一个elasticsearch服务,端口为9200,远程云主机B需要访问这个服务。

我们可以借助sense(笔者用的是chrome的sense插件)来访问本地的elasticsearch服务。

为啥需要远程端口转发呢?

通常,本地主机是没有独立的公网IP的,它与同一网络中的主机共享一个IP。没有公网IP,云主机是无法访问本地主机上的服务的。

什么是远程端口转发?

所谓远程端口转发,就是将发送到远程端口的请求,转发到目标端口。这样,就可以通过访问远程端口,来访问目标端口的服务。使用-R属性,就可以指定需要转发的端口,语法是这样的:

-R 远程网卡地址:远程端口:目标地址:目标端口 

这时,通过远程端口转发,可以将发送到远程云主机B1端口2000的请求,转发到本地主机A1端口3000。

# 在本地主机A1登陆远程云主机B1,并进行远程端口转发
$ ssh -R localhost:9200:localhost:9280 ubuntu@js.wanqing520.cn
ubuntu@js.wanqing520.cn's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-53-generic i686)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

*** System restart required ***
Last login: Mon Jun 12 14:21:16 2017 from 58.19.126.219

这样,在远程云主机B可以通过访问http://localhost:9280来访问本地主机的elasticsearch服务。

# 在远程云主机B访问本地主机A上的elasticsearch服务
$ curl "http://localhost:9200/website/blog/1/_source?_source=text&pretty"
{
  "text" : "Starting to get the hang of this..."
}

同理,远程网卡地址可以省略,目标地址也可以是其他主机地址。

动态端口转发

应用场景:

远程云主机B运行了多个服务,分别使用了不同端口,本地主机A需要访问这些服务。

为啥需要动态端口转发呢?

一方面,由于防火墙限制,本地主机A并不能直接访问远程云主机B上的服务,因此需要进行端口转发;另一方面,为每个端口分别创建本地端口转发非常麻烦。

什么是动态端口转发?

对于本地端口转发远程端口转发,都存在两个一一对应的端口,分别位于SSH的客户端和服务端,而动态端口转发则只是绑定了一个本地端口,而目标地址:目标端口则是不固定的。目标地址:目标端口是由发起的请求决定的,比如,请求地址为js.wanqing520.cn:10086,则通过SSH转发的请求地址也是js.wanqing520.cn:10086

-D 本地网卡地址:本地端口

这时,通过动态端口转发,可以将在本地客户端发起的请求,转发到远程主机,而由远程主机去真正地发起请求。

# 在本地主机A1登陆远程云主机B1,并进行动态端口转发
ssh -D localhost:1080 ubuntu@js.wanqing520.cn

而在本地发起的请求,需要由Socket代理(Socket Proxy)转发到SSH绑定的1080端口。以Firefox浏览器为例,配置Socket代理需要找到首选项>高级>网络>连接->设置:

这样的话,Firefox浏览器发起的请求都会转发到1080端口,然后通过SSH转发到真正地请求地址。若某项服务运行在远程云主机B上,则在Firefox中访问localhost:3000即可以访问。

链式端口转发

本地端口转发远程端口转发结合起来使用,可以进行链式转发。假设A主机在公司,B主机在家,C主机为远程云主机。A主机上运行了某个服务,需要在B主机上访问该服务。由于A和B不在同一个网络,且A主机没有独立公共IP地址,所以无法直接访问服务。

通过本地端口转发,将发送到B主机8081端口的请求,转发到远程云主机C的8080端口。

# 在B主机登陆远程云主机C,并进行本地端口转发
ssh -R localhost:8081:localhost:8080 ubuntu@wanqing520.cn

通过远程端口转发,将发送到远程云主机C端口8080的请求,转发到A主机的8080端口。

# 在A主机登陆远程云主机C,并进行远程端口转发
ssh -R localhost:8080:localhost:8080 ubuntu@js.wanqing520.cn

这样,在主机B可以通过访问http://localhost:8081来访问主机A上的服务。

可能会出现的问题

如果您在做测试的时候,出现了下面的问题

$ ssh -L 80:wanqing520.cn:10086 ubuntu@js.wanqing520.cn
ubuntu@js.wanqing520.cn's password:
bind: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 80
Could not request local forwarding.
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-53-generic i686)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

*** System restart required ***
Last login: Mon Jun 12 12:15:00 2017 from 58.19.126.219
ubuntu@VM-195-65-ubuntu:~$ logout
Connection to js.wanqing520.cn closed.

在windows下可以采用下面的方法来解决解决
1. 使用netstat -nao | findstr "80"查看所有和80端口相关的线程

[c:\~]$ netstat -nao | findstr "80"
  TCP    0.0.0.0:1080           0.0.0.0:0              LISTENING       46428
  TCP    0.0.0.0:1536           0.0.0.0:0              LISTENING       680
  TCP    0.0.0.0:1580           0.0.0.0:0              LISTENING       848
  TCP    0.0.0.0:1801           0.0.0.0:0              LISTENING       4696
  TCP    0.0.0.0:7680           0.0.0.0:0              LISTENING       4044
  TCP    0.0.0.0:9100           0.0.0.0:0              LISTENING       13380
  TCP    127.0.0.1:80           0.0.0.0:0              LISTENING       53108
  TCP    127.0.0.1:1080         127.0.0.1:47166        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:47178        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:47614        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:47635        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:47644        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:47778        ESTABLISHED     46428
  TCP    127.0.0.1:1080         127.0.0.1:54127        TIME_WAIT       0
  TCP    127.0.0.1:1080         127.0.0.1:54128        TIME_WAIT       0
  TCP    127.0.0.1:1080         127.0.0.1:54131        TIME_WAIT       0
  TCP    127.0.0.1:1080         127.0.0.1:54135        TIME_WAIT       0
  TCP    127.0.0.1:1080         127.0.0.1:54137        TIME_WAIT       0
  TCP    127.0.0.1:1080         127.0.0.1:54163        ESTABLISHED     46428
  TCP    127.0.0.1:47166        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:47178        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:47614        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:47635        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:47644        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:47778        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:54139        127.0.0.1:1080         TIME_WAIT       0
  TCP    127.0.0.1:54148        127.0.0.1:1080         TIME_WAIT       0
  TCP    127.0.0.1:54163        127.0.0.1:1080         ESTABLISHED     41788
  TCP    127.0.0.1:54165        127.0.0.1:1080         TIME_WAIT       0
  TCP    127.0.0.1:54177        127.0.0.1:1080         TIME_WAIT       0
  TCP    127.0.0.1:54179        127.0.0.1:1080         TIME_WAIT       0
  TCP    192.168.1.108:80       0.0.0.0:0              LISTENING       45624
  TCP    192.168.1.108:80       192.168.1.103:33074    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:33904    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:33905    ESTABLISHED     45624
  TCP    192.168.1.108:80       192.168.1.103:33923    ESTABLISHED     45624
  TCP    192.168.1.108:80       192.168.1.103:60820    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60821    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60822    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60823    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60824    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60825    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60830    ESTABLISHED     45624
  TCP    192.168.1.108:80       192.168.1.103:60831    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60832    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60835    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60836    CLOSE_WAIT      45624
  TCP    192.168.1.108:80       192.168.1.103:60837    ESTABLISHED     45624
  TCP    192.168.1.108:18013    65.55.223.38:40021     CLOSE_WAIT      52172
  TCP    192.168.1.108:18014    91.190.217.52:12350    CLOSE_WAIT      52172
  TCP    192.168.1.108:36666    101.199.97.107:80      ESTABLISHED     14008
  TCP    192.168.1.108:45222    182.254.92.140:443     ESTABLISHED     48040
  TCP    192.168.1.108:47731    163.177.73.40:80       CLOSE_WAIT      48384
  TCP    192.168.1.108:52992    182.254.76.117:443     CLOSE_WAIT      48040
  TCP    192.168.1.108:53057    106.120.166.79:80      ESTABLISHED     14008
  TCP    192.168.1.108:54211    121.195.187.54:80      ESTABLISHED     52672
  TCP    192.168.1.108:54212    115.157.63.18:80       ESTABLISHED     52672
  TCP    192.168.1.108:54214    121.195.187.54:80      TIME_WAIT       0
  TCP    192.168.1.108:54218    121.195.187.54:80      TIME_WAIT       0
  TCP    192.168.1.108:54220    121.195.187.54:80      TIME_WAIT       0
  TCP    192.168.1.108:54221    115.25.209.36:80       TIME_WAIT       0
  TCP    192.168.1.108:54222    58.205.214.142:80      ESTABLISHED     48384
  TCP    192.168.1.108:54223    123.58.182.103:80      ESTABLISHED     13008
  TCP    192.168.1.108:54224    119.147.10.139:80      ESTABLISHED     48040
  TCP    192.168.1.108:54225    101.4.60.83:80         FIN_WAIT_2      12036
  TCP    [::]:1536              [::]:0                 LISTENING       680
  TCP    [::]:1580              [::]:0                 LISTENING       848
  TCP    [::]:1801              [::]:0                 LISTENING       4696
  TCP    [::]:7680              [::]:0                 LISTENING       4044
  TCP    [::1]:80               [::]:0                 LISTENING       53108
  TCP    [::1]:54183            [::1]:80               TIME_WAIT       0
  TCP    [::1]:54184            [::1]:80               TIME_WAIT       0
  TCP    [::1]:54185            [::1]:80               TIME_WAIT       0
  TCP    [::1]:54186            [::1]:80               TIME_WAIT       0
  TCP    [::1]:54187            [::1]:80               TIME_WAIT       0
  TCP    [::1]:54188            [::1]:80               TIME_WAIT       0
  UDP    0.0.0.0:1080           *:*                                    46428
  UDP    0.0.0.0:58096          *:*                                    48736
  UDP    [fe80::6d88:2667:fe2:4c27%2]:5353  *:*                                    4876

找到80端口的占用线程的PID(本文演示时的PID=53108)后
在任务管理器中,打开PID显示

找到对应的线程,然后结束掉该线程就可以了。

相关内容

    暂无相关文章