TT Lab
开始
学习 学习路径 课程

SSH 与文件传输

往三个方向挖隧道

在 TT Lab 中继续学习

目标

把 -L、-R、-D 三种转发都亲手创建一遍,并亲自确认每条隧道在哪里打开端口。

为什么重要

只要方向不弄混,端口转发都很简单。-L 在本地一侧打开端口,-R 在对方一侧打开端口,-D 则在本地一侧建立 SOCKS 代理。而且 -L 中间的主机名是以 SSH 服务器为基准解析的——即使这个名字在本地解析不了也没关系。光是这一点,就几乎涵盖了经由跳板机(bastion)连接的全部内容。

在这个实验中,SSH 服务器是 127.0.0.1:2222。由于服务器和客户端是同一台主机,-R 的结果也可以立即确认。

步骤

  1. 以 9200 端口、绑定 127.0.0.1 启动 /opt/fixtures/nt-http/server.py。它就是隧道的目的地。
  2. 用本地转发在后台打开 19200 → 127.0.0.1:9200 隧道,并把 curl -s http://127.0.0.1:19200/ok 的结果保存到 /root/tun/local.txt。
  3. 确认是谁打开了 19200,并保存到 /root/tun/proof.txt。进程名称中必须能看到 ssh。
  4. 用远程转发在 SSH 服务器一侧打开 19300 并转发到 127.0.0.1:9200,再把 curl -s http://127.0.0.1:19300/ok 的结果保存到 /root/tun/remote.txt。
  5. 用动态转发(SOCKS)打开 11080,把通过该代理请求 http://127.0.0.1:9200/ok 的结果保存到 /root/tun/socks.txt。
  6. 再打开一个本地转发,这次绑定到所有地址,转发到 19201 → 127.0.0.1:9200,并把用自己接口的 IP 连接的结果保存到 /root/tun/gateway.txt。
  7. 把当前正在运行的 ssh 隧道进程的命令行保存到 /root/tun/inventory.txt。至少要有 4 行(两个 -L、一个 -R、一个 -D)。
  8. 把 /root/tun/report.txt 写成下面这 3 行。每个值表示该选项打开端口的一侧。 L=local / R=remote / D=local

参考

启动后端服务

以 9200 端口、绑定 127.0.0.1 启动 /opt/fixtures/nt-http/server.py。它就是隧道的目的地。

需要一个作为隧道目的地的服务。即使只在回环接口上启动,经过隧道也能访问到。

本地转发

用本地转发在后台打开 19200 → 127.0.0.1:9200 隧道,并把 curl -s http://127.0.0.1:19200/ok 的结果保存到 /root/tun/local.txt。

-L 之后用冒号连接三个值。中间的主机以 SSH 服务器为基准解析。

确认隧道打开的端口

确认是谁打开了 19200,并保存到 /root/tun/proof.txt。进程名称中必须能看到 ssh。

用 ss 查看监听套接字,就会显示进程名称。隧道的端口是由 ssh 进程打开的。

远程转发

用远程转发在 SSH 服务器一侧打开 19300 并转发到 127.0.0.1:9200,再把 curl -s http://127.0.0.1:19300/ok 的结果保存到 /root/tun/remote.txt。

-R 在 SSH 服务器一侧打开端口。在这个实验中,服务器就是同一台主机,所以可以立即确认结果。

SOCKS 代理

用动态转发(SOCKS)打开 11080,把通过该代理请求 http://127.0.0.1:9200/ok 的结果保存到 /root/tun/socks.txt。

-D 只接收一个端口。curl 有指定 SOCKS5 代理的选项。

绑定到外部地址

再打开一个本地转发,这次绑定到所有地址,转发到 19201 → 127.0.0.1:9200,并把用自己接口的 IP 连接的结果保存到 /root/tun/gateway.txt。

可以在 -L 的前面额外写上绑定地址。也可以使用 -g 选项。

整理隧道列表

把当前正在运行的 ssh 隧道进程的命令行保存到 /root/tun/inventory.txt。至少要有 4 行(两个 -L、一个 -R、一个 -D)。

查看当前正在运行的 ssh 进程的命令行,就能知道每条隧道的方向。

三个方向的对照表

把 /root/tun/report.txt 写成下面这 3 行。每个值表示该选项打开端口的一侧。 L=local / R=remote / D=local

关键区别在于端口打开在哪里。值请写 local 或 remote。