第19章 内网穿透与隧道:frp / gost / SSH 隧道 / ngrok

学习目标

  • 理解内网穿透的核心难题(NAT 后无法被动连入)与"反向隧道"解法
  • 掌握 SSH 隧道三式:-L(本地转发)、-R(远程转发=穿透)、-D(SOCKS)
  • 会用 frp 把内网服务安全暴露到公网,理解 frps/frpc 架构
  • 分清"隧道"与"代理"的关系,及穿透的安全风险

前置知识


原理

核心难题:NAT 后的服务无法被动连入

内网服务(家里的 NAS、公司内网的 Web、开发机的本地服务)通常没有公网 IP,躲在 NAT 后面。NAT 的规则是"内可主动出、外不可主动入"——所以外部根本无法主动连到它。

   公网 Client ──想访问──▶ ❌ [NAT/防火墙] ╳ 内网服务(无公网IP,连不进来)

解法:反向隧道(内网主动连出,建立通路)

既然"外不可入",那就让内网主动连出到一台有公网 IP 的中转服务器,建立一条隧道;之后外部请求打到中转服务器,再经隧道反向送回内网:

   ① 内网 frpc ──主动连出──▶ [公网中转 frps] ◀──② 外部请求──  公网 Client
                              │
   ③ 请求经隧道反向回内网 ◀───┘
   内网服务 ◀── frpc 转发 ──┘

这就是一切内网穿透工具的共同骨架:内网主动建隧道 + 公网中转 + 反向转发。它和 第01章 的"隧道"一脉相承——只是方向反过来用。

SSH 隧道三式(自带、最方便)

SSH 是最唾手可得的隧道工具,三种转发方向要分清:

-L 本地转发:把"本地端口"的访问,经 SSH 转到"远端可达的目标"
   ssh -L 8080:db.internal:5432 user@jump   → 访问本地 8080 = 访问 jump 能看到的 db:5432
   用途:从本地访问远端内网服务

-R 远程转发:把"远端端口"的访问,经 SSH 转回"本地可达的目标" ← 这就是内网穿透!
   ssh -R 9000:localhost:3000 user@public   → 访问 public:9000 = 访问你本地的 3000
   用途:把本地/内网服务暴露到公网中转机

-D 动态转发:在本地起一个 SOCKS5 代理(第06章)
   ssh -D 1080 user@jump                     → 本地 1080 成为 SOCKS5 出口
   用途:通用代理

记忆法:-L 是"拉"(把远端服务拉到本地端口),-R 是"推"(把本地服务推到远端端口),-R 才是穿透。

frp:专业内网穿透

SSH -R 够用但功能有限(暴露多服务、HTTP 虚拟主机、UDP 都不方便)。frp 是专业方案,国内最常用:

  • 架构:frps(公网服务端)+ frpc(内网客户端),frpc 主动连 frps 建隧道
  • 协议:支持 TCP/UDP/HTTP/HTTPS/STCP(点对点加密)/XTCP(P2P 打洞)
  • 能力:多服务复用一个 frps、HTTP 按域名路由、加密、鉴权、Web 管理面板、带宽限制
        公网                         内网
  ┌──────────────┐            ┌──────────────────┐
  │ frps :7000   │◀──控制连接──│ frpc             │
  │ frps :80(http)│            │  → localhost:8080│  内网 Web
  │ frps :6000(tcp)│           │  → localhost:22  │  内网 SSH
  └──────────────┘            └──────────────────┘
   外部访问 frps:80 → 隧道 → 内网 8080

gost:隧道/代理瑞士军刀

gost 是多功能的代理/隧道工具,支持几乎所有协议(HTTP/SOCKS/SS/relay/tunnel)和转发链(forward chain)——可把多个代理串成一条链,每跳用不同协议。适合复杂的代理组合场景。

ngrok:SaaS 化穿透

ngrok 把穿透做成了云服务:你不用自己搭公网中转,一行命令就把本地服务暴露到 ngrok 分配的公网域名——特别适合调试 Webhook、临时演示:

ngrok http 8080      # 立刻得到一个 https://xxxx.ngrok.io 指向你本地 8080

代价是依赖第三方服务、免费版有限制。

隧道 vs 代理:到底什么关系

  • 代理(前 18 章主角):代收代发,可能理解/改写内容(第01章)
  • 隧道:在两点间打通一条透明通路,把流量原样运过去(第04章 CONNECT)
  • 内网穿透 = 反向使用的隧道:方向是"从内向外建、从外向内用"

三者技术同源,常组合:穿透隧道里可以跑代理协议(如 frp 隧道里暴露一个 SOCKS5)。

⚠️ 穿透的安全风险

把内网服务暴露到公网 = 主动打开一个攻击面:

  • 暴露的服务必须有认证(别把无密码的内网后台直接暴露)
  • 隧道本身要加密(SSH 自带加密;frp 用 tls/stcp)
  • 中转服务器是单点,被攻破则隧道尽失
  • 企业环境中,未经授权的穿透是绕过出网管控的后门,安全团队会重点监控

️ 实现 / 命令

实验一:SSH -R 把本地服务暴露到公网中转机

# 本地跑了个服务在 3000,想让外部通过公网机 public 的 9000 访问它
ssh -N -R 9000:localhost:3000 user@public
# 注意:frps 端 sshd 要开 GatewayPorts yes,9000 才能对外(否则只绑 127.0.0.1)

# 在任意能访问 public 的机器上:
curl http://public:9000/        # = 访问你本地的 3000

实验二:frp 暴露内网 Web 与 SSH

# frps.toml(公网服务器)
bindPort = 7000
vhostHTTPPort = 80
webServer = { addr = "0.0.0.0", port = 7500, user = "admin", password = "admin" }
# frpc.toml(内网客户端)
serverAddr = "1.2.3.4"
serverPort = 7000

[[proxies]]
name = "web"
type = "http"
localPort = 8080
customDomains = ["app.example.com"]    # 访问 http://app.example.com → 内网 8080

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000                      # 访问 frps:6000 → 内网 22
# 公网启 frps,内网启 frpc
./frps -c frps.toml &
./frpc -c frpc.toml &
ssh -p 6000 user@1.2.3.4               # 经 frp 隧道 SSH 进内网机

实验三:ngrok 一行暴露(调试 Webhook 神器)

ngrok http 8080
# Forwarding  https://a1b2.ngrok.io -> http://localhost:8080
# 把 a1b2.ngrok.io 填到第三方 Webhook 配置里,本地就能收到回调

实验四:gost 转发链

# gost 把流量经两跳代理转发(A→B→目标),每跳协议可不同
gost -L=:8080 -F=socks5://proxyA:1080 -F=http://proxyB:3128
# 本地 8080 收到的流量 → 经 socks5 proxyA → 再经 http proxyB → 出网

排错

现象根因解决
ssh -R 端口只绑 127.0.0.1sshd 默认 GatewayPorts no服务端开 GatewayPorts yes
frpc 连不上 frps端口/防火墙/token 不符查 bindPort、安全组、auth.token 两端一致
HTTP 穿透 404/域名不通customDomains 与访问域名不符核对域名解析指向 frps 公网 IP
穿透延迟高/断流中转机带宽/网络抖动选近的中转、加 keepalive
暴露后被扫描攻击服务无认证就裸暴露加认证、用 STCP 点对点、限制来源
SSH 隧道频繁断无保活加 ServerAliveInterval/autossh

本章小结

  • 内网穿透的本质是反向隧道:内网主动连出公网中转,外部请求经隧道反向回内网。
  • SSH 三式:-L 拉远端到本地、-R 推本地到远端(=穿透)、-D 起 SOCKS(第06章)。
  • frp 是专业穿透(frps+frpc,多协议多服务);gost 是隧道瑞士军刀(转发链);ngrok 是 SaaS 化一行穿透。
  • 隧道与代理技术同源、常组合;穿透 = 主动开攻击面,必须认证 + 加密 + 受控。

下一章 第20章 科学上网生态的技术原理,把"加密代理 + 流量混淆 + 智能分流"这套技术从工程角度讲清楚——它和企业代理、CDN、Mesh 在技术上同源。