端口转发
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
- 在A上建立动态连接
ssh -D 0.0.0.0:1080 root@127.0.0.1
在A 上建立自身的动态连接
复制
- 在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
复制
- 在公有云上确认是否30000 端口建立成功
复制
ss -luntp |grep 30000
复制
- 在笔记本上 建立本地连接到公有云30000端口
复制
ssh -L 11080:127.0.0.1:30000 root@115.x.x.x
在本机笔记本上开启端口11080 将所有访问11080的流量转发到 115.XX.X.X 30000 端口上
复制
- 在笔记本上连接到 A机器
复制
ssh -o ProxyCommand=’/usr/bin/nc -X 5 -x 127.0.0.1:11080 %h %p’ root@10.0.0.1
复制
参考
http://www.zsythink.net/archives/2450