commit e09b81f0093c6cad2c5c29d2016727a857e7def4 Author: darcy Date: Wed Apr 1 11:10:25 2026 +0800 init diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6d2e34a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "iis.configDir": "" +} \ No newline at end of file diff --git a/nginx_emqx_cfg.md b/nginx_emqx_cfg.md new file mode 100644 index 0000000..f65a2af --- /dev/null +++ b/nginx_emqx_cfg.md @@ -0,0 +1,361 @@ +# EMQX 服务接入配置说明书 + +> MQTT / WS / WSS / MQTTS 全协议接入指南 +> 服务器:`emqx.laidaixi.com` | EMQX 5.x + Nginx 反向代理 | 阿里云 ECS + +--- + +## 1. 系统架构概述 + +本服务器在阿里云 ECS 上部署了 EMQX 5.x 消息代理,并通过 Nginx 反向代理对外暴露多种 MQTT 协议接入方式。客户端无需直接访问 EMQX 端口,统一通过 Nginx 进行流量分发。 + +``` +客户端 → Nginx(80 / 443 / 8883)→ EMQX(1883 / 8083) +域名:emqx.laidaixi.com +证书:已配置 SSL 证书,支持 TLS 1.2 / 1.3 +``` + +--- + +## 2. 接入方式总览 + +| 协议 | 连接地址 | 端口 | 路径 | 加密 | 适用场景 | +|------|----------|------|------|------|----------| +| MQTT (TCP) | emqx.laidaixi.com | 1883 | — | ❌ 否 | 内网 / 测试工具直连 | +| WS | emqx.laidaixi.com | 80 | /mqtt | ❌ 否 | Web 浏览器 / 开发调试 | +| WSS | emqx.laidaixi.com | 443 | /mqtt | ✅ 是 | 微信小程序 / Web 生产 | +| MQTTS | emqx.laidaixi.com | 8883 | — | ✅ 是 | IoT 设备 / 原生客户端 | + +--- + +## 3. MQTT(TCP 明文) + +### 3.1 协议说明 + +MQTT over TCP 是最基础的接入方式,客户端直连 EMQX 的 1883 端口,无 TLS 加密,适合内网环境或工具调试使用。 + +### 3.2 连接参数 + +| 协议 | 连接地址 | 端口 | 路径 | 加密 | 适用场景 | +|------|----------|------|------|------|----------| +| MQTT | emqx.laidaixi.com | 1883 | — | ❌ 否 | 调试工具 / 内网设备 | + +### 3.3 MQTTX 配置示例 + +``` +协议:mqtt:// +Host:mqtt:// +地址:emqx.laidaixi.com +端口:1883 +Client ID:mqttx_xxxxxxxx +Username:lai +Password:(对应密码) +注:直连 EMQX,不经过 Nginx +``` + +### 3.4 注意事项 + +- 此连接方式不经过 Nginx,直接访问 EMQX 的 TCP 端口 1883。 +- 明文传输,不建议在生产环境传输敏感数据。 +- 阿里云安全组需放行 1883 端口(入方向),或仅内网使用。 + +--- + +## 4. WS(WebSocket 明文) + +### 4.1 协议说明 + +MQTT over WebSocket,通过 Nginx 在 80 端口代理到 EMQX 的 8083 端口。适用于 Web 浏览器环境和开发调试。数据明文传输,不适合生产环境敏感业务。 + +### 4.2 连接参数 + +| 协议 | 连接地址 | 端口 | 路径 | 加密 | 适用场景 | +|------|----------|------|------|------|----------| +| WS | emqx.laidaixi.com | 80 | /mqtt | ❌ 否 | Web 浏览器 / 开发调试 | + +### 4.3 Nginx 配置(laidaixi.conf) + +```nginx +# ===== ws:// 明文 WebSocket(80 端口)===== +server { + listen 80; + server_name emqx.laidaixi.com; + + location /mqtt { + proxy_pass http://127.0.0.1:8083; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_read_timeout 3600s; + } + + # EMQX Dashboard(可选) + location / { + proxy_pass http://127.0.0.1:18083/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +``` + +### 4.4 MQTTX 配置示例 + +``` +协议:ws:// +Host:ws:// +地址:emqx.laidaixi.com +端口:80 +路径:/mqtt +Client ID:mqttx_88759893(或自定义) +Username:lai +Password:(对应密码) +``` + +### 4.5 JavaScript 代码示例 + +```javascript +// 使用 mqtt.js 连接 ws:// +import mqtt from 'mqtt'; + +const client = mqtt.connect('ws://emqx.laidaixi.com/mqtt', { + port: 80, + clientId: 'web_' + Math.random().toString(16).slice(2), + username: 'lai', + password: 'your_password', + keepalive: 60, + clean: true, +}); + +client.on('connect', () => { + console.log('Connected via WS'); + client.subscribe('test/topic'); +}); + +client.on('message', (topic, payload) => { + console.log(topic, payload.toString()); +}); +``` + +### 4.6 注意事项 + +- Nginx 通过 `Upgrade` / `Connection` 头完成 WebSocket 握手升级。 +- `proxy_read_timeout` 设为 3600s,避免长连接被 Nginx 主动断开。 +- EMQX Dashboard 也通过 80 端口的 `location /` 代理访问。 + +--- + +## 5. WSS(WebSocket 加密,小程序专用) + +### 5.1 协议说明 + +MQTT over WebSocket Secure,Nginx 在 443 端口终止 TLS,再以明文反向代理到 EMQX 8083 端口。微信小程序强制要求 `wss://` 协议,本方案是小程序接入 MQTT 的标准配置。 + +> ⚡ **重要:微信小程序只允许 `wss://` 协议,请务必使用此接入方式,不可使用 `ws://`。** + +### 5.2 连接参数 + +| 协议 | 连接地址 | 端口 | 路径 | 加密 | 适用场景 | +|------|----------|------|------|------|----------| +| WSS | emqx.laidaixi.com | 443 | /mqtt | ✅ 是 | 微信小程序 / Web 生产环境 | + +### 5.3 Nginx 配置(laidaixi.conf) + +```nginx +# ===== wss:// 加密 WebSocket(443 端口,小程序专用)===== +server { + listen 443 ssl; + server_name emqx.laidaixi.com; + + ssl_certificate /etc/nginx/cert/emqx.laidaixi.com.pem; + ssl_certificate_key /etc/nginx/cert/emqx.laidaixi.com.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + location /mqtt { + proxy_pass http://127.0.0.1:8083; # 后端仍为明文 8083 + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 3600s; + + # 小程序跨域支持 + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; + add_header Access-Control-Allow-Headers content-type; + } + + # EMQX Dashboard(生产推荐) + location / { + proxy_pass http://127.0.0.1:18083/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +``` + +### 5.4 MQTTX 配置示例 + +``` +协议:wss:// +Host:wss:// +地址:emqx.laidaixi.com +端口:443 +路径:/mqtt +Client ID:mqttx_xxxxxxxx +Username:lai +Password:(对应密码) +``` + +### 5.5 微信小程序代码示例 + +```javascript +// 小程序中使用 mqtt.js(需打包进小程序) +const mqtt = require('./mqtt.min.js'); + +const client = mqtt.connect('wxs://emqx.laidaixi.com/mqtt', { + // 小程序使用 wxs:// (wx.connectSocket 底层) + // 或根据 mqtt.js 版本写成: + // protocol: 'wss', + // hostname: 'emqx.laidaixi.com', + // port: 443, + // path: '/mqtt', + clientId: 'mini_' + Math.random().toString(16).slice(2), + username: 'lai', + password: 'your_password', + keepalive: 60, + clean: true, + reconnectPeriod: 5000, +}); +``` + +### 5.6 注意事项 + +- SSL 证书在 Nginx 层终止,EMQX 后端无需配置证书,保持简洁。 +- 已添加 CORS 头(`Access-Control-Allow-Origin: *`),支持跨域访问。 +- 证书路径:`/etc/nginx/cert/emqx.laidaixi.com.pem` 和 `.key` +- 443 端口同时代理 EMQX Dashboard,通过 `location /` 转发至 18083 端口。 + +--- + +## 6. MQTTS(TCP 加密) + +### 6.1 协议说明 + +MQTT over TLS,原生 MQTT TCP 连接加密版本。适用于 IoT 设备、嵌入式系统、Python/C 原生客户端等不支持 WebSocket 的场景。EMQX 直接在 8883 端口终止 TLS,不经过 Nginx。 + +### 6.2 连接参数 + +| 协议 | 连接地址 | 端口 | 路径 | 加密 | 适用场景 | +|------|----------|------|------|------|----------| +| MQTTS | emqx.laidaixi.com | 8883 | — | ✅ 是 | IoT 设备 / 嵌入式 / 原生客户端 | + +### 6.3 EMQX 配置 + +证书通过 docker-compose.yml 挂载进容器: + +```yaml +volumes: + - /etc/nginx/cert/emqx.laidaixi.com.pem:/opt/emqx/etc/certs/server.pem + - /etc/nginx/cert/emqx.laidaixi.com.key:/opt/emqx/etc/certs/server.key +``` + +在 EMQX Dashboard → 管理 → 监听器 → ssl:default(8883)中配置: +- TLS Cert: `/opt/emqx/etc/certs/server.pem` +- TLS Key: `/opt/emqx/etc/certs/server.key` +- 双向认证:关闭(单向 TLS,客户端无需证书) + +### 6.4 MQTTX 配置示例 + +``` +协议:mqtts:// +地址:emqx.laidaixi.com +端口:8883 +TLS:true +Client ID:mqttx_xxxxxxxx +Username:lai +Password:(对应密码) +``` + +### 6.5 验证命令 + +```bash +mosquitto_pub -h emqx.laidaixi.com -p 8883 --tls-use-os-certs \ + -u lai -P your_password -t test/topic -m "hello mqtts" +``` + +--- + +## 7. EMQX Dashboard 管理界面 + +### 7.1 访问地址 + +| 方式 | 地址 | 端口 | 加密 | 说明 | +|------|------|------|------|------| +| HTTP | http://emqx.laidaixi.com | 80 | ❌ 否 | 开发环境 | +| HTTPS | https://emqx.laidaixi.com | 443 | ✅ 是 | 生产环境(推荐) | + +### 7.2 默认账号 + +- 默认用户名:`admin` +- 默认密码:`public`(首次登录后请立即修改) + +> 🔒 **安全建议:生产环境请修改默认密码,并考虑将 Dashboard 访问限制为特定 IP。** + +--- + +## 8. 端口与服务汇总 + +| 端口 | 协议层 | Nginx 监听 | EMQX 后端 | 状态 | +|------|--------|------------|-----------|------| +| 1883 | TCP | —(直连) | EMQX TCP | ✅ 已开启 | +| 80 | HTTP | ws:// + Dashboard | EMQX 8083 / 18083 | ✅ 已开启 | +| 443 | HTTPS | wss:// + Dashboard | EMQX 8083 / 18083 | ✅ 已开启 | +| 8083 | WS | (内部端口) | EMQX WS | ✅ 已开启 | +| 8883 | TLS | —(直连) | EMQX SSL | ✅ 已开启 | +| 18083 | HTTP | (内部端口) | EMQX Dashboard | ✅ 已开启 | + +--- + +## 9. 安全建议 + +- **阿里云安全组**:仅放行必要端口(80、443、1883、8883),关闭 8083 和 18083 公网访问。 +- **EMQX 认证**:已启用用户名/密码认证,避免使用匿名连接。 +- **生产环境**:优先使用 WSS(443)或 MQTTS(8883)等加密协议。 +- **Dashboard 密码**:修改默认 `admin / public` 密码,并可配置 IP 白名单。 +- **证书续期**:定期检查 SSL 证书有效期,可配置 certbot 自动续期。 +- **日志监控**:定期查看 EMQX 日志(`/var/log/emqx/`)及 Nginx 日志,排查异常连接。 + +--- + +## 10. 常见问题排查 + +### Q1:连接失败,提示 Connection Refused + +- 检查 EMQX 是否正常运行:`systemctl status emqx` +- 检查 Nginx 是否正常运行:`systemctl status nginx` +- 检查阿里云安全组是否放行对应端口。 + +### Q2:WebSocket 连接 101 升级失败 + +- 确认 Nginx 配置中包含 `proxy_set_header Upgrade` 和 `Connection "upgrade"`。 +- 确认连接路径为 `/mqtt`,不可遗漏。 + +### Q3:微信小程序连接报错 + +- 必须使用 `wss://` 协议,不支持 `ws://` 明文。 +- 确认域名 `emqx.laidaixi.com` 已在微信公众平台配置为合法域名(socket 合法域名)。 +- 证书链必须完整(含中间证书),不可使用自签名证书。 + +### Q4:连接后频繁断线 + +- 检查 `proxy_read_timeout` 是否设置为 3600s(Nginx 默认 60s 会断开长连接)。 +- 客户端 keepalive 建议设置 60 秒,与 MQTTX 配置保持一致。