ssh端口转发

玩转SSH端口转发

SSH有三种端口转发模式,本地端口转发(Local Port Forwarding)远程端口转发(Remote Port Forwarding)以及动态端口转发(Dynamic Port Forwarding)。对于本地/远程端口转发,二者的方向刚好相反。动态端口转发则能够用于FQ。html

SSH端口转发也被称做SSH隧道(SSH Tunnel),由于它们都是经过SSH登录以后,在SSH客户端SSH服务端之间创建了一个隧道,从而进行通讯。SSH隧道是很是安全的,由于SSH是经过加密传输数据的(SSH全称为Secure Shell)。linux

在本文全部示例中,本地主机A1为SSH客户端,远程云主机B1为SSH服务端。从A1主机经过SSH登录B1主机,指定不一样的端口转发选项(-L、-R和-D),便可在A1与B1之间创建SSH隧道,从而进行不一样的端口转发。git

本地端口转发

应用场景:

远程云主机B1运行了一个服务,端口为3000,本地主机A1须要访问这个服务。github

示例为一个简单的Node.js服务:shell

var http = require('http');

var server = http.createServer(function(request, response)
{
    response.writeHead(200,
    {
        "Content-Type": "text/plain"
    });
    response.end("Hello Fundebug\n");
});

server.listen(3000);

假设云主机B1的IP为103.59.22.17,则该服务的访问地址为:http://103.59.22.17:3000ubuntu

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

通常来说,云主机的防火墙默认只打开了22端口,若是须要访问3000端口的话,须要修改防火墙。为了保证安全,防火墙须要配置容许访问的IP地址。可是,本地公网IP一般是网络提供商动态分配的,是不断变化的。这样的话,防火墙配置须要常常修改,就会很麻烦。浏览器

什么是本地端口转发?

所谓本地端口转发,就是将发送到本地端口的请求,转发到目标端口。这样,就能够经过访问本地端口,来访问目标端口的服务。使用-L属性,就能够指定须要转发的端口,语法是这样的:安全

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

经过本地端口转发,能够将发送到本地主机A1端口2000的请求,转发到远程云主机B1的3000端口。网络

# 在本地主机A1登录远程云主机B1,并进行本地端口转发
ssh -L localhost:2000:localhost:3000 root@103.59.22.17

若是远程主机也是经过隧道来进行访问的话,那么须要加入端口号来进行登陆而不是默认的ssh的22端口号ssh

# 假设要访问的主机是属于远程内网主机,那么此时就是搭建的隧道来访问了(隧道的搭建也是经过ssh端口转发来搭建的),这里的2061端口就是暴露出的端口,经过这个端口能够访问到远程内网主机
ssh -L localhost:2000:localhost:3000 root@103.59.22.17 -p 2061

这样,在本地主机A1上能够经过访问http://localhost:2000来访问远程云主机B1上的Node.js服务。

# 在本地主机A1访问远程云主机B1上的Node.js服务
curl http://localhost:2000
Hello Fundebug

实际上,-L选项中的本地网卡地址是能够省略的,这时表示2000端口绑定了本地主机A1的全部网卡:

# 在本地主机A1登录远程云主机B1,并进行本地端口转发。2000端口绑定本地全部网卡
ssh -L 2000:localhost:3000 root@103.59.22.17

若本地主机A2可以访问A1,则A2也能够经过A1访问远程远程云主机B1上的Node.js服务。

另外,-L选项中的目标地址也能够是其余主机的地址。假设远程云主机B2的局域网IP地址为192.168.59.100,则能够这样进行端口转发:

# 在本地主机A1登录远程云主机B1,并进行本地端口转发。请求被转发到远程云主机B2上
ssh -L 2000:192.168.59.100:3000 root@103.59.22.17

若将Node.js服务运行在远程云主机B2上,则发送到A1主机2000端口的请求,都会被转发到B2主机上。

远程端口转发

应用场景:

本地主机A1运行了一个服务,端口为3000,远程云主机B1须要访问这个服务。

将前文的Node.js服务运行在本地,在本地就能够经过http://localhost:3000访问该服务。

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

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

什么是远程端口转发?

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

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

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

# 在本地主机A1登录远程云主机B1,并进行远程端口转发
ssh -R localhost:2000:localhost:3000 root@103.59.22.17

这样,在远程云主机A1能够经过访问http://localhost:2000来访问本地主机的服务。

# 在远程云主机B1访问本地主机A1上的Node.js服务
curl http://localhost:2000
Hello Fundebug

同理,远程网卡地址能够省略,目标地址也能够是其余主机地址。假设本地主机A2的局域网IP地址为192.168.0.100。

# 在本地主机A1登录远程云主机B1,并进行远程端口转发
ssh -R 2000:192.168.0.100:3000 root@103.59.22.17

若将Node.js服务运行在本地主机A2上,则发送到远程云主机A1端口2000的请求,都会被转发到A2主机上。

动态端口转发

应用场景:

远程云主机B1运行了多个服务,分别使用了不一样端口,本地主机A1须要访问这些服务。

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

一方面,因为防火墙限制,本地主机A1并不能直接访问远程云主机B1上的服务,所以须要进行端口转发;另外一方面,为每一个端口分别建立本地端口转发很是麻烦。

什么是动态端口转发?

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

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

这时,经过动态端口转发,能够将在本地主机A1发起的请求,转发到远程主机B1,而由B1去真正地发起请求。

# 在本地主机A1登录远程云主机B1,并进行动态端口转发
ssh -D localhost:2000 root@103.59.22.17

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

img

这样的话,Firefox浏览器发起的请求都会转发到2000端口,而后经过SSH转发到真正地请求地址。若Node.js服务运行在远程云主机B1上,则在Firefox中访问localhost:3000便可以访问。若是主机B1可以访问外网的话,则能够FQ……

链式端口转发

本地端口转发远程端口转发结合起来使用,能够进行链式转发。假设A主机在公司,B主机在家,C主机为远程云主机。A主机上运行了前文的Node.js服务,须要在B主机上访问该服务。因为A和B不在同一个网络,且A主机没有独立公共IP地址,因此没法直接访问服务。

经过本地端口转发,将发送到B主机3000端口的请求,转发到远程云主机C的2000端口。

# 在B主机登录远程云主机C,并进行本地端口转发
ssh -L localhost:3000:localhost:2000 root@103.59.22.17

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

# 在A主机登录远程云主机C,并进行远程端口转发
ssh -R localhost:2000:localhost:3000 root@103.59.22.17

这样,在主机B能够经过访问http://localhost:3000来访问主机A上的服务。

# 在主机B访问主机A上的服务
curl http://localhost:3000
Hello Fundebug

参考连接

原文连接:https://blog.fundebug.com/2017/04/24/ssh-port-forwarding/

相关文章
相关标签/搜索