双 Traefik 架构的公网穿透与内网隔离实践
通过双 Traefik 与 Tailscale 实现公网穿透、HTTPS 后端转发和内网服务访问隔离。
1. 背景与网络架构
在 HomeLab 或企业边缘计算场景中,一种非常经典的架构是:利用一台廉价的公网云服务器 A 作为入口,与本地高性能的内网服务器 B 通过 Tailscale 组建虚拟局域网(SDN)。
- 服务器 A(公网):内存小、带宽有限,主要运行轻量级容器,负责接收公网流量。域名
*.example.com解析至 A 的公网 IP。 - 服务器 B(内网):内存大、性能强(IP:
100.88.0.9),运行 GitLab、Harbor、Nacos、Code-Server 等重载服务。 - 网关控制:两台服务器均使用 Traefik 作为反向代理。服务器 A 负责申请
*.example.com的通配符证书,并通过自动化脚本同步至服务器 B。
2. 核心痛点:Harbor HTTPS 无限重定向
在初始配置中,服务器 A 采用 HTTP 泛解析路由将流量透传给内网 B 的 80 端口:
# 服务器 A 初始错误配置片段
services:
ganzhou-service:
loadbalancer:
servers:
- url: "http://100.88.0.9:80"
问题现象
当内网 B 的 Harbor 配置了强制 HTTPS 时,公网访问 harbor.example.com 会陷入 ERR_TOO_MANY_REDIRECTS(重定向次数过多) 的死循环;而内网机器修改 Host 直连 B 时却完全正常。
原因分析
- 客户端 (HTTPS) 发起请求。
- 服务器 A (Traefik) 接收请求,卸载 TLS 证书(TLS Termination),根据配置转为 HTTP 协议转发给内网 B(
100.88.0.9:80)。 - 服务器 B (Harbor/Traefik) 收到 HTTP 请求,触发内部安全策略,返回
302 Redirect要求跳转到 HTTPS。 - 客户端收到 302 后再次发起 HTTPS 请求,无限循环形成。
3. 全自动化全穿透解决方案
为了彻底解决重定向问题,同时实现“在内网 B 起新服务,完全无需动服务器 A 配置文件”的无感自动化体验,最终演进出 HTTP 全局兜底 + HTTPS 后端转发 的架构。
核心逻辑
服务器 A 负责公网层面的证书解密,但在通过 Tailscale 隧道转发给 B 时,不再降级为 HTTP,而是直接走 HTTPS(443端口)。
方案配置实现
1. 公网服务器 A:动态/静态配置文件(一劳永逸)
http:
serversTransports:
# 必须信任内网自签或因域名不字面匹配的证书
secure-backend-transport:
insecureSkipVerify: true
routers:
# 全局兜底路由:优先级设为最低(priority: 1)
# 确保 A 本地通过 Docker Label 发现的轻量小服务优先匹配
global-fallback-to-b:
rule: "HostRegexp(`^[a-z0-9-]+\\.yuweinfo\\.com$`)"
entryPoints:
- websecure
priority: 1
service: backend-b-https-service
tls:
certResolver: aliresolver
services:
backend-b-https-service:
loadbalancer:
serversTransport: secure-backend-transport
servers:
# 关键点:直接打到内网 B 的 HTTPS 443 端口
- url: "https://100.88.0.9:443"
2. 内网服务器 B:应用部署(以 Harbor/GitLab 为例)
内网 B 正常运行 Traefik 并挂载同步过来的证书。后续新增任何服务,直接在 docker-compose.yml 中写 Label 即可:
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.entrypoints=websecure"
- "traefik.http.routers.my-app.rule=Host(`my-app.example.com`)"
- "traefik.http.routers.my-app.tls=true"
架构优势:
公网访问:流量经 A 解密后,以 HTTPS 甩给 B,完美避开 302 重定向循环。
内网拉取(大流量):内网机器修改 Host 将
harbor.example.com指向100.88.0.9,流量彻底绕过公网 A。利用本地同步的证书直接进行 TLS 握手,直接跑满内网千兆/万兆带宽。
4. 进阶安全:内网专属服务的“防偷渡”隔离
越权安全隐患
当在内网 B 部署了私有服务(如 nacos.example.com、code.example.com)并将其 DNS 解析到内网 IP 100.88.0.9 时,理论上外网无法解析。
但是,由于 *.example.com 依然解析在公网,攻击者只需在公网通过构造特定的请求头:
curl -k -H "Host: code.example.com" https://<服务器A的公网IP>:443
由于服务器 A 存在全局兜底路由,A 会忠实地将该请求“偷渡”转发给内网 B。内网 B 识别到 Host 匹配,直接放行,导致内网服务无防备暴露在公网。
安全闭环:Traefik IP 白名单拦截
坚守“不改动公网 A”的原则,在内网服务器 B 实施拦截。利用 Traefik 的 X-Forwarded-For 信任机制与 IPAllowList 中间件,实现精准防御。
步骤一:配置内网 B 的 Traefik 识别真实客户端 IP
修改内网 B 的 Traefik 静态配置文件(traefik.yml),信任来自 Tailscale 网段的转发头:
entryPoints:
websecure:
address: ":443"
forwardedHeaders:
trustedIPs:
- "100.64.0.0/10" # Tailscale 官方标准网段
步骤二:在动态文件 middlewares.yml 中定义白名单
http:
middlewares:
# 限制仅允许 Tailscale 虚拟内网 IP 访问
tailscale-only:
ipAllowList:
sourceRange:
- "100.64.0.0/10"
# 其他常用中间件,如大文件上传限制
code-max-body-limit:
buffering:
maxRequestBodyBytes: 524288000
步骤三:在 Docker Compose 中跨 Provider 调用中间件
在部署私有服务(如 code-server)时,通过 @file 后缀链式调用文件供应商中的中间件:
version: '3.8'
services:
code-server:
image: codercom/code-server:latest
container_name: code-service
labels:
- "traefik.enable=true"
# 1. 正常配置路由
- "traefik.http.routers.code-web.entrypoints=websecure"
- "traefik.http.routers.code-web.rule=Host(`code.example.com`)"
- "traefik.http.routers.code-web.tls=true"
# 2. 核心:链式调用外部 file 里的【内网白名单】与【文件大小限制】中间件
- "traefik.http.routers.code-web.middlewares=tailscale-only@file,code-max-body-limit@file"
- "traefik.http.services.code-web-service.loadbalancer.server.port=8080"
networks:
- traefik-net
networks:
traefik-net:
external: true
5. 防御效果验证与测试填坑
在测试“偷渡”防御时,若直接执行 curl -H "Host: code.example.com" https://<公网IP>,会遇到 SEC_E_UNTRUSTED_ROOT 证书不受信任报错。
这是因为 TLS 握手阶段的 SNI 扩展 与 HTTP 请求头中的 Host 相互独立。未指定 SNI 时,服务器 A 无法匹配证书,会返回默认的 Traefik 自签证书导致连接中断。
正确的测试与防御判定命令
使用 curl 的 --resolve 参数模拟最真实的 DNS 劫持欺骗:
curl -v --resolve code.example.com:443:<公网服务器A的IP> https://code.example.com
- 防御前:请求成功穿透 A 抵达 B,正确返回 200 OK 或服务页面。
- 防御后:流量虽然通过 A 转发到了 B,但内网 B 的 Traefik 识别出
X-Forwarded-For里的真实客户端 IP 为外部公网 IP,中间件直接进行安全拦截,无情返回403 Forbidden。
至此,一个兼顾高性能大流量拉取、全面自动化免维护、高级内网隔离安全的双 Traefik 混合网络架构完美闭环。