Cloudflare Workers TCP Sockets 配置指南:用 Wrangler、Tunnel 与 Smart Placement 打通私有网络
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
导读
本文基于 workers-vpc 配置参考,系统讲解如何在 Cloudflare Workers 中启用并配置TCP Sockets API(cloudflare:sockets),让 Worker 能够直连 AWS、Azure、GCP、本地数据中心等私有网络中的数据库、SSH、MQTT 或自定义 TCP 服务。读完本文,你将掌握完整的wrangler.jsonc配置方式、环境变量与多环境管理、通过 Cloudflare Tunnel 安全接入私有网络的端到端步骤,以及 Smart Placement、Hyperdrive、Secrets 等配套能力的正确组合用法,并规避常见的连接限制与安全陷阱。
Wrangler 基础配置
TCP Sockets 默认可用,无需特殊开关
TCP Sockets 是 Workers 运行时内置能力,只要wrangler.jsonc中指定了main入口与compatibility_date即可直接使用,无需额外的 compatibility flags:
{ "name": "private-network-worker", "main": "src/index.ts", "compatibility_date": "2025-01-01" }其中compatibility_date建议使用当前日期(示例为"2025-01-01"),以便获得最新运行时特性。对应 Worker 入口只需从cloudflare:sockets导入connect:
import { connect } from 'cloudflare:sockets'; export default { async fetch(req: Request): Promise<Response> { const socket = connect({ hostname: "db.internal.company.net", port: 5432 }); // ... } };注意:
connect()必须在请求处理函数(handler)内部创建,不能在模块全局作用域创建。从源码结构看,workers-vpc README 将"必须在 handler 内创建"列为硬性要求,因为 Socket 生命周期与请求绑定。
环境变量:把连接细节与代码解耦
把主机、端口等连接参数放入vars,避免硬编码在源码中:
{ "vars": { "DB_HOST": "10.0.1.50", "DB_PORT": "5432" } }在代码中通过Env接口类型化访问:
interface Env { DB_HOST: string; DB_PORT: string; } export default { async fetch(req: Request, env: Env): Promise<Response> { const socket = connect({ hostname: env.DB_HOST, port: parseInt(env.DB_PORT) // vars 中的值均为字符串,需显式转换 }); // 使用 socket... } };注意wrangler.jsonc的vars中所有值都以字符串形式注入,端口号必须在代码中通过parseInt()转换为 number,以满足 TCP Sockets API 中SocketAddress.port为number的类型要求。
按环境隔离配置(staging / production)
借助env字段可以为不同部署环境覆盖变量,实现"同一份代码、多套配置":
{ "vars": { "DB_HOST": "localhost" }, "env": { "staging": { "vars": { "DB_HOST": "staging-db.internal.net" } }, "production": { "vars": { "DB_HOST": "prod-db.internal.net" } } } }分别部署到对应环境:
wrangler deploy --env staging wrangler deploy --env production该模式与 Hyperdrive、Tunnel 等私有网络方案天然互补——每个环境指向各自独立的数据库主机,避免误连生产库。
集成 Cloudflare Tunnel:从 Worker 安全访问私有网络
架构链路
Worker 本身无法直接路由到局域网 IP,标准做法是让 Worker 通过 TCP Socket 连接Tunnel 主机名,再由部署在私有网络内的cloudflared把流量转发到目标服务:
Worker (TCP Socket) → Tunnel hostname → cloudflared → Private Network五步快速搭建
在私有网络内的服务器上安装 cloudflared;
创建隧道:
cloudflared tunnel create my-private-network配置路由(
config.yml):将 Tunnel 主机名映射到内网服务地址:tunnel: <TUNNEL_ID> credentials-file: /path/to/<TUNNEL_ID>.json ingress: - hostname: db.internal.example.com service: tcp://10.0.1.50:5432 - service: http_status:404 # Required catch-allingress规则按从上到下、首条匹配生效的顺序求值,因此兜底的http_status:404必须放在最后;支持tcp://、ssh://、rdp://、http://、https://等多种 service 类型,详见 Tunnel 配置参考;启动隧道:
cloudflared tunnel run my-private-network从 Worker 发起连接:直接以 Tunnel 主机名作为目标地址,并开启 TLS:
const socket = connect( { hostname: "db.internal.example.com", port: 5432 }, // Tunnel hostname { secureTransport: "on" } );secureTransport: "on"表示连接建立后立即执行 TLS 握手;对于 Postgres、SMTP、IMAP 等先明文后升级的协议,应使用"starttls"模式并在握手成功后调用socket.startTls()(详见 TCP Sockets API 参考)。
Tunnel 运维补充
- 配置校验与规则测试:
cloudflared tunnel ingress validate校验配置;cloudflared tunnel ingress rule https://foo.example.com可实测某 URL 命中的规则; - 私有网络模式:若内网有多台机器需要互通,可启用
warp-routing: enabled: true并用cloudflared tunnel route ip add 10.0.0.0/8 my-tunnel添加路由网段; - 证书问题:源站使用自签名证书时,可在
originRequest中配置noTLSVerify或caPool;生产环境应始终关闭noTLSVerify(详见 Tunnel 疑难排查); - 凭据轮换:轮换凭据后需在 24 小时宽限期内重启所有旧的
cloudflared进程,避免连接失败。
Smart Placement 集成:让 Worker 靠近后端,降低延迟
TCP Socket 直连内网服务时,网络往返路径越长延迟越高。启用 Smart Placement 后,Workers 会根据实际观测到的连接延迟,自动将运行位置迁移到更靠近 TCP Socket 目标端点的区域:
{ "placement": { "mode": "smart" } }使用前提与限制
- 仅影响
fetchhandler:Smart Placement 只对默认导出的fetch方法生效;RPC 方法(WorkerEntrypoint)、命名入口、scheduled定时器等不受影响,仍运行在边缘节点。若后端逻辑使用 RPC 调用,需改造成 fetch 模式才能受益; - 互斥字段:
mode不能与显式放置字段(region、host、hostname)同时出现; - 分析期:启用后约需最长 15 分钟流量分析,期间会自动将 1% 请求作为未优化基线用于性能对比;
- 本地开发无效:
wrangler dev本地模式不会触发 Smart Placement,需wrangler deploy --env staging部署后验证; - 静态资源警告:切勿在
assets.run_worker_first = true的 Pages 项目中启用 Smart Placement,否则所有静态资源请求会被路由到远端,资产加载性能将严重劣化。推荐做法是拆分为"前端 Worker 留在边缘 + 后端 Worker 开启 Smart Placement"两个服务。
完整模式对照与前后端拆分示例见 Smart Placement 配置参考。
Secrets 管理:敏感凭据不进配置文件
数据库口令、隧道凭据等敏感信息不要写入wrangler.jsonc,而应使用wrangler secret命令注入:
wrangler secret put DB_PASSWORD # Enter value when prompted运行时通过env.DB_PASSWORD读取,并用于协议握手或认证:
const socket = connect( { hostname: env.DB_HOST, port: parseInt(env.DB_PORT) }, { secureTransport: "on" } ); // 在协议层使用 env.DB_PASSWORD 完成认证密钥与vars在代码中的读取方式一致,但前者不进入版本库、可独立轮换,且默认对代码不可见(加密存储),是私有网络场景下保护凭据的首选。
本地开发:wrangler dev 与降级策略
使用wrangler dev即可本地联调。注意:本地模式可能无法访问私有网络(取决于网络环境与 Tunnel 可达性),因此更稳妥的做法是准备"开发/生产"两套目标:
const config = process.env.NODE_ENV === 'dev' ? { hostname: 'localhost', port: 5432 } // Mock : { hostname: 'db.internal.example.com', port: 5432 }; // Production const socket = connect(config);- 开发期:指向本机 mock 服务或公开 echo 服务(如
tcpbin.com:4242)验证收发逻辑; - 验证阶段:可对云端数据源使用
npx wrangler dev --remote以远程执行模式联调(注意这会影响线上配置); - 由于 Socket 生命周期与请求绑定,本地开发务必注意每次请求结束后关闭连接,避免资源泄漏。
连接字符串解析模式
许多基础设施以连接字符串形式提供地址(例如postgres://10.0.1.50:5432/mydb)。可以借助标准URL解析,把连接字符串规整为SocketAddress,实现配置与协议的松耦合:
function parseConnectionString(connStr: string): SocketAddress { const url = new URL(connStr); // e.g., "postgres://10.0.1.50:5432/mydb" return { hostname: url.hostname, port: parseInt(url.port) || 5432 }; }该函数直接返回 TCP Sockets API 中定义的SocketAddress(hostname: string、port: number),可无缝接入connect();|| 5432兜底处理了未显式指定端口的情况,使模式可复用到 Postgres、MySQL、Redis 等多种服务。
Hyperdrive 集成:数据库场景的更好选择
对于 PostgreSQL/MySQL,优先使用 Hyperdrive 而非裸 TCP Socket——Hyperdrive 自带连接池、查询缓存与 TLS 终结,性能与稳定性远优于每条请求新建 TCP 连接:
{ "hyperdrive": [{ "binding": "DB", "id": "<HYPERDRIVE_ID>" }] }代码中通过绑定直接使用:
export default { async fetch(req: Request, env: Env): Promise<Response> { const result = await env.DB.prepare('SELECT * FROM users').all(); return Response.json(result); } };创建 Hyperdrive 配置的命令示例(详见 Hyperdrive 配置参考):
npx wrangler hyperdrive create my-db \ --connection-string="postgres://user:pass@host:5432/db"何时选 TCP Sockets、何时选 Hyperdrive 的决策依据:
| 需求 | 推荐方案 | 原因 |
|---|---|---|
| HTTP/HTTPS 私有 API | VPC Services(beta,另行文档)/fetch() | SSRF 防护、声明式绑定 |
| PostgreSQL/MySQL | Hyperdrive | 连接池、缓存、性能优化 |
| 自定义 TCP 协议(SSH、MQTT、专有二进制) | TCP Sockets(本文) | 完整线协议控制 |
| 需要 StartTLS / 自定义 TLS 协商 | TCP Sockets | 支持starttls模式与startTls() |
| 把内网服务暴露到公网(入站) | Cloudflare Tunnel | 非 Worker 专属,独立方案 |
另外,若 Worker 单请求内对数据库执行多次查询,可在 Hyperdrive 配置 中同时启用 Smart Placement,让 Worker 运行在更靠近数据库的位置,进一步压缩往返延迟。
兼容性说明
- TCP Sockets 在所有现代 Workers 运行时均可用,无特殊开关;
- 建议将
compatibility_date设为当前日期(示例"2025-01-01"),无需额外 compatibility flags; - DNS 名在连接时解析,支持 IPv4、IPv6 及私有 IP 段(
10.x、172.16.x、192.168.x)。
常见限制与排错要点
以下要点提炼自 workers-vpc gotchas,是私有网络联调中最高频的坑:
平台硬限制
| 限制 | 值 |
|---|---|
| 单请求最大并发 Socket 数 | 6(硬限制) |
| Socket 生命周期 | 请求期间内 |
| 连接超时 | 平台决定,无配置项 |
超过 6 个并发连接会直接报错,需按 6 个一批分批处理:
for (let i = 0; i < hosts.length; i += 6) { const batch = hosts.slice(i, i + 6).map(h => connect({ hostname: h, port: 443 })); await Promise.all(batch.map(async s => { /* use */ await s.close(); })); }被拦截的目标
出于安全考虑,以下目标被 Cloudflare 阻止:Cloudflare 自身 IP(如1.1.1.1)、localhost(127.0.0.1)、端口 25(SMTP)、Worker 自身 URL。解决办法是使用公网 IP 或 Tunnel 主机名,例如connect({ hostname: "db.internal.company.net", port: 5432 })。
典型报错速查
"proxy request failed":目标被拦截 / DNS 失败 / 网络不可达 → 校验目标地址、改用 Tunnel 主机名、用 try/catch 捕获;
"TCP Loop detected":Worker 连到了自己 → 改为连接外部服务;
"Port 25 prohibited":SMTP 端口被禁 → 改用 Email Workers API 收发邮件;
"socket is not open":关闭后再读写 → 用
try/finally保证关闭顺序;连接超时:无内置超时 → 用
Promise.race()实现超时控制:const socket = connect(addr, opts); const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000)); await Promise.race([socket.opened, timeout]);
安全:防 SSRF
如果目标地址由用户输入控制,必须做严格白名单校验,防止访问内部服务:
const ALLOWED = ['api1.internal.net', 'api2.internal.net']; const host = new URL(req.url).searchParams.get('host'); if (!host || !ALLOWED.includes(host)) return new Response('Forbidden', { status: 403 });更多真实场景(Redis RESP、MQTT、重试退避、连接池、多协议网关等)可参阅 workers-vpc patterns。
相关配置参考
- Tunnel 配置:cloudflared 详细配置与 ingress 规则;
- Smart Placement 配置:放置模式选项与限制;
- Hyperdrive 配置:数据库连接池完整设置;
- TCP Sockets API 参考:
connect()签名、Socket接口与startTls(); - workers-vpc 概览与选型:技术选型决策表与最佳实践;
- workers-vpc 排错指南:完整限制清单与错误解决方案;
- workers-vpc 实战模式:协议实现与错误处理示例。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考