跳转到内容

反向隧道

家宽、NAT 小鸡、没有公网入站的机器很适合当落地,但中转服务器连不进去 —— 「端口转发」要求入口能直接访问目标的端口。反向隧道把建立连接的方向倒过来:由目标服务器主动连到入口服务器,在两台之间拉起一条 WireGuard 隧道,入口再经这条隧道把流量转给目标。

适合这些场景:

  • 落地机在家宽 / 运营商 NAT 后面,没有公网 IP,或没法做端口映射
  • 落地机有公网 IP,但不想对外开放节点端口
  • 落地机的公网 IP 经常变,不想每次改转发目标

反向隧道在「节点管理 → Tunnel 管理」里创建和管理,是管理员功能。

名称 说明
入口服务器 有公网地址、客户端实际连接的那台(中转)。它监听一个 UDP 端口等目标连上来
目标服务器 在 NAT 后面、主动拨出的那台(落地)。不需要开放任何入站端口
内网地址 隧道通了以后,两台各多一个只在这条隧道里有效的地址:入口是 198.18.x.y,目标是 198.19.x.y
隧道端口 入口上给隧道用的 UDP 端口,默认从 51820 起自动挑一个空闲的;连到同一台入口的所有目标共用它

隧道只负责把两台服务器「接到同一个内网」。转发本身仍然是普通的端口转发:入口上的 tunnel 入站,目标地址写成目标服务器的内网地址。

客户端 ──节点凭据──▶ 入口服务器 :监听端口
│ 端口转发,目标 = 198.19.x.y:节点端口
▼
WireGuard 隧道(目标主动拨入、自动保活)
│
▼
目标服务器上的节点 ──▶ 出网

节点还是建在目标服务器上的那个节点:用户凭据、流量统计、限速都和直连它时一样。

  • 入口与目标都是面板里的服务器,Agent 在线,且版本支持反向隧道(不支持时创建会提示是哪一台)
  • 目标服务器能访问入口服务器的隧道端口(UDP)。入口的防火墙 / 云厂商安全组要放行这个 UDP 端口,创建后面板会告诉你端口号
  • 两台的 Agent 以 root 运行,系统有 /dev/net/tun。Docker 部署的 Agent 需要加上 --cap-add NET_ADMIN --device /dev/net/tun
  • 目标服务器不需要公网 IP,也不需要开放任何入站端口

教程:把家宽落地节点挂到中转上

Section titled “教程:把家宽落地节点挂到中转上”

下面以「入口 AgentA-Entry(有公网 IP)+ 目标 AgentB-Exit(在 NAT 后面)」为例,把目标上的一个 Shadowsocks 节点通过入口对外提供。

照常在「节点管理 → 添加节点」里,给目标服务器建一个节点(这里是 Shadowsocks 2022,端口 56631)。目标在 NAT 后面,这个节点暂时从外面连不上,不要紧。

2. 建一条走反向隧道的端口转发

Section titled “2. 建一条走反向隧道的端口转发”

打开「节点管理 → Tunnel 管理 → 端口转发」:

  1. 选择入口服务器:选中转(AgentA-Entry)
  2. 模式:选「反向隧道」
  3. 入站 tag:随便起个名字,如 home(会生成 tunnel-home)
  4. 监听端口:客户端连入口时用的端口,如 50740
  5. 目标:从已有节点里选第 1 步建的节点,地址和端口会自动填好;下方会提示「由 AgentB-Exit 主动连到入口,转发走它的内网地址」
  6. 保持「新增节点」勾选,点「应用」

端口转发的反向隧道模式截图

端口转发选「反向隧道」模式:入口 AgentA-Entry,监听 50740,目标选 AgentB-Exit 上的 Shadowsocks 节点

点「应用」后面板会依次做三件事:

  • 让目标服务器拨一条隧道到入口(这两台之间已经有隧道就直接用)
  • 在入口上建一条端口转发,目标是目标服务器的内网地址
  • 复制一个节点,地址改成「入口地址 : 监听端口」,凭据与原节点相同

第一次给这台入口建隧道时,右下角会提示要放行的 UDP 端口。

到入口服务器的防火墙 / 云厂商安全组里,放行提示的 UDP 端口(默认 51820)。只需要放行这一个,以后连到这台入口的其它目标都用它。

回到「Tunnel 管理」列表,最上面是反向隧道,下面是刚建的端口转发:

Tunnel 管理列表里的反向隧道截图

反向隧道显示「已连接」,有 1 条端口转发在用;下面的 tunnel-home 目标显示为「AgentB-Exit (反向隧道)」,延迟 188ms

  • 反向隧道那一条显示已连接,说明目标已经连上来了。一般几秒内完成
  • 点端口转发右侧的仪表图标做延迟探测:测的是入口经隧道到目标节点端口的延迟,有数值就说明整条路是通的

节点列表里多了一个名字带 -tunnel-home 的节点:服务器地址是入口的地址和监听端口,下面一行小字是它背后的原地址。

节点列表里的中转节点截图

上面是新生成的节点(入口地址 :50740,下方为原地址),下面是目标服务器上的原节点

把这个新节点加进订阅或套餐即可。原节点(目标的公网地址)在 NAT 后面本来就连不上,可以隐藏或不放进订阅。

也可以先把隧道建起来,以后再建转发:「Tunnel 管理 → 反向隧道」,选目标服务器和入口服务器,点「建立反向隧道」。

建立反向隧道表单截图

只建隧道:目标选在 NAT 后面的那台,入口选中转

隧道建好后,列表里会显示目标的内网地址(如 198.19.0.1)。之后在这台入口上:

  • 用「端口转发 → 新增 tunnel」并把目标地址手动填成这个内网地址,效果和反向隧道模式一样
  • 「链式转发」的最终目标也可以填这个内网地址,让多跳链路最后落到 NAT 后面的机器

同一对服务器之间只有一条隧道,可以同时承载任意多条端口转发。一台入口可以连多台目标,一台目标也可以同时连多台入口。

显示 含义
已连接 最近 3 分钟内握过手,隧道可用
未连接 目标还没连上来,或已经断开超过 3 分钟
状态未知 读不到入口服务器的状态(入口离线等),下方会给出原因
N 条端口转发在用 入口上目标是这条隧道内网地址的端口转发数量

隧道由两端的 Agent 维持:目标每 25 秒发一次保活;目标重启、换 IP 后会自动重新连上;Agent 重启后不等主控下发就会自行恢复隧道。

  • 删端口转发:在列表里点它右侧的删除。隧道保留,其它转发不受影响
  • 删隧道:点反向隧道右侧的删除。两端的隧道会被拆掉,入口上所有指向这个内网地址的端口转发都会不通(不会自动删除,需要手动清理)
  • 用「新增节点」生成的节点不会随转发一起删,不用了请到节点列表里删除
  • 隧道是 UDP(WireGuard)。入口与目标之间 UDP 被屏蔽或严重限速的线路不适合用
  • 入口能访问目标上的其它服务:隧道通了以后,入口服务器可以用内网地址访问目标上所有监听在 0.0.0.0 的端口,不只是节点端口。目标所在局域网里的其它设备访问不到。入口服务器请只用自己信得过的机器
  • 来源地址:目标节点看到的客户端地址是入口的内网地址,不是用户的真实 IP。按来源 IP 做的限制(如设备数)在这类节点上不准
  • 只放行端口转发本身:服务器默认禁止代理流量访问内网地址,面板只给指向隧道内网地址的端口转发单独放行。入口上普通节点的用户访问不到隧道另一头
  • 接收到的分享服务器暂不支持反向隧道

按顺序检查:

  1. 入口的防火墙 / 安全组是否放行了列表里显示的 UDP 端口
  2. 目标服务器是否在线(服务管理里看)
  3. 目标服务器能不能访问入口的地址:列表里「目标 → 入口」后面那个地址就是它要连的。入口用域名时,确认域名解析到的是入口的公网 IP

提示某台的 agent 不支持反向隧道

Section titled “提示某台的 agent 不支持反向隧道”

那台服务器的 Agent 离线或版本过低。到「服务管理」里确认在线并升级 Agent。

提示「隧道没起来:创建隧道网卡失败」

Section titled “提示「隧道没起来:创建隧道网卡失败」”

Agent 没有权限创建网卡。常见于容器里的 Agent:给容器加上 --cap-add NET_ADMIN --device /dev/net/tun 后重启;LXC 容器需要在宿主机上为它开启 TUN。

  • 用列表里的延迟探测看「入口 → 目标节点端口」通不通:不通多半是目标上的节点没在运行,或端口填错
  • 确认客户端用的是新生成的节点(入口地址 + 监听端口),而不是原节点
  • 确认入口的监听端口(如 50740)在入口的防火墙 / 安全组里放行了 —— 这个端口是给客户端连的,TCP 和 UDP 都要放行