玩转SSH端口转发
SSH有三种端口转发模式,本地端口转发(Local Port Forwarding),**远程端口转发(Local Port Forwarding)**以及**动态端口转发(Dynamic Port Forwarding)**。对于本地/远程端口转发,两者的方向恰好相反。**动态端口转发**则可以用于科学上网。
SSH端口转发也被称作SSH隧道([SSH Tunnel](http://blog.trackets.com/2014/05/17/ssh-tunnel-local-and-remote-port-forwarding-explained-with-examples.html)),因为它们都是通过SSH登陆之后,在**SSH客户端**与**SSH服务端**之间建立了一个隧道,从而进行通信。SSH隧道是非常安全的,因为SSH是通过加密传输数据的(SSH全称为Secure Shell)。
在本文所有示例中,本地主机A1为SSH客户端,远程云主机B1为SSH服务端。从A1主机通过SSH登陆B1主机,指定不同的端口转发选项(**-L、-R和-D**),即可在A1与B1之间建立SSH隧道,从而进行不同的端口转发。
### 本地端口转发
#### 应用场景:
> 远程云主机B1运行了一个服务,端口为3000,本地主机A1需要访问这个服务。
示例为一个简单的Node.js服务:
```javascript
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:3000](http://103.59.22.17:3000)
#### 为啥需要本地端口转发呢?
> 一般来讲,云主机的防火墙默认只打开了22端口,如果需要访问3000端口的话,需要修改防火墙。为了保证安全,防火墙需要配置允许访问的IP地址。但是,本地公忘IP通常是网络提供商动态分配的,是不断变化的。这样的话,防火墙配置需要经常修改,就会很麻烦。
#### 什么是本地端口转发?
所谓本地端口转发,就是**将发送到本地端口的请求,转发到目标端口**。这样,就可以通过访问本地端口,来访问目标端口的服务。使用**-L**属性,就可以指定需要转发的端口,语法是这样的:
```shell
-L 本地网卡地址:本地端口:目标地址:目标端口
```
通过**本地端口转发**,可以将发送到本地主机A1端口2000的请求,转发到远程云主机B1的3000端口。
```shell
# 在本地主机A1登陆远程云主机B1,并进行本地端口转发
ssh -L localhost:2000:localhost:3000 root@103.59.22.17
```
这样,在本地主机A1上可以通过访问[http://localhost:2000](http://localhost:2000)来访问远程云主机B1上的Node.js服务。
```shell
# 在本地主机A1访问远程云主机B1上的Node.js服务
curl http://localhost:2000
Hello Fundebug
```
实际上,**-L选项**中的**本地网卡地址**是可以省略的,这时表示2000端口绑定了本地主机A1的所有网卡:
```bash
# 在本地主机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,则可以这样进行端口转发:
```bash
# 在本地主机A1登陆远程云主机B1,并进行本地端口转发。请求被转发到远程云主机B2上
ssh -L 2000:192.168.59.100:3000 root@103.59.22.17
```
若将Node.js服务运行在远程云主机B2上,则发送到A1主机2000端口的请求,都会被转发到B2主机上。
### 远程端口转发
#### 应用场景:s
> 本地主机A1运行了一个服务,端口为3000,远程云主机B1需要访问这个服务。
将前文的Node.js服务运行在本地,在本地就可以通过[http://localhost:3000](http://localhost:3000)访问该服务。
#### 为啥需要远程端口转发呢?
> 通常,本地主机是没有独立的公网IP的,它与同一网络中的主机共享一个IP。没有公网IP,云主机是无法访问本地主机上的服务的。
#### 什么是远程端口转发?
所谓远程端口转发,就是**将发送到远程端口的请求,转发到目标端口**。这样,就可以通过访问远程端口,来访问目标端口的服务。使用**-R**属性,就可以指定需要转发的端口,语法是这样的:
```shell
-R 远程网卡地址:远程端口:目标地址:目标端口
```
这时,通过**远程端口转发**,可以将发送到远程云主机B1端口2000的请求,转发到本地主机A1端口3000。
```shell
# 在本地主机A1登陆远程云主机B1,并进行远程端口转发
ssh -R localhost:2000:localhost:3000 root@103.59.22.17
```
这样,在远程云主机A1可以通过访问[http://localhost:2000](http://localhost:2000)来访问本地主机的服务。
```shell
# 在远程云主机B1访问本地主机A1上的Node.js服务
curl http://localhost:2000
Hello Fundebug
```
同理,**远程网卡地址**可以省略,**目标地址**也可以是其他主机地址。假设本地主机A2的局域网IP地址为192.168.0.100。
```bash
# 在本地主机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去真正地发起请求。
```bash
# 在本地主机A1登陆远程云主机B1,并进行动态端口转发
ssh -D localhost:2000 root@103.59.22.17
```
而在本地发起的请求,需要由Socket代理([Socket Proxy](https://en.wikipedia.org/wiki/SOCKS))转发到SSH绑定的2000端口。以Firefox浏览器为例,配置Socket代理需要找到**首选项**>**高级**>**网络**>**连接**->**设置**:
这样的话,Firefox浏览器发起的请求都会转发到2000端口,然后通过SSH转发到真正地请求地址。若Node.js服务运行在远程云主机B1上,则在Firefox中访问[localhost:3000](localhost:3000)即可以访问。如果主机B1能够访问外网的话,则可以科学上网…...
### 链式端口转发
**本地端口转发**与**远程端口转发**结合起来使用,可以进行链式转发。假设A主机在公司,B主机在家,C主机为远程云主机。A主机上运行了前文的Node.js服务,需要在B主机上访问该服务。由于A和B不在同一个网络,且A主机没有独立公共IP地址,所以无法直接访问服务。
通过本地端口转发,将发送到B主机3000端口的请求,转发到远程云主机C的2000端口。
```bash
# 在B主机登陆远程云主机C,并进行本地端口转发
ssh -R localhost:3000:localhost:2000 root@103.59.22.17
```
通过远程端口转发,将发送到远程云主机C端口2000的请求,转发到A主机的3000端口。
```bash
# 在A主机登陆远程云主机C,并进行远程端口转发
ssh -R localhost:2000:localhost:3000 root@103.59.22.17
```
这样,在主机B可以通过访问[http://localhost:3000](http://localhost:3000)来访问主机A上的服务。
```shell
# 在主机B访问主机A上的服务
curl http://localhost:3000
Hello Fundebug
```
### 参考链接
- [SSH PortForwarding](https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding?action=fullsearch&value=linkto%3A%22SSH%2FOpenSSH%2FPortForwarding%22&context=180)
- [SSH隧道的原理和实现](http://www.pchou.info/linux/2015/11/01/ssh-tunnel.html)
玩转SSH端口转发的更多相关文章
- 005. [转] SSH端口转发
玩转SSH端口转发 SSH有三种端口转发模式,本地端口转发(Local Port Forwarding),远程端口转发(Remote Port Forwarding)以及动态端口转发(Dynamic ...
- ssh 端口转发实现外网 80 端口映射到内网 80 端口
开发中经常需要外网服务映射到本机内网服务的需要,便于调试. 以前都是同事帮着配,这两天自己也看了一下 ssh 端口转发. 同事分分钟钟搞定的事情,自己折腾了 2 天, 真是弱爆了. 最初老想不明白一件 ...
- 【转】实战 SSH 端口转发
本文转自:http://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html,至于有什么用,懂的懂! 实战 SSH 端口转发 通 ...
- SSH 端口转发
第一部分 概述 当你在咖啡馆享受免费 WiFi 的时候,有没有想到可能有人正在窃取你的密码及隐私信息?当你发现实验室的防火墙阻止了你的网络应用端口,是不是有苦难言?来看看 SSH 的端口转发功能能给我 ...
- 实战 SSH 端口转发
转自实战 SSH 端口转发 通过本文的介绍,读者可以从中了解到如何应用 SSH 端口转发机制来解决日常工作 / 生活中的一些问题.学会在非安全环境下使用端口转发来加密网络应用,保护个人隐私以及重要商业 ...
- 使用SSH代理上IPV6(使用SSH端口转发)
这几个月在国外待着,一直担心我的六维账户怎么办,那可是个宝贝啊.我看网上说可以用六飞啊神马的在IPV6下上IPV6的网站,但是冒失现在六维封禁了非学校的IPV6地址,所以这些软件就不顶用了. 想到以前 ...
- SSH25个命令 + 深入SSH端口转发细节
OpenSSH是SSH连接工具的免费版本.telnet,rlogin和ftp用户可能还没意识到他们在互联网上传输的密码是未加密的,但SSH是加密的,OpenSSH加密所有通信(包括密码),有效消除了窃 ...
- Linux SSH端口转发
SSH端口转发分为两种,一种是本地端口转发,又称为本地SSH隧道.一直是远程端口转发.SSH端口转发,还必须指定数据传送的目标主机,从而形成点对点的端口转发. 本地端口转发 假定有三台主机A. ...
- SSH端口转发详解及实例
一.SSH端口转发简介 SSH会自动加密和解密所有SSH客户端与服务端之间的网络数据.但是,SSH还能够将其他TCP端口的网络数据通SSH链接来转发,并且自动提供了相应的加密及解密服务.这一过程也被叫 ...
随机推荐
- 算法模板——sap网络最大流 3(递归+邻接表)
实现功能:同前 程序还是一如既往的优美,虽然比起邻接矩阵的稍稍长了那么些,不过没关系这是必然,但更重要的一个必然是——速度将是一个质的飞跃^_^(这里面的point指针稍作了些创新——anti指针,这 ...
- 浅谈并发和tomcat线程数
假设Tomcat每到固定一个时间会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s. 服务器性能很好,Tomcat版本是7.0.54,配置如下 & ...
- python 接口自动化测试(四)
说完了SOAP协议的接口自动化 该说下http协议的接口测试了 HttpService.py import requests import sys reload(sys) sys.setdefault ...
- UML软件方法大纲
利用周末的时间读了潘加宇的<软件方法(上)>,希望梳理清楚UML的知识脉络: 工作流 子流程 内容 备注 建模和uml 利润=需求-设计 愿景 缺乏清晰.共享的愿景往往是项目失 ...
- Android Material Design 系列之 SnackBar详解
SnackBar是google Material Design提供的一种轻量级反馈组件.支持从布局的底部显示一个简洁的提示信息,支持手动滑动取消操作,同时在同一个时间内只能显示一个SnackBar. ...
- java中有符号和无符号数据类型发生转换
package com.itheima.test01;/* * byte short int long float double 是有符号位的数 * char boolean 是无符号位的数 * 补码 ...
- iOS开发之清除缓存
NSFileManager *mgr = [NSFileManager defaultManager]; NSString *cachePath = [NSSearchPathForDirectori ...
- celldb.cc
欢迎光临 celldb.cc 的新博客 老博客的内容就不搬迁了, 工作量太大. http://celldb.cc 主要功能: 1 话单基站轨迹分析 2 基站查询 3 邻近基站查询 4 CDMA根据城市 ...
- 初步认识Thymeleaf:简单表达式和标签。(二)
本篇文章是对上篇文章中Thymeleaf标签的补充. 1.th:each:循环,<tr th:each="user,userStat:${users}">,userSt ...
- 【C++】浅谈三大特性之一继承(三)
四,派生类的六个默认成员函数 在继承关系里,如果我们没有显示的定义这六个成员函数,则编译系统会在适合场合为我们自动合成. 继承关系中构造函数和析构函数的调用顺序: class B { public: ...