HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 代理技术全栈手册

    • 代理技术全栈手册 - HiHuo
    • 原理篇

      • 第01章 代理是什么:正向 / 反向 / 透明 / 隧道的统一模型
      • 第02章 代理与网络层级:L3 / L4 / L5 / L7 在哪里截断流量
      • 第03章 一个请求穿过代理的一生:连接生命周期全景
    • 协议篇

      • 第04章 HTTP 代理协议:绝对 URI、CONNECT 隧道、转发头与连接池
      • 第05章 HTTPS 与 TLS 代理:终止 / 透传 / MITM / SNI / mTLS
      • 第06章 SOCKS 协议:SOCKS4/4a/5 与 UDP ASSOCIATE 报文级解析
      • 第07章 HTTP/2、gRPC 与 HTTP/3(QUIC) 代理的挑战
      • 第08章 代理自动配置:PAC / WPAD / 系统代理 / NO_PROXY
    • 层级与转发篇

      • 第09章 L4 代理:TCP/UDP 转发与连接级负载均衡
      • 第10章 L7 代理:协议感知与基于内容的路由
      • 第11章 透明代理:iptables REDIRECT/DNAT、TPROXY 与 eBPF 劫持
      • 第12章 数据搬运的艺术:splice / sendfile / 零拷贝 / io_uring
    • 组件横评篇

      • 第13章 Nginx / OpenResty:反向代理、upstream 与 Lua 可编程
      • 第14章 HAProxy:L4/L7、ACL、健康检查与 stick table
      • 第15章 Envoy:xDS 动态配置与 filter chain,为何是云原生数据面
      • 第16章 Traefik / Caddy:自动服务发现与自动 HTTPS
      • 第17章 Squid 与正向/缓存代理:企业出网、缓存与审计
      • 第18章 mitmproxy:抓包、改包、脚本化调试
      • 第19章 内网穿透与隧道:frp / gost / SSH 隧道 / ngrok
      • 第20章 科学上网生态的技术原理(技术中立)
    • 多语言手写篇

      • 第21章 Go:100 行手写 HTTP/CONNECT + SOCKS5 代理
      • 第22章 Rust:基于 tokio 的高性能 TCP 代理
      • 第23章 Python:asyncio 实现,适合调试与脚本
      • 第24章 C:epoll 裸写与零拷贝,及语言选型对比
    • 容器与K8s篇

      • 第25章 Docker 里的代理:HTTP_PROXY、build/pull 与 daemon 配置
      • 第26章 Sidecar 与流量劫持:Istio init-container 的 iptables 原理
      • 第27章 Ingress 与南北流量:Ingress-nginx 与 Gateway API
      • 第28章 Egress 与出网治理:出口网关、registry mirror、审计
      • 第29章 Service Mesh 数据面:Envoy Sidecar 全链路
    • 进阶篇

      • 第30章 可编程代理:Lua / Wasm / eBPF / xDS,代理的"软件定义"
      • 第31章 性能调优:并发模型、连接池、超时与重试、压测
      • 第32章 排错决策树:502 / 504 / 握手失败 / 环路 / 泄漏
      • 第33章 代理安全:开放代理、SSRF、凭证泄漏与攻击面
    • 底层机制篇

      • 第34章 代理的背压与流控:一个代理最难的部分
      • 第35章 socket 与 TCP 状态机:半关闭、超时、连接生命周期
      • 第36章 HTTP/2 帧、流控与 HPACK:h2 代理的内部机制
      • 第37章 负载均衡算法推导与韧性状态机
      • 第38章 Capstone:把玩具代理改造成生产级骨架
    • 综合实战篇

      • 第39章 企业多跳转发链:拓扑、协议矩阵与贯穿性难题
      • 第40章 端到端实战:把 6 类流量全代理通
      • 第41章 更刁钻的流量:gRPC、长轮询、WebRTC、大文件、双向流
      • 第42章 可落地完整参考实现:一套能跑的多协议转发栈
    • 附录

      • 附录 A:代理协议报文速查(HTTP / SOCKS / PAC / PROXY protocol)
      • 附录 B:组件选型决策树
      • 附录 C:抓包与命令速查

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

学习目标

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

前置知识

  • 第01章 隧道代理、第06章 SOCKS(ssh -D)
  • 第04章 CONNECT 隧道

原理

核心难题: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 在技术上同源。

Prev
第18章 mitmproxy:抓包、改包、脚本化调试
Next
第20章 科学上网生态的技术原理(技术中立)