用 Nginx 来代理 EMQX 获取不到真实 IP

环境信息

  • EMQX 版本:4.4.1
  • 操作系统及版本:Ubuntu 20.04
  • 其他

问题描述

我在 EMQX 前面加了一个 Nginx 来做 TCP Stream 代理,但无法获取到真实 IP。在 $SYS/brokers/emqx@127.0.0.1/clients/#/connected中。

我在 Nginx 用 set_real_ip_from 0.0.0.0/24; 测试过 ipaddress 依然是我Nginx所在服务器的IP。

有此方面实践过的大佬,烦请分享一下。

已解决

Nginx 只要增加一个配置即可 proxy_protocol on;

upstream mqtt_tcp_server {
        server 192.168.118.243:1883;
    }

    server {
        listen       2883;
        # listen       2883 proxy_protocol ;  这样是不行的,网上很多文章,放这里
        proxy_protocol on;  # 只要增加这一行配置即可
        proxy_connect_timeout 360s;
        proxy_timeout 360s;
        proxy_pass mqtt_tcp_server;
        proxy_buffer_size 3M;
        tcp_nodelay on;
    }

emqx.conf 开启 proxy_protocol

listener.tcp.external.proxy_protocol = on

重启 Nginx EMQX 即可生效。

参考:用 Nginx 来代理 EMQX 获取不到真实 IP - #16,来自 DDDHuang

如果 EMQX 集群部署在 HAProxy 或 Nginx 后,且需要拿到客户端真实的源 IP 地址与端口,则需打开 Proxy Protocol 配置,配置项:EMQX 监听器 proxy_protocol

Proxy Protcol 参考: https://www.haproxy.com/blog/haproxy/proxy-protocol (opens new window)

Nginx 使用 Proxy Prorcol 参考: https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/(opens new window)

我设置 listener.tcp.external.proxy_protocol = on 后,1883端口都无法访问了。
查看日志,没有任何输出sudo docker logs emqx -f --tail 111

抓包没有 Connect Ack

跟这个帖子有点类似,但没提到解决办法:emq4.2.9消息桥接到低版本2.3.11的问题 - #8,来自 ch111889922

我的版本是:4.4.1

不知道你的网络拓扑关系呀,方便画一个简单的吗?表意即可,我们也方便看出问题

图一
image

如图一所示,客户端 与 Broker 同网段,当 Broker 开启 proxy_protocol 后,1883就无法连接了。

图二
image

如图二所示,我 客户端 与 Broker 之间增加了一个 Nginx,客户端通过 2883 连接 Nginx,Nginx 代理到 Broker 的 1883,Nginx 配置了 proxy_protocol on; Broker 开启了 proxy_protocol,此时客户端也无法连接成功。 原因应该也是 Broker 1883 启用 proxy_protocol 后就无法访问的原因。

当不启用 proxy_protocol 时,Broker 1883 端口可以被访问。

1 看下ngix的配置,Ngix配置文档
2 开启Nigx之后代理的端口是1883还是2883呢?我看到拓扑图中2883端口,192.168.118.84机器上是用2883端口作为MQTT服务的吗?Ngix应该是代理MQTT的服务端口的,如果你用的是默认设置,MQTT端口是在1883的。
3 代理之后,可以看下192.168.118.84的日志,如果是代理成功,但是数据包不对,是有信息打印的,如果是代理不成功,应该是没有消息进来。日志的操作参考文档
4 用MQTTX连一下被代理的服务,走ngix,看下报错的情况,是链接超时,还是端口拒绝或者其他问题

您好!
这是我客户端连接 Nginx 的错误提示:
image

我 Nginx 监听 2883 端口,代理到 Broker 的 1883 端口。 所以我客户端连接的是 nginx ip:2883

Nginx tcp 日志如下:

192.168.118.84 [14/Jul/2022:02:41:37 +0000] TCP 400 0 0 0.001 "-" "-" "-" "-"

只有这一行,每次连接都输出这个。

我客户端跳过 Nginx 直接连接 Broker 的 1883 端口,也是无法连接的。
所以根本原因应该是:开启 proxy_protocol 后,1883 端口就无法访问了。 如果 Broker 直连 1883 端口可以访问,那我想 Nginx 代理后的 2883 端口也是可以访问的。 因为 Nginx 确实收到了请求,只是连接不上 Broker。

另外,只要我不开启 proxy_protocol ,无论是直连 Broker,还是 Nginx 代理后的都可以连接成功。

我现在去把 Broker 的 log 都打开看看。

把nginx的配置信息贴出来吧

我做了一下配置:

log.to = both
log.level = debug

当我直连 Broker 的时候,Broker 也没错误日志输出。

大佬你好,可以先不管 Nginx 代理问题了。想先解决 启用 proxy_protocol 后,直连 1883 也不行的问题。

就这一行配置,我注释掉,重启,就可以。

开启后,正常的操作就不该再直连了。开启之后,正常会收到nginx关于原始IP的报文。

nginx的配置呢?配置了吗?

image

您好,这是我 Nginx 配置。

那这个我无法直连的问题就是:配置了 proxy_protocol 就不允许直连了吗。 如果这样,那应当跟 Nginx 配置有关。

是的,开启之后不支持直连的,因为代理有自己的交互协议,会在tcp包中带上一部分自己的业务,设备直连没有这些业务信息是连不上的

1 个赞

不能直连的原因应该是解析不到那个推送过来的报文。
nginx开启的方式是这个

proxy_protocol on;

2 个赞