尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Nginx反向代理EMQX:HTTPS+MQTT over WSS完整配置
Nginx 反向代理 EMQXHTTPS MQTT over WSS 完整配置先说结论Nginx 反向代理 EMQX443 端口同时处理 Web HTTPS 和 MQTT over WSS。设备端用wss://连接Web 端用https://访问。安全、统一、好管理。做物联网平台时设备端通过 MQTT 连接 BrokerWeb 端通过 WebSocket 连接展示实时数据。如果平台部署了 HTTPSMQTT 的明文 1883 端口和 HTTP 的 8083 WebSocket 端口就不能直接暴露。用 Nginx 做反向代理统一走 443 端口 HTTPSMQTT over WSS。一、网络拓扑互联网 │ ├── HTTPS 443 ──→ Nginx ──┬── / → Web前端 (Nginx静态文件) │ ├── /mqtt → EMQX WebSocket (8083) │ └── /api → 后端API (8080) │ └── MQTT 8883 ──→ Nginx ──→ EMQX TLS (8883)二、Nginx 配置完整的 Nginx 配置# /etc/nginx/sites-available/iot-platform # HTTP → HTTPS重定向 server { listen 80; server_name iot.example.com; return 301 https://$server_name$request_uri; } # HTTPS主配置 server { listen 443 ssl; http2 on; server_name iot.example.com; # SSL证书 ssl_certificate /etc/letsencrypt/live/iot.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/iot.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; # HSTS add_header Strict-Transport-Security max-age31536000 always; # Web前端静态文件 root /var/www/iot-platform; index index.html; location / { try_files $uri $uri/ /index.html; } # API反向代理 location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # MQTT over WebSocket 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 300s; proxy_send_timeout 300s; } } # MQTT TLS 直连代理 stream { server { listen 8883 ssl; ssl_certificate /etc/letsencrypt/live/iot.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/iot.example.com/privkey.pem; proxy_pass 127.0.0.1:1883; } }关键配置解释Upgrade和Connection upgradeWebSocket 升级必需proxy_read_timeout 300sMQTT 长连接默认 60 秒超时会被断开改成 300 秒stream模块处理 TCP 层的 MQTT TLS 直连和 HTTP 的server块分开http2 on启用 HTTP/2提升 Web 性能三、Nginx stream 模块默认 Nginx 不加载 stream 模块。在nginx.conf的最外层加载# /etc/nginx/nginx.conf user www-data; worker_processes auto; events { worker_connections 1024; } http { # ... 其他http配置 include /etc/nginx/sites-enabled/*; } # stream模块必须和http平级 stream { include /etc/nginx/streams-enabled/*; }# 创建stream配置目录sudomkdir/etc/nginx/streams-enabled# 启用stream模块如果用apt安装的nginx默认已编译# 确认模块nginx-V21|grepstream四、EMQX 配置EMQX 端关闭 TLS让 Nginx 处理 TLS 终止# emqx.conflisteners:# MQTT TCPNginx stream代理到这个端口tcp:default:bind:0.0.0.0:1883max_connections:100000# MQTT WebSocketNginx HTTP代理到这个端口ws:default:bind:0.0.0.0:8083max_connections:10000websocket:mqtt_path:/mqtt# 关闭EMQX自带的SSL监听器# ssl:# default:# bind: 0.0.0.0:8883# ssl_options:# keyfile: ...# certfile: ...# 允许WebSocket从Nginx代理连接websocket:origin:https://iot.example.comEMQX 只需要开 1883 和 8083TLS 交给 Nginx 处理。这种方式叫TLS 终止TLS TerminationEMQX 只处理明文数据CPU 开销更低。五、设备端连接设备端用 MQTT over WSS// Web端浏览器constclientnewmqtt.Client(wss://iot.example.com/mqtt,// 走Nginx 443端口client_Math.random().toString(16).substr(2,8));client.onConnect(){console.log(Connected via WSS);client.subscribe(device/001/temperature);};client.connect();# Python设备端设备直连MQTT TLSimportsslimportpaho.mqtt.clientasmqtt clientmqtt.Client()contextssl.create_default_context()context.load_verify_locations(ca.crt)# Lets Encrypt证书链client.tls_set_context(context)client.connect(iot.example.com,8883,60)# 走Nginx stream代理# 或用WebSocketclientmqtt.Client(transportwebsockets)contextssl.create_default_context()context.load_verify_locations(ca.crt)client.tls_set_context(context)client.connect(iot.example.com,443,60)# 走Nginx HTTP代理ESP32 Arduino 端#includeWiFiClientSecure.h#includePubSubClient.hWiFiClientSecure esp_client;PubSubClientmqtt_client(esp_client);voidsetup(){WiFi.begin(SSID,password);// 加载CA证书Lets Encrypt ISRG Root X1constchar*ca_cert\-----BEGIN CERTIFICATE-----\nMIIFazCCB...省略...\n-----END CERTIFICATE-----\n;esp_client.setCACert(ca_cert);// 通过WSS连接443端口mqtt_client.setServer(iot.example.com,443);mqtt_client.setStream(esp_client);// 使用WebSocket路径// PubSubClient不直接支持WSS需要用ESP-MQTT库}ESP-IDF 端用esp-mqtt组件支持 WSS#includemqtt_client.hconstchar*mqtt_uriwss://iot.example.com/mqtt;constchar*cert\-----BEGIN CERTIFICATE-----\n...ISRG Root X1...\n-----END CERTIFICATE-----\n;esp_mqtt_client_config_tmqtt_cfg{.urimqtt_uri,.cert_pemcert,.client_iddevice_001,.lwt_topicdevice/001/status,.lwt_msgoffline,.lwt_qos1,.lwt_retain1,};esp_mqtt_client_handle_tclientesp_mqtt_client_init(mqtt_cfg);esp_mqtt_client_register_event(client,ESP_EVENT_ANY_ID,mqtt_event_handler,NULL);esp_mqtt_client_start(client);六、证书自动续期Let’s Encrypt 证书 90 天过期用 certbot 自动续期# 安装certbotsudoaptinstallcertbot python3-certbot-nginx# 申请证书自动修改Nginx配置sudocertbot--nginx-diot.example.com# 测试续期sudocertbot renew --dry-run# 添加cron定时续期sudocrontab-e# 每月1号凌晨3点检查续期031* * /usr/bin/certbot renew--quiet--post-hooksystemctl reload nginx七、性能调优高并发场景下 Nginx 参数# /etc/nginx/nginx.conf events { worker_connections 10240; # 每个worker最大连接数 use epoll; # Linux高效事件模型 multi_accept on; # 一次accept多个连接 } http { # 连接复用 keepalive_timeout 65; keepalive_requests 1000; # WebSocket特殊处理 map $http_upgrade $connection_upgrade { default upgrade; close; } # Gzip压缩 gzip on; gzip_types text/css application/javascript application/json; # 缓冲区 proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; # 日志格式 log_format mqtt $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent rt$request_time; }系统层面# 文件描述符限制ulimit-n65535# 或永久修改 /etc/security/limits.confnginx soft nofile65535nginx hard nofile65535# 内核参数 /etc/sysctl.confnet.core.somaxconn65535net.ipv4.tcp_max_syn_backlog65535net.ipv4.ip_local_port_range1000065535sudosysctl-p八、实测数据Nginx EMQX 5.02核4GB 服务器指标直连EMQXNginx代理最大WebSocket连接数5000050000消息吞吐100k/s95k/sTLS握手延迟0ms已建连20ms首次连接建立延迟5ms15msCPU占用40%55%内存占用500MB700MB九、踩坑清单WebSocket 路径Nginx 的location /mqtt要和 EMQX 的mqtt_path一致。不一致会 404proxy_read_timeout默认 60 秒。MQTT Keep Alive 通常设 30-120 秒如果 Nginx 超时比 Keep Alive 短连接会被 Nginx 断开HTTP/1.1WebSocket 代理必须设proxy_http_version 1.1默认 1.0 不支持 Upgrade 头stream 模块位置stream 块必须在 nginx.conf 的最外层不能放在 http 块内证书链Let’s Encrypt 的 fullchain.pem 包含中间证书。只发 cert.pem 会导致部分设备验证失败TLS 版本IoT 设备可能不支持 TLSv1.3。ssl_protocols TLSv1.2 TLSv1.3兼容性最好ALPNHTTP/2 需要 ALPN 协商。Nginx 默认支持但如果设备端 mbedTLS 版本低可能协商失败Nginx reload 不中断nginx -s reload不会断开现有连接。但如果 stream 配置改了需要nginx -s reopenX-Forwarded-ForEMQX 拿到的源 IP 是 Nginx 的 127.0.0.1。要在 EMQX 中配置proxy_protocol或从 X-Forwarded-For 头取真实 IP
RELATED

相关推荐

丰田亚洲龙定价策略与产品力分析:中高级轿车市场的错位竞争之道

丰田亚洲龙定价策略与产品力分析:中高级轿车市场的错位竞争之道

1. 从“亚洲龙”上市,聊聊中高级轿车市场的“生存法则”最近,一汽丰田亚洲龙正式公布了售价,20.88万到28.98万元这个区间,可以说是在当前这个竞争白热化的中高级轿车市场里,投下了一颗不大不小的石子。表面上看&#x…

📅 2026/10/9 2:12:12
知漫剧角色一致性教程:统一画风与系列 IP 创作

知漫剧角色一致性教程:统一画风与系列 IP 创作

引言 AI 漫剧赛道今年跑出了不少爆款,但做过的人都知道,单集出片不难,难的是跨集角色一致。角色换个镜头就"换脸",观众根本记不住你的人设,系列化更是无从谈起。知漫剧(zz.jiaxunai.cn&#xff…

📅 2026/9/10 3:04:03
如何让《暗黑破坏神2》在现代电脑上满帧运行?D2DX宽屏补丁完整上手指南

如何让《暗黑破坏神2》在现代电脑上满帧运行?D2DX宽屏补丁完整上手指南

如何让《暗黑破坏神2》在现代电脑上满帧运行?D2DX宽屏补丁完整上手指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2d…

📅 2026/10/8 8:32:11
MORE NEWS

更多资讯

📰

CentOS 6.3 老系统维护指南:兼容性、源配置与依赖管理

简介:这份资源面向需要在 CentOS 6.3 环境下进行前端页面开发与调试的技术人员,尤其适合关注源码构建与工具链使用的学习者。CentOS 6.3 基于 RHEL 6.3 源码构建,是当年企业服务器常用的稳定发行版,而该压缩包提供了一套可直接运行…

📰

基于Hadoop的列车管理系统设计:从论文到可运行系统的完整实践

简介:这是一份面向计算机科学与技术、软件工程等专业本科专科毕业生的原创学士学位论文,以Hadoop架构为核心,围绕列车管理系统的设计与实现展开,适合需要完成大数据方向毕业论文或希望深入理解分布式计算应用的学习者。压缩包内共…

📰

Redis 7持久化机制详解:RDB快照与AOF日志的Java实践

开头做 Java 开发的人,迟早要跟 Redis 打交道。尤其是那些日请求量上了几十万、百万的系统,Redis 几乎成了标配——热点数据缓存、分布式锁、接口幂等、排行榜,全是它的活。可很多 Java 同学对 Redis 的印象就停留在“一个很快的 KV 数据库”…

📰

洛谷P1135奇怪电梯:从图论建模到BFS/DFS剪枝与双向BFS全解析

第一次读到P1135的时候,我盯着题目看了半天,不太明白这个“奇怪的电梯”到底想干什么。后来想明白了,它根本不关心你是不是按错了楼层按钮。这台电梯的逻辑是:你在第 i 层,它只会往上走 k[i] 层,或者往下走…

📰

深度学习框架选型与模型部署实战:Keras、TensorFlow、PyTorch全解析

很多人在前面两篇已经把环境搭好、把基础网络跑通了,但真正进入项目阶段就会碰到三个躲不开的问题:三个框架到底怎么选、选完之后深度学习模型怎么做得“复杂”起来,以及模型训练完之后怎么落到实际环境里跑起来。这一篇我打算把这些问题一次…

📰

artcraft:用工程化流程实现可复现的艺术创作

1. 从“artcraft”这个名字说起:它到底想解决什么问题第一次看到“artcraft”这个标题,我脑子里蹦出来的第一反应是“艺术”加“手艺”,听起来像是个做创意工具的项目。但真正让我感兴趣的,是它背后隐含的那层意思——把“art”这…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬