城东书院 www.cdsy.xyz
SSH 隧道
使用 SSH 可以进行端口转发,从而实现流往某端口的数据被加密后传向另一机器,这个过程形似构造了一条通道,因此也称之为 SSH 隧道(SSH Tunnel)
使用 SSH 隧道可以让数据被加密并透明地传输到远端系统
SSH 隧道的类型
SSH 隧道有三种类型 :
- 动态端口转发 (socks 代理)
- 本地端口转发
- 远程端口转发
参数提前说明
- bind_address – 可选的, 监听的网卡地址
- 省略 – 取决于 GatewayPorts 的设置(man 手册可以看到,但是没有在 Ubuntu 14.04中找到)
- localhost/127.0.0.1 – 监听 127.0.0.1, 仅能用于本地
- 0.0.0.0/* – 监听本机所有网络接口
- hostX – 主机 hostX 的 ip 或 域名
- hostX_port – 主机hostX 的空闲端口
- 0 - 1023 : 特权端口,只能 root 用户才能进行端口转发
- 1024 - 65535 : 选择一个没被占用的端口
- user@hostX – 用户名为 user 可以登录主机 hostX
动态端口转发 – SOCKS 代理
支持 SOCKS4 和 SOCKS5 代理
假设
- 存在两台主机 host1, host2
- host1 可以 SSH 连接 host2
可以使 host1 某端口的数据发往 host2, host2 根据其应用程序协议发出到指定地址, 就好像是从 host2 直接发出的数据
可以认为我们搭建了一个代理服务器(Proxy Server)
于是就有了下面这个命令 (host1上执行)
命令原型
host1 $ ssh -D [bind_address:]host1_port user@host2
动态端口转发的过程 :
- host1 申请了一个 socket 来监听 bind_address:host1_port
- host1 与 host2 建立一条 ssh 隧道
- 当 host1 有请求 bind_address:host1_port, 请求数据会从 ssh 隧道发往 host2
- host2 收到数据, 根据数据的应用程序协议去发送数据到指定的地址
- 返回数据会按原有路径返还
实际使用
host1 $ ssh -D 127.0.0.1:7070 user@host2
- chrome 上使用 proxy SwitchySharp 进行代理设置
- 新建情景模式 proxy, 在 socks代理 那行填入 127.0.0.1 和 端口那栏填入 7070
- 点击 proxy SwitchySharp 的头标, 勾选 proxy
- Ubuntu 下使用 proxychains 为应用程序设置代理
- 安装 – sudo apt-get install proxychains
- 修改配置文件(/etc/proxychains.conf)的 [ProxyList] 为自己的代理 : socks4 127.0.0.1 7070
- 让程序使用代理 : proxychains program-name
- 可以使用 curl 进行下载验证
$ curl --socks5 localhost:7070 download-link
本地端口转发
假设
- 存在三台主机 host1, host2, host3
- host1 和 host3 不能通信
- host2 可以同时和 host1 与 host3 通信
因此, 我们可以借助 host2 实现 host1 和 host3 的通信
于是就有了下面这个命令原型(host1 上执行)
命令原型
host1 $ ssh -L [bind_address:]host1_port:host3:host3_port user@host2
本地端口转发的过程 :
- 绑定 host1 的 bind_address:host1_port, 与 host2 构建一条 SSH 隧道
- 当我们请求 bind_address:host1_port 时, 请求的数据通过 SSH 隧道到达 host2,host2 就会把数据发送到 host3 的 host3_port
- 返回的数据按照原路返回
实际使用
- 通过访问 host1 本地 8080 端口来访问 host3 的 80 端口(host3 已经安装 Web 服务)
host1 $ ssh -L 8080:host3:80 user@host2
执行完成,在 host1 浏览器中 输入 localhost:8080 即可看到 host3 的 Web 页面
如果使用 xshell 等工具访问 host1, 那么可以使用 curl localhost:8080 来查看 Web 内容
- host1 使用 ssh 登录 host3 :
host1 $ ssh -L 2030:host3:22 user@host2
现在你可以在另开一个 host1 终端输入 : ssh -p 2030 user@host3 去登录 host3
远程端口转发
假设
- 存在三台主机 host1, host2, host3
- host1 和 host3 不能相互访问
- host2 可以和 host3 相互访问
- host2 可以 ssh 访问 host1
- host1 不可以访问 host2
这样的话, host1 就不可以 ssh 连接 host2 了,所以本地端口转发就不能用了
而 host2 可以 ssh 连接 host1, 那么 host1 就可以借助这条连接与 host3 进行通信
这就是 SSH 的远程端口转发
于是就有了下面这个命令原型 (host2 上执行)
命令原型
host2 $ ssh -R [bind_address:]host1_port:host3:host3_port user@host1
远程端口转发的过程 :
- host2 与 host1 构建了一条 ssh 隧道
- host1 申请了一个 socket 随时监听 bind_address:host1_port
- 当 host1 有请求 bind_address:host1_port 时, 请求的数据会从 ssh 隧道 发往 host2
- host2 收到数据, 然后转发数据到 host3:host3_port
- 返回数据按原路径返还
实际应用
- 通过访问 host1 本地 8080 端口来访问 host3 的 80 端口(host3 已经安装 Web 服务)
host2 $ ssh -R 8080:host3:80 user@host1
执行完成,在 host1 浏览器中 输入 localhost:8080 即可看到 host3 的 Web 页面
如果使用 xshell 等工具访问 host1, 那么可以使用 curl localhost:8080 来查看 Web 内容
- host1 使用 ssh 登录 host3 :
host2 $ ssh -R 2030:host3:22 user@host1
现在你可以在另开一个 host1 终端输入 : ssh -p 2030 user@host3 去登录 host3
SSH 一些辅助参数
相关命令
- 查看端口是否占用 : sudo lsof -i :port
- 使用 curl 下载文档
代理软件
- proxycap – windows
- Proxifier – windows/OS – 全局代理
- proxychains – Linux
- readsocks – Linux
- tsocks – Linux – 全局代理
- Proxy SwitchySharp – chrome
- curl 支持 socks4/SOCKS5 等代理下载 – 太棒了, 命令行用起来很方便
城东书院 www.cdsy.xyz