太好了 — 我给你一份实战级全攻略:如何在受限的局域网/内网环境下,使用 EMQX(本地部署) + cpolar(内网穿透) 实现可供公网访问的 MQTT 服务。包含:环境准备、Docker 快速部署、cpolar 隧道命令、客户端连接示例、以及安全建议与常见问题。我把关键点都标注了官方文档参考,方便你生产环境落地与二次扩展。🎯
一、整体思路(一句话)
在本地启动 EMQX(监听本地 1883/8883/8083/8084 等端口),用 cpolar 建立一个将公网端口映射到本地相应 MQTT 端口的 TCP 隧道,然后客户端通过 cpolar 提供的公网地址直接访问你的本地 EMQX。参考:EMQX 官方端口说明与 WebSocket 支持。(emqx.com)
二、准备工作(前提)
- 一台可以运行 Docker / 或直接在服务器上安装 EMQX 的机器(局域网内)。
 - 注册并安装 cpolar(极点云)客户端(有免费/付费计划,免费通常有连接数/带宽限制)。(dashboard.cpolar.com)
 - 可选:MQTT 客户端(
mosquitto_pub/sub、MQTTX、mqtt-cli、浏览器 JS 客户端等)。 
三、步骤详解(命令一步到位)
1. 拉起本地 EMQX(Docker 快速版)
# 拉取并运行 latest 镜像(示例端口映射:1883/TCP, 8883/TLS, 8083/WS, 8084/WSS, 18083 Dashboard)
docker run -d --name emqx \
  -p 1883:1883 \
  -p 8883:8883 \
  -p 8083:8083 \
  -p 8084:8084 \
  -p 18083:18083 \
  emqx/emqx:latest
- 说明:1883 = MQTT/TCP,8883 = MQTT/TLS(建议生产用),8083 = MQTT over WebSocket(非加密),8084 = MQTT over WebSocket Secure(WSS)。关于端口与协议对照见 EMQX 官方说明。(emqx.com)
 
2. 验证本地 EMQX 是否正常
在本地机器上运行(示例使用 mosquitto_sub):
# 订阅本地测试主题
mosquitto_sub -h localhost -p 1883 -t 'test/topic' -v &
# 在另一终端发布
mosquitto_pub -h localhost -p 1883 -t 'test/topic' -m 'hello emqx'
你应该能在订阅端看到消息。
3. 安装并登录 cpolar
- 注册 cpolar(https://dashboard.cpolar.com/)并获取 
authtoken。(dashboard.cpolar.com) - 下载并安装 
cpolar客户端(Linux/Mac/Windows 均支持)。 
在本地终端:
# 将 <YOUR_TOKEN> 替换为 cpolar 控制台里的 authtoken
cpolar authtoken <YOUR_TOKEN>
4. 用 cpolar 建立 TCP 隧道到本地 MQTT 端口
A. 暴露 MQTT(非 TLS,1883)
cpolar tcp 1883
命令成功后,cpolar 会返回一个公网地址与端口,例如:0.tcp.cpolar.cn:12345。外部 MQTT 客户端直接连接到该地址与端口即可(等同于直连本地 1883)。
注意:非 TLS 传输数据明文,不建议直接在公网使用。(dashboard.cpolar.com)
B. 推荐 — 暴露 MQTT/TLS(8883)
如果你已经在 EMQX 上配置了 TLS(或使用内置证书),优先暴露 8883:
cpolar tcp 8883
然后客户端使用 TLS(CA 验证或跳过证书验证)连接到 cpolar 返回的公网地址。使用 TLS 可以避免中间人窃听。EMQX TLS 配置参考官方文档。(docs.emqx.com)
C. 暴露 WebSocket(如果客户端是浏览器或需要 WSS)
EMQX 支持 MQTT over WebSocket(8083/8084),可以用 cpolar 暴露对应端口:
# 非加密 WebSocket
cpolar tcp 8083
# 或 加密 WSS(需要 EMQX 已配置 TLS)
cpolar tcp 8084
浏览器端可以用 mqtt.js 连接 ws://<cpolar-host>:<port>/mqtt(视 EMQX WebSocket path 而定),或 wss://...(加密)。参考 EMQX 的 WebSocket 快速入门示例。(emqx.com)
5. 客户端连接示例
非 TLS(示例)
# 假设 cpolar 给出 0.tcp.cpolar.cn:12345(映射到本地 1883)
mosquitto_sub -h 0.tcp.cpolar.cn -p 12345 -t 'test/topic' -v
mosquitto_pub -h 0.tcp.cpolar.cn -p 12345 -t 'test/topic' -m 'hello from remote client'
TLS(示例)
# 如果 EMQX 使用自签名证书,客户端可能需要跳过证书验证(仅测试)
mosquitto_sub -h 0.tcp.cpolar.cn -p 54321 --capath /path/to/ca -t 'secure/topic' -v --tls-version tlsv1.2
浏览器(mqtt.js,WSS)
const client = mqtt.connect('wss://0.tcp.cpolar.cn:PORT/mqtt'); // 或 ws:// 如果非加密
client.on('connect', () => { client.subscribe('test/topic'); client.publish('test/topic', 'hello') });
四、安全建议(必须认真读)
- 优先使用 TLS(8883 / WSS) —— 通过 cpolar 暴露 TLS 端口,避免明文传输。EMQX 支持导入证书(Let’s Encrypt / 自签名 / 商业 CA)。(docs.emqx.com)
 - 启用用户认证与 ACL —— 在 EMQX 中启用用户名/密码或 JWT 认证,并设置 ACL 规则避免任意订阅/发布。(docs.emqx.com)
 - 限制连接数与速率 —— cpolar 免费隧道通常有限制;在 EMQX 侧也设置连接数/速率限制,防止滥用。(dashboard.cpolar.com)
 - 生产环境避免长期依赖公网隧道服务 —— 隧道适合测试、演示、临时远程调试。生产建议:在云上部署 EMQX(或使用 EMQX Cloud /自建 NAT/VPN/端口映射)并做高可用/监控。EMQX 官方推荐用于生产的部署模式与 Cluster Linking 有说明。(emqx.com)
 
五、常见问题与排查要点
- 连接不上? 检查本机 EMQX 是否在对应端口监听(
ss -ltnp/docker logs emqx);确认 cpolar 隧道已启动并返回公网地址。 - 权限拒绝? 确认 EMQX 是否已开启匿名访问(默认可能已禁用),尝试用正确的 username/password。(docs.emqx.com)
 - TLS 握手失败? 校验证书链、域名是否匹配(若使用域名),或客户端是否允许自签名证书。(docs.emqx.com)
 - 延迟/吞吐不佳? 隧道服务会增加一跳转发开销,免费计划可能限速,生产请评估带宽与可用性。(instatunnel.my)
 
六、进阶建议(如果你想做得更专业)
- 使用 EMQX 的桥接(bridge)功能 或 Cluster Linking 实现跨地域 MQTT 集群互通,而不是把单机暴露在公网。(docs.emqx.com)
 - 考虑在云上部署一个负载均衡 + EMQX 集群,把内网设备通过安全通道(VPN / WireGuard /私有线)接入,再通过公网 LB 提供服务。
 - 对接监控(Prometheus / Grafana)和日志(ELK)以便运维。
 
七、参考资料(出站链接)
- EMQX 官方:端口与安全建议(MQTT 端口说明)。(emqx.com)
 - EMQX 教程与 WebSocket 快速入门。(emqx.com)
 - cpolar 官网 / 控制台(隧道使用说明、authtoken)。(dashboard.cpolar.com)
 - ngrok 对 MQTT 的使用示例(概念参考,隧道方案类似)。(ngrok.mintlify.dev)
 - EMQX 关于 Cluster Linking 与生产部署的方案文档。(emqx.com)
 
发表回复