SSH端口转发

端口转发

ssh 会自动加密和解密所有的ssh客户端与服务端之间的网络数据。但是ssh 还提供了一个端口转发的功能。转发是一种与其他网络应用程序交互的方式,它能将其他TCP端口的网络数据通过SSH链接来转发,并且自动提供了相应的加密以及解密服务。这一过程有时也被叫做隧道

应用场景

A: 本地服务器(IP: 10.0.0.1)

B: 中间服务器(IP: 10.10.10.1)

C: 目标服务器(C可以看到都是中间服务器B 在访问自己)

本地转发

第一种场景

A: 10.0.0.1

B: 10.0.0.2 (安装Mysql service,监听端口3306)

B 上数据库 限制了 只有本机上的应用才可以直接连接Mysql 服务,如果我们由于调试需要用A上直接连接这个LDAP服务器,就需要使用本地转发实现

ssh -L <本地端口>:<远程主机>:<远程端口>  

复制

本例中应该如下:

ssh -L 30000:10.0.0.2:80 root@10.0.0.2

复制

* -L 表示 使用 本地转发 建立ssh隧道

* 选用 -f 后台建立隧道

* -N 建议隧道后不执行命令

* -fNR

* 本地转发: 本地转发是 表示本地的端口上的数据通讯都会被转发到目标主机的对应端口上,这里可以抽象成是一种映射,执行命令的主机 为 本地主机。

* 访问本地主机的30000 端口A,就相当于访问目标主机的端口B,当方粉本地的端口时,通讯数据会转发到目标主机的端口B,这就是本地转发

* 访问A的30000 端口 就转发到了10.0.0.2 上的 80 端口上了

* 30000 表示本地端口的监听地址

* 10.0.0.2 表示远程主机以及端口

* root@10.0.0.2 创建的ssh隧道是连接到10.0.0.2 上的root用户的

* 综上

* 从本机10.0.0.1 建议到10.0.0.2的隧道,使用本地转发模式,监听本机的30000端口,当访问本机的30000端口时,数据会被转发到10.0.0.2的80 端口上

第二种场景

A. 本地服务器 10.0.0.1

B: 中间服务器 10.0.0.2

C: 目标服务器 192.168.0.2

A——能访问——>B——能访问——>C

A——不能访问————> C

A 通过该本地端口 以B的名义去访问——>C

ssh -Nf -L <本地IP>:<本地端口>:<目标主机>:<目标端口>  <中间服务器地址>

复制

ssh -Nf -L 30001:192.168.0.2:80 root@10.0.0.2

复制

远程端口转发

应用场景:

A: 客户端PC 10.0.0.1

B: 服务器端 10.0.0.2

B 可以ssh连接A,但是A无法连接B

服务器端操作,这时 服务器端就是操作端

ssh -R AIP::<服务器端端口>  

复制

在10.0.0.2 上操作

ssh -R 30001:localhost:80 root@10.0.0.1

复制

* 在 10.0.0.1 建立隧道连接 并在10.0.0.1上建立端口 30001 端口监听

* 在10.0.0.1 访问30001 的端口 会通过转发 到 服务端10.0.0.2 的 80 端口

动态转发

A: 10.0.0.1

B: 10.0.0.2

本地转发、远程转发都是需要一个我们已知的一个应用服务的端口的,但是如果没有端口的话,这里就需要用动态转发。

A 上操作

ssh -D  

复制

例如:

ssh -D 30002 root@10.0.0.2

复制

* -D bind_address:port D参数说明我们开启了一个本地的端口转发。通过在本地分配了一个socket去监听端口。只要连接请求到这个port上来时,这个连接就会被安全通过该转发出去,应用程序的协议将有远程机器来决定连接到哪里。

A 把B 作为了自己的全权代理,不限定目标服务器以及端口

场景说明:

浏览器访问google.com,此时浏览器开启了一个端口15435,但是发现在访问某个节点时,此网络包被丢弃了或者返回了错误的信息,导致我们无法访问google.com. 但是我们可以访问proxy.remotehost.com,而且该代理机器可以访问google.com,因此我们用 proxy.remotehost.com 做一个跳转。

复制

因此我们利用的ssh动态端口转发技术来达到这个目的,在本地开启30002端口,并且将端口关联到proxy.remote.com的22端口上,通过浏览器的设置,将所有的请求都转发到 127.0.0.1:30002上,通过ssh隧道,会将数据包传递到proxy.remotehost.com:22 上。proxy 服务器会随机开启一个端口访问google.com.然后将数据返回给proxy,然后再返回给浏览器,这就是代理的转发。

问题

账号已登录成功就被退出了

ssh -D 30002 -l username proxy.remotehost.com -N

复制

* 增加-N 选项 参数是 不请求shell界面,不执行远程命令。这个只是在端口转发的时候使用,其他不会请求

让该进程在后台运行

ssh -D 30002 -l username proxy.remotehost.com -Nf

复制

给ssh 增加http代理

在某些场景下,PC 无法直接访问到ssh服务器,但是只有http代理可以访问,那么我们要建立这个socket5的端口转发只能为他增加一个代理

ssh -D 30002 -l username proxy.remotehost.com -Nf -o ProxyCommand="connect -H web-proxy.oa.com:8282 %h %p "

复制

其中 ProxyCommand 执行了使用connect 程序来进行代理,通常还可以使用 corkscrew 来达到相同的效果。

* 安装 ubuntu 下

复制

apt-get install connect-proxy

复制

* mac下安装corkscrew

复制

brew install corkscrew

复制

连接一段时间后 自耦东断开了

ssh -D 30002 -l username proxy.remotehost.com -Nf -o ProxyCommand="connect -H web-proxy.oa.com:8080 %h %p " -o ServerAliveInterval=60

复制

-X 转发

a

真实场景

A—— 10.0.0.11

B: 10.0.0.2 可以访问内网A 也可以联网到B

B: 115.xx.x 公有云机器

C: 笔记本

A——可以联网–可以访问——B

C——可以联网 可以访问—-B

B 无法访问A

B 无法访问C

目标:C想访问A

  1. 在A上建立动态连接
 ssh -D 0.0.0.0:1080 root@127.0.0.1

 在A 上建立自身的动态连接

复制

  1. 在B上建立远程连接到公有云C

复制

ssh -R 0.0.0.0:30000:10.0.0.1:1080 root@115.X.X.X

在B上建立远程转发,在115.X.X.X上启用建立端口 30000 目标主机为 10.0.0.1

复制

  1. 在公有云上确认是否30000 端口建立成功

复制

ss -luntp |grep 30000

复制

  1. 在笔记本上 建立本地连接到公有云30000端口

复制

ssh -L 11080:127.0.0.1:30000 root@115.x.x.x

在本机笔记本上开启端口11080 将所有访问11080的流量转发到 115.XX.X.X 30000 端口上

复制

  1. 在笔记本上连接到 A机器

复制

ssh -o ProxyCommand=’/usr/bin/nc -X 5 -x 127.0.0.1:11080 %h %p’ root@10.0.0.1

复制

参考

ssh权威指南

https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html

http://www.zsythink.net/archives/2450

https://www.chenyudong.com/archives/linux-ssh-port-dynamic-forward.html