使用 nginx 对 emqx 进行反向代理的时候,可能会到此错误,根本原因是在nginx 上配置了 TLS/SSL 证书以后又将反向代理地址指向了 EMQX 的 TLS 端口,此时 TLS 的校验已经交由 nginx 进行管理,反向代理到 emqx 的普通 1883 端口即可
这里涉及的是 TLS 终止 (TLS Termination) 的概念问题。
问题根本原因
当使用 NGINX 对 EMQX 进行反向代理时,如果在 NGINX 上配置了 TLS/SSL 证书,会出现 双重 TLS 加密 的问题:
- 客户端 → NGINX:第一层 TLS 加密
- NGINX → EMQX:如果代理到 EMQX 的 TLS 端口(如 8883),会形成第二层 TLS 加密
这种配置会导致:
- TLS 握手失败
- 连接超时或被拒绝
- 证书验证冲突
- 性能开销增加
正确的解决方案
方案一:TLS 终止在 NGINX(推荐)
upstream emqx_backend {
server 127.0.0.1:1883; # 使用 EMQX 的普通端口
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/key.pem;
location / {
proxy_pass http://emqx_backend; # 注意是 http,不是 https
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-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
方案二:TLS 透传(如果需要端到端加密)
stream {
upstream emqx_tls {
server 127.0.0.1:8883;
}
server {
listen 443;
proxy_pass emqx_tls;
proxy_timeout 1s;
proxy_responses 1;
}
}
关键要点
- TLS 终止位置选择:要么在 NGINX,要么在 EMQX,避免重复
- 端口对应关系:NGINX 有 SSL → EMQX 普通端口(1883)
- 协议一致性:代理配置中使用
http://
而非https://
- WebSocket 支持:如需要,添加相应的 Upgrade 头部
这样配置可以有效避免 TLS 冲突,提高连接稳定性和性能。