https://www.ramkitech.com/2012/04/how-to-do-ssh-tunneling-port-forwarding.html

https://www.cnblogs.com/popsuper1982/p/3875420.html

本文我将谈到ssh是怎么工作的,到底什么是ssh tunneling隧道技术,ssh隧道到底有什么重要意义,以及如何搭建ssh tunnel.正常情况下,ssh server只要安装了,那么默认情况下就允许ssh tunneling.

SSH tunneling(port forwarding)

tunneling是这样一种概念:将一种网络协议报文(这里更多指应用层协议)封装到另外一个协议中传输,这里我们就是ssh,也就是说将其他协议的报文封装到ssh中,由于ssh本身是加密的,因此所有的应用层网络通信都是加密安全的. 在ssh tunneling的技术中,我们会绑定一个local port,并且所有targeted到这个local port的报文都将透明的加密并通过隧道转发到remote system,正因为如此,SSH tunneling也被称为端口转发。

为什么需要ssh tunneling?

SSH虽然对于管理远端系统是足够了,但是ssh并不足以用于访问所有远端系统所提供的服务。

需要注意的是:在上面的3个系统中,ssh server daemon service都运行着并监听22端口,而防火墙允许使用ssh client连接这个22端口.

在上面的网络架构中101可以和PrivateServer 102直接通信,因为两个系统都直接和internet相连接,但是101却不能和intranet 10.10.1.11通信,因为从101系统的角度来说,10.10.1.11是一个non routeable的IP地址,该IP地址本身只是一个local ip,而不是公网的IP,因此无法路由dest addr是该私有网络的报文.

现在的需求是我希望从101访问到intranet 10.10.1.11的机器,怎么办?

一个可行的方案是首先ssh登录到privateserver(102机器)然后从102再ssh到intranet 10.10.1.11上.嗯,这是一个办法,至少我们现在可以管理到10.10.1.11机器了,执行一些shell命令.但是问题是,如果10.101.1.11机器上也提供了其他的服务,比如VNC, apache web server, smtp, pop3, squid proxy等服务,我们如何从101机器上访问这些服务呢,比如在101的机器上使用firefox来访问10.10.1.11上的web server?仅仅使用ssh传统的log/shell就无法满足了。

真正的解决方案就是使用:ssh tunneling或者说ssh port forwarding

SSH是如何工作的?

在terminal中,当我们敲入ssh someone@private-server.org时,terminal application将调用ssh client,ssh client则连接到private-server.org机器的22端口(由ssh server监听).然后client和server交换Identitiy,public key, cipher suite info并且在server端创建一个新的shell process.随后client和server之间就建立了安全的通道了,这样之后的所有command及response都通过这个secure channel来传递。

比如当ssh连接建立后,我将执行ls命令。那么ls命令将由ssh client加密封装通过该通道发往server.server则解密取出命令'ls'并且在shell(该shell就是ssh链接创建时所创建的)中执行,所有的输出将被redirect到该隧道的另一端-ssh client上,最后ssh client则解密取出output消息打印在terminal application上。

这里需要说明的是ssh本身只使用了22端口(也就是ssh server监听的那个端口)

ssh tunneling

ssh协议本身要求对远程机器上服务的访问请求是通过channels来传递的。一个ssh connection可以包含多个channels,这有点类似于有线电视同轴电缆上可以同时传输多个信道的电视节目一样。每一个channel则代表着单一的那个service.比如,你通过Net::ssh的方式激活了一个远程主机上的一个进程时,就将创建一个channel专门用于服务于那个invocation,和那个process有关的所有的input和output都将经由那个channel来传输.而ssh connection本身则管理着该connection中所有已开的channels上流动的packets.这也意味着,虽然我们只有一个ssh connection,但是我们却可以同时执行:运行新的进程,sftp下载文件,端口转发port forwarding等。一个channel就是一个流

https://net-ssh.github.io/ssh/v1/chapter-3.html#s1

通常情况下我们就是用shell channel.但是在ssh tunneling模式下,我们准备使用data channel.需要了解的基础概念是:在101机器上ssh client绑定了一个端口并且和server(102)建立了secure connection,并且创建一个data channel和一个shell channel(实际上我们可以通过-N选项来忽略shell channel的创建)。这样,在101机器上任何应用如果发送数据到那个端口(就是ssh client绑定的那个端口),那么ssh client将透明地截取数据加密后转发给server(应该是通过所谓shell channel,不确定).而在server上(102)则接收并且解密这个数据并且做本地调用(这块随后就将讨论)

ssh tunneling types

ssh提供3种类型的隧道,

  • Dynamic Tunneling(SOCKS proxy)
  • Local Port Forwarding
  • Remote Port Forwarding

Dynamic Tunneling(Socks proxy)

ssh     -D      ramki@192.168.56.102

这里-D 8080可以解读为SOCKS V5 Proxy代理将在client side上绑定8080端口.

使用Dynamic Tunneling可以解决 Websense blocks your intended sites: websense是一个局域网代理解决方案

现在101的ssh client将在client side创建an一个SOCKS proxy server并且绑定一个local port 8080.随后使用ramki这个用户的信息去登录远程102服务器并且建立secure channel.

随后client application比如firefox,chrome需要配置proxy使用SOCKS proxy server localhost:8080.然后在我们101机器的firefox地址栏输入http://localhost,尽管在我们的101机器上并没有任何web服务开启着,我们却可以看到来自server 102返回的web页面!!!(注意:在102机器和10.10.1.11上都有apache绑定在其80端口上提供服务,而101机器并无web服务运行)

这到底发生了什么?

由于我们配置了proxy在浏览器中,因此浏览器将所有的http请求(甚至是localhost本身的http请求)都会送往8080端口,而SOCKS proxy正在这里监听着8080端口,随后SOCKS proxy将会把我们的http request打包并且送给ssh client加密后送往server.在server端则解密并且extract出来http request。这样在server端,http request中的http://localhost/实际上上指向的是server机器本身,并且是80端口(因为http协议中如果不明确指明端口则意味着默认80端口)。因此server将invoke这个request,而我们的102机器中apache正好在监听这个80端口并且提供服务,因此返回页面内容并通过相同的secure channel返回到client side的应用(firefox)

还有一点需要说一下,本来从client机器101上,10.10.1.11是不可路由的,但是现在如果在101机器firefox浏览器上输入http://10.10.1.11则可以正确访问到10.10.1.11这个机器上部署的apache服务!!原因是该请求实际上是由102这台ssh server代为请求的,而102是可以访问该10.10.1.11机器的哦!

优势: 只要使用client机器上创建的proxy server就能够访问remote machine以及其身后子网机器上的任何服务;

缺点:我们需要在client application上配置这个proxy,但是如果应用本身并不支持proxy的配置选项,则我们仍然无法通过这种方式来访问到对应的service。

可以参考以下博客文章搭建自己的proxy server:

https://bugthinking.com/bypass-internet-censorship-using-aws-and-shadowsocks/

验证可用:

随后必须使用firefox使能socks proxy,并且使用remote dns

local port forwarding

ssh   -L  :localhost:     ramki@192.168.56.102

注意这里的语法是: -L   <local port> : <remote hostname> : <remote service port> user@sshserver

以上命令执行后,将在client side绑定了8000本地端口。任何发往8000端口的traffic将被redirect到ssh client(因为ssh client监听绑定了8000端口),随后加密送往server端,随后server将直接deliver数据到localhost的80端口.在Dynamic tunnel(SOCKS)模式下,server会检查packet并且决定我们要将该packet最终发往何处(比如,http://localhost则送往80, smtp则送往25)但是在local port forwarding模式下,目的地永远是在建立这个local port forwarding命令中指定的remote service port! <remote hostname> : <remote service port>

这种模式下,101机器的firefox中不再需要配置proxy选项(如果有的话,你需要清除掉proxy配置),随后在地址栏输入 http://localhost:8000,那么http request将会送往local port 8000,随后redirect并送往server.server则直接将报文送往server 102机器的port 80(注意这里的host及port是由 <remote hostname> : <remote service port>决定的,也就是localhost=102,80为目标端口)

如果你希望访问10.10.1.11上的http service则必须创建一个新的local port forwarding,也就是说local port forwarding是点对点一对一的!我们不能使用前面已经创建好的隧道,因为老的隧道总是指向localhost:80,也就是102这台机器的80端口!

使用以下命令:

ssh   -L  :10.10.1.11:   ramki@192.168.56.102

以上命令执行后,则101 localhost的8000端口将再被重定向到10.10.1.11:80这个机器,via(通由)192.168.56.102

在firefox中,我们输入http://localhost:8000,那么我们就将访问到10.10.1.11的http service

好处: 不必配置proxy

缺点: 对于每个service我们都需要配置一个不同的Local port forwarding(即:对于192.168.56.102和10.10.1.11两台机器上的http service,我们需要分别创建两个local port转发隧道)

下面是自己做实验验证的结果截图

Remote Port Forwarding

remote port forwarding和local port forwarding是类似的,但是区别在于,我们将在server端创建port forwarding(102机器),而不是在101 ssh client side上

ssh    -R :localhost:       ramki@192.168.56.101

这里非常重要的区别是:我们将从server连接到client,因此这里是ramki@192.168.56.101注意是101而不是102.(值得怀疑)当执行这条命令后将会连接到client并且在client side创建8000端口.

随后client使用本地8000端口来连接server,就像是local port forwarding一样.

为何remote port forwarding是重要的?

一般来说,计算机会在NAT之后,因此从外部是无法访问到计算机的.

windows上使用实例

在windows机器上,如果希望运行ssh server,则有很多选择,比如winsshd,freesshd,openssh等。如果只使用ssh client,则可以使用putty.

假设192.168.56.101机器上运行这windows系统,我们来演示如何使用ssh tunneling.打开putty并且输入host ramki@192.168.56.102并选择connection->ssh->tunnels,输入8080到source port并选择Dynamic,这就相当于启动了sock proxy等价于-D 8080命令

如果希望使用local port forwarding则任意选择一个未使用的port 6000到source port并且在destination中输入localhost:80选择local模式,等价于-L 6000:localhost:80

如果你希望访问10.10.1.11机器的远程桌面vnc,那么就创建一个local port forwarding,并且选择destination是10.10.1.11:5900,因为5900端口是11这台机器的vnc server监听的端口。随后使用任何vnc client,比如我们使用tightvnc client连接到local port 6000

图解再谈ssh port forwarding-ssh隧道技术的更多相关文章

  1. SSH Tunnel扫盲(ssh port forwarding端口转发)

    SSH的的Port Forward,中文可以称为端口转发,是SSH的一项非常重要的功能.它可以建立一条安全的SSH通道,并把任意的TCP连接放到这条通道中.下面仔细就仔细讨论SSH的这种非常有用的功能 ...

  2. 再谈初学者关心的ssh应用方方面面

    http://blog.robertelder.org/what-is-ssh/ https://www.ssh.com/ssh/key/ 什么是ssh? ssh是一个在计算机之间实现安全通信的网络协 ...

  3. ssh port forwarding

    SSH端口转发,总是忘记,今天记录下.端口转发有两种,一个是local一个是remote(可能还有一种dynamic,还没有研究) 贴个链接 https://www.ssh.com/ssh/tunne ...

  4. SSH port forwarding: bind: Cannot assign requested address

    https://www.electricmonk.nl/log/2014/09/24/ssh-port-forwarding-bind-cannot-assign-requested-address/

  5. 再谈javascript图片预加载技术

    图片预加载技术的典型应用: 如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展 ...

  6. How to do SSH Tunneling (Port Forwarding)

    How to do SSH Tunneling (Port Forwarding) In this post we will see how ssh works?, what is SSH tunne ...

  7. 利用SSH隧道技术穿越内网访问远程设备

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/11899478.html 通常,我们用于调试的计算机无法远程访问位于局域网中的待调试设备. ...

  8. SSH隧道技术----端口转发,socket代理

    原文的原始出处不详,本文也是在复制引用了某篇转载,并做了必要的整理与编辑. 本文的受众 如果你遇到了以下问题,那么你应该阅读这篇文章 我听说过这种技术,我对它很感兴趣 我想在家里访问我在公司的机器(写 ...

  9. GitLab non-standard SSH port

    /***************************************************************************** * GitLab non-standard ...

随机推荐

  1. 01、Linux基础命令

    linux 一些主要目录的认识: /bin 二进制可执行命令 /boot 存放系统引导文件,如 内核.grub 等 /dev 设备文件 /etc 系统配置目录 /home 普通用户家目录 /lib 系 ...

  2. 用session实现的用户登陆,客户端是怎样获取到cookie信息的

    大家都知道cookie是存在客户端,session存在服务器端.那么客户端具体是怎样获取cookie信息的呢? 更好的阅读体验可访问 这里. 实验环境 实验环境:xampp + Thinkphp5 + ...

  3. 【转】Pandas学习笔记(三)修改&添加值

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  4. java JSONObject

    JSONObject.has("key")方法首先判断是否含有该key字段,如果不存在该字段,返回false;如果存在此字段,还判断了该字段的value值是否为null,如果val ...

  5. ESA2GJK1DH1K基础篇: 来吧! 彻底了解一下MQTT

    首先你需要知道MQTT并不是什么高大上的事物,它只是一个软件,对就是一个软件.其实就是个TCP服务器 一,既然是TCP服务器,这个TCP服务器和咱平时做的有什么不一样呢. 首先,平时的时候咱做的TCP ...

  6. 网络协议 10 - Socket 编程(上)

    前面一直在说各种协议,偏理论方面的知识,这次咱们就来认识下基于 TCP 和 UDP 协议这些理论知识的 Socket 编程.     说 TCP 和 UDP 的时候,我们是分成客户端和服务端来认识的, ...

  7. Softmax与Sigmoid函数的联系

    译自:http://willwolf.io/2017/04/19/deriving-the-softmax-from-first-principles/ 本文的原始目标是探索softmax函数与sig ...

  8. haproxy 配置文件详解 之 WEB监控平台

    HAProxy 虽然实现了服务的故障转移,但是在主机或者服务出现故障的时候,并不能发出通知告知运维人员,这对于及时性要求很高的业务系统来说,是非常不便的,不过,HAProxy 似乎也考虑到了这一点,在 ...

  9. web前端图片模糊到清晰的实现过程

    在网页图片显示的时候,会发现许多网站采用了先模糊,然后在慢慢清晰的过程,这样的加载用户体验是比较好的,那么如何实现? 默认加载2张图片,一张缩略图,一张原图,当打开网页的时候默认只显示缩略图,然后我们 ...

  10. MinGW g++.exe 编译 DLL 时,导出函数名带@的问题

    今天尝试用CodeBlocks写了一个简单的Dll,发现生成的 dll 文件导出的函数名后面都有一个 @xxx 从生成的 libDll2.def 中看到: EXPORTS DllMain@ @ Max ...