端口转发 (隧道)
SSH 隧道的数学与架构指南
SSH 端口转发(隧道)通常被误解为“魔法”。实际上,它是一种通过加密流将网络套接字从一台机器映射到另一台机器的稳健方法。
Netcatty 提供了一个 图形化隧道管理器,使这些临时连接变得持久、可见且易于管理。
三种转发模式
理解隧道的“方向”是最难的部分。让我们来详细拆解。
1. 本地转发 (Local Forwarding, -L)
“将远程拉取到本地”
你希望像访问笔记本电脑上的服务一样,访问运行在远程服务器(或远程服务器可触达的机器)上的服务。
- 架构:
- Netcatty 在你的笔记本电脑上开启一个监听器(例如
localhost:9000)。 - 当你连接到
localhost:9000时,Netcatty 将字节流转发给 SSH 服务器。 - SSH 服务器开启到目标的连接(例如
db-prod:5432)。
- Netcatty 在你的笔记本电脑上开启一个监听器(例如
- 场景:RDS 访问
- 目标: 将 TablePlus 连接到位于 VPC 内部的 AWS RDS 实例 (
mydb.aws.com)。 - 配置:
- SSH 主机: 你的 EC2 跳转机。
- 类型: 本地 (Local)。
- 本地端口:
54320(任意空闲端口)。 - 远程主机:
mydb.aws.com(由跳转机负责 DNS 解析!)。 - 远程端口:
5432。
- 使用方法: 在 TablePlus 中连接到
127.0.0.1的54320端口。
- 目标: 将 TablePlus 连接到位于 VPC 内部的 AWS RDS 实例 (
2. 远程转发 (Remote Forwarding, -R)
“将本地推送到远程”
你希望允许远程服务器(或任何能触达它的人)访问运行在你笔记本电脑上的服务。
- 架构:
- SSH 服务器在它自己的接口上开启一个监听器(例如
0.0.0.0:8080)。 - 当有人访问
http://远程服务器:8080时,字节流通过隧道倒流回 Netcatty。 - Netcatty 连接到你的本地服务(例如
localhost:3000)。
- SSH 服务器在它自己的接口上开启一个监听器(例如
- 场景:Webhook 测试
- 目标: Stripe 需要访问一个 Webhook URL,但你的代码运行在
localhost:3000。你还不想部署。 - 配置:
- 类型: 远程 (Remote)。
- 远程端口:
9000。 - 本地主机:
127.0.0.1。 - 本地端口:
3000。
- 使用方法: 告诉 Stripe 将 Webhook 发送到
http://你的服务器IP:9000。
- 目标: Stripe 需要访问一个 Webhook URL,但你的代码运行在
GatewayPorts
为了让远程转发接受来自其他计算机的连接(而不仅仅是服务器本身),服务器的 sshd_config 必须设置 GatewayPorts yes。否则,它只会绑定到回环地址 (127.0.0.1)。
3. 动态转发 (Dynamic Forwarding, -D)
“瑞士军刀 / SOCKS 代理”
Netcatty 不再映射一个特定的端口,而是充当 SOCKS5 代理服务器。它会根据你发送给它的流量实时确定目的地。
- 架构:
- Netcatty 开启一个 SOCKS 监听器(例如
localhost:1080)。 - 你配置 Chrome/Firefox 使用此代理。
- 当你在 Chrome 中输入
http://内部人力资源门户/时,浏览器请求 Netcatty 获取它。 - Netcatty 隧道化该请求;SSH 服务器执行查找并获取数据。
- Netcatty 开启一个 SOCKS 监听器(例如
- 结果: 你是以服务器的 IP 地址在浏览网页。非常适合绕过有 IP 白名单限制的防火墙。
故障排除
“地址已被占用 (Address already in use)”
- 原因: 你选择的本地端口(例如 8080)已被其他应用(如 Docker 或 Node.js)占用。
- 解决方法: 挑选一个随机的高位端口,如
54321。
“连接被拒绝 (Connection Refused)” (目标侧)
- 原因: 远程主机(例如
mydb.aws.com)屏蔽了跳转机的 IP。 - 检查: 验证目标上的安全组 / 防火墙规则,确保允许来自跳转机安全组的 5432 端口访问。
“特权端口”
- 除非你以 root 身份运行 Netcatty(不推荐),否则你无法绑定到小于 1024 的端口(如 80 或 443)。请使用大于 1024 的端口。