参考文章:
https://ryaninf.github.io/2019/07/08/%E6%B5%85%E8%B0%88%E4%BB%A3%E7%90%86%E9%9A%A7%E9%81%93%E7%9A%84%E5%87%A0%E7%A7%8D%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF/(代理隧道)
https://www.cnblogs.com/oxspirt/p/10260053.html(借用例子彻底明白原理)
核心命令解释贴在了最后(直接借用的第三篇文章的内容)
实操:
通过命令行ssh转发流量,实现
一层跳板
这一步要注意端口的占用可能会造成拉闸
ssh -p 22 -Nf -L 0.0.0.0:7777:阿里云IP:22 root@阿里云IP 访问本地7777相当于访问阿里云服务器的22端口
ssh -p 7777 -Nf -D 127.0.0.1:9999 root@127.0.0.1 本地9999开启S5监听,把流量发送到本地7777,因为做了ssh本地转发,相当于发送到阿里云服务器的22端口

Proxifier设置代理服务器为本地9999端口,检测发现代理可用,代理上火狐浏览器,去测试IP

火狐浏览器的IP地址检测如下,是跳板机(阿里云)的IP,代理成功:

中间再过一个虚拟机,实现
两层跳板
ssh -p 22 -Nf -L 0.0.0.0:7777:
192.168.177.128
:7777 kali@192.168.177.128
访问本地7777相当于访问虚拟机
192.168.177.128的7777(我的虚拟机是kali,默认把root关了,懒得调,直接连接普通账户kali了)

ssh -p 22 -Nf -L 0.0.0.0:7777:阿里云IP:22 root@阿里云IP
在虚拟机上执行这条命令,访问虚拟机本地的7777相当于访问阿里云服务器的22端口

ssh -p 7777 -Nf -D 127.0.0.1:9999 kali@127.0.0.1
本地9999开启S5监听,把流量发送到本地7777,一通映射下去,就把流量扔到了阿里云服务器的22端口,所以这里的密码填写的是阿里云服务器的密码

注意:
要先做完端口转发,再做S5代理转发,不然你的隧道的出口如果不是跳板机(阿里云主机)的22端口的话,S5转发的流量是出不去的,会出现下列报错:

报错内容——连接失败 我的理解是是这条隧道是ssh隧道,你隧道的尽头咋也得是个ssh的接收端口才行,不能太离谱
测试通过:

火狐浏览器走代理,IP地址正确:

继续加VPS,实现更
多层跳板
ssh -p 22 -Nf -L 0.0.0.0:7777:下一跳IP地址
:7777 用户名@下一跳IP地址 跳板间建立起端口转发
ssh -p 22 -Nf -L 0.0.0.0:7777:最后的出口IP:22 root@
最后的出口
IP 最后的出口处,把流量塞到22端口,建立起ssh隧道
ssh -p 7777 -Nf -D 127.0.0.1:9999 root@127.0.0.1 在本地建立S5的流量转发
最终实现,流量从本地9999走S5代理进来,层层转发到ssh隧道的出口,一套流量代理下来,“我在本地做操作”就变成了经过层层跳板后“登录到出口跳板做操作”
核心命令解释
本地转发(端口转发)
本地监听指定端口,该端口收到的请求会通过远程服务器转发到另一台机器的指定端口上
-
语法:
ssh [-p ssh_port] -L [bind_address:]port:host:hostport user@remote_host
解释:
port:本地监听的端口
bind_address:监听端口使用的本地地址(如:192.168.1.2,127.0.0.1,0.0.0.0), 不设置默认为回环地址 127.0.0.1
host:转发的目标IP
hostport:转发的目标端口
注意:
host:hostport 是远程主机 user@remote_host:ssh_port 所能访问到的地址(包括 user@remote_host自己),本地主机不一定能访问该地址
-
示例:
ssh -p 23 -Nf -L 0.0.0.0:3000:123.123.123.124:3001 root@123.123.123.123
说明:
1. 通过 23 端口 ssh 远程服务器 123.123.123.123,使用帐号 root 登录
2. 本地监听端口 0.0.0.0:3000
3. 123.123.123.124 和 123.123.123.123 在一个局域网下,而本地不能直接访问 123.123.123.124
4. 123.123.123.124 主机通过 3001 端口开放服务
5. 调用链路:本地访问 --> 127.0.0.1:3000 -- ssh 隧道 --> 123.123.123.123 -- 转发 --> 123.123.123.124:3001
上面示例中相当于将远程主机 123.123.123.124 的 3001 端口映射为本地的 3000 端口,这样就可以通过局域网访问被限制的公网服务了。
远程转发(反向代理)
远程服务器上监听指定端口,该端口收到的请求会通过本地转发到另一台机器的指定端口上
-
语法:
ssh [-p ssh_port] -R [bind_address:]port:host:hostport user@remote_host
解释:
语法和 -L 一样,只不过监听侧和目标侧的网络对换而已
port:在远程主机 user@remote_host 上监听的端口
bind_address:远程主机 user@remote_host 监听端口使用的地址(如:remote_host,127.0.0.1,0.0.0.0)。
和 -L 有点区别,指定IP需要在远程主机上修改 /etc/ssh/sshd_config 中的配置:GatewayPorts。"yes" 表示 强制为 0.0.0.0; 默认为 "no" 表示强制为回环地址 127.0.0.1;"clientspecified" 表示由客户端决定
host:转发的目标IP
hostport:转发的目标端口
注意:
host:hostport 是本地主机所能访问到的地址(包括本机),远程主机 user@remote_host:ssh_port 不一定能访问该地址
-
示例:
ssh -p 23 -Nf -R 172.17.0.1:3000:192.168.1.100:3001 root@123.123.123.123
说明:
1. 通过 23 端口 ssh 远程服务器 123.123.123.123,使用帐号 root 登录
2. 123.123.123.123 监听端口 172.17.0.1:3000 (远程服务器运行 docker , 多了一个虚拟网络 172.17.0.0)
3. 192.168.1.100 和 本地主机 在一个局域网下,而 123.123.123.123(外网) 不能直接访问 192.168.1.100(内网)
4. 192.168.1.100 主机通过 3001 端口开放服务
5. 调用链路:远程服务器中访问 --> 172.17.0.1:3000 -- ssh 隧道 --> 本地 -- 转发 --> 192.168.1.100:3001
上面示例中相当于将局域网主机 192.168.1.100 的 3001 端口映射为远程服务器 123.123.123.123 的 3000 端口,这样就可以通过公网来访问局域网中的服务了。
动态转发(S5代理)
监听本地的指定端口,本机将作为 SOCKS5 服务器使用
-
语法:
ssh [-p ssh_port] -D [bind_address:]port user@remote_host
解释:
port:本地监听的端口
bind_address:监听端口使用的本地地址(如:192.168.1.2,127.0.0.1,0.0.0.0), 不设置默认为回环地址127.0.0.1
注意:
启动 socks5 代理
代理使用示例:
curl --socks5 bind_address:port
baidu.com
-
示例
ssh -p 23 -Nf -D 127.0.0.1:3000 root@123.123.123.123
说明:
1. 通过 23 端口 ssh 远程服务器 123.123.123.123,使用帐号 root 登录
2. 本地监听端口 127.0.0.1:3000
3. 调用链路:本地局域网中访问任意http服务 -- 使用代理 --> 172.17.0.1:3000 -- ssh 隧道 --> 123.123.123.123 -- 转发 --> 目标http服务
上面示例中相当于开启了一个代理服务器,比起
本地转发
需要指定具体端口来说更加方便。