HAProxy终结TLS双向认证代理EMQX集群

文章目录

  • 1. 背景介绍
  • 2. 系统架构
  • 3. 证书签发
    • 3.1 创建根证书
    • 3.2 创建中间证书
    • 3.3 创建设备证书
    • 3.4 创建服务端证书
  • 4. HAProxy开启双向认证
  • 5. 验证
  • 6. 总结

1. 背景介绍

  MQTT协议已经成为当前物联网领域的关键技术之一,当前市面上主流的实现MQTT协议的产品主要有 EMQX、Mosquito、NanoMQ等。本文以EMQX开源版为基础,构建 MQTT Broker 集群,并使用 HAProxy代理 MQTT Broker 集群,由 HAProxy 开启双向认证,并终结TLS,HAProxy 到 MQTT Broker 集群的流量采用非加密模式。

2. 系统架构

HAProxy终结TLS双向认证代理EMQX集群_第1张图片
  设备端携带设备证书向NLB所在的域名发起业务请求,NLB将流量转发到 HAProxy 负载均衡服务,HAProxy校验设备证书的有效性,当校验通过后终结TLS,将流量分发到某个MQTT Broker节点。HAProxy的负载策略可采用循环负载。

3. 证书签发

  使用 cfssl 工具签发设备证书。证书信任模型为:
HAProxy终结TLS双向认证代理EMQX集群_第2张图片

3.1 创建根证书

  • 首先创建配置文件config.json
{
   "signing": {
     "default": {
       "expiry": "262800h"
     },
     "profiles": {
       "intermediate": {
         "usages": ["cert sign", "crl sign"],
         "expiry": "700800h",
         "ca_constraint": {
           "is_ca": true,
           "max_path_len": 1
         }
      },
      "device": {
        "usages": [
            "client auth",
            "signing",
            "digital signing",
            "key encipherment",
            "server auth"
        ],
        "expiry": "262800h"
      }
     }
   }
 }
  • 创建根证书配置文件 root.json
{
    "CN": "emqx.com",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "WuHan",
            "O": "emqx",
            "OU": "EMQX Root CA",
            "ST": "China"
        }
    ]
}
  • 创建根CA证书
cfssl gencert -initca root.json  | cfssljson -bare CaRoot
  • 执行上边命令后将会得到根证书私钥、根证书请求文件、根证书。
    在这里插入图片描述

3.2 创建中间证书

  • 创建中间证书配置文件 intermediate.json
{
  "CN": "intermediate.emqx.com",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "WuHan",
      "L": "XS",
      "O": "EMQX intermediate CA",
      "OU": "EMQX intermediate CA"
    }
  ]
}
  • 使用根CA签发中间证书
cfssl gencert -ca=./CaRoot.pem -ca-key=./CaRoot-key.pem -config=./config.json -profile=intermediate ./intermediate.json | cfssljson -bare CaIntermediate
  • 执行上边命令后将会生成中间证书私钥、中间证书申请文件、中间证书
    在这里插入图片描述

3.3 创建设备证书

  • 创建设备证书配置文件device-a-csr.json
{
  "CN": "DEVICEAXXXXXXXX",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "WuHan",
      "L": "XS",
      "O": "EMQX DEVICE",
      "OU": "EMQX DEVICE"
    }
  ]
}
  • 创建设备证书
cfssl gencert -ca=./CaRoot.pem -ca-key=./CaRoot-key.pem -config=./config.json -profile=device ./device-a-csr.json | cfssljson -bare device-a
  • 执行上边命令将会得到设备证书私钥、设备证书申请文件、设备证书
    在这里插入图片描述

3.4 创建服务端证书

  • 创建服务端证书配置文件 emqx-server-csr.json
{
  "CN": "emqx.xxx.com",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hubei",
      "L": "Wuhan",
      "O": "emqx",
      "OU": "EMQX Server"
    }
  ]
}
  • 使用根CA签发服务端证书
cfssl gencert -ca=./CaRoot.pem -ca-key=./CaRoot-key.pem -config=./config.json -profile=device ./emqx-server-csr.json | cfssljson -bare emqx-server
  • 执行上边命令将会得到EMQX服务端证书私钥 emqx-server-key.pem、证书申请文件 emqx-server.csr、服务端证书emqx-server.pem
  • 将服务端证书私钥与服务端证书合并到一个PEM文件,得到 server-allinone.pem 证书文件。
cat emqx-server-key.pem emqx-server.pem |tee server-allinone.pem

4. HAProxy开启双向认证

  修改/etc/haproxy/haproxy.cfg文件,开启MQTT Broker访问端口,并开启双向认证。

frontend emqx-tls
        bind *:8091 ssl crt /etc/emqx/certs/server-allinone.pem ca-file /etc/haproxy/certs/CaIntermediate.pem ca-verify-file /etc/haproxy/certs/CaRoot.pem verify required
        # 一层证书信任模型,设备证书直接由根证书签发时,ca-file 配置根证书
        # bind *:8091 ssl crt /etc/emqx/certs/server-allinone.pem ca-file /etc/haproxy/certs/CaRoot.pem verify required
        mode tcp
        log global
        option tcplog
        default_backend emqx-backend

backend emqx-backend
        mode tcp
        option tcplog
        balance roundrobin
        default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 500000 maxqueue 10000 weight 100
        server emqx-165 10.0.1.165:1883 check-send-proxy send-proxy-v2 check inter 10s fall 2 rise 5
        server emqx-171 10.0.1.171:1883 check-send-proxy send-proxy-v2 check inter 10s fall 2 rise 5
  • ca-file 指定中间证书,用于校验设备端证书的有效性
  • ca-verify-file 指定根CA证书,用于校验中间证书的有效性,如果只有一层信任模型,这个参数通常不会使用
  • crt 指定服务端证书,此处的服务端证书包含了证书及私钥
  • verify required 表示开启双向认证,
  • check-send-proxy send-proxy-v2 用于开启 Proxy Protocol 协议,MQTT Broker 可获取到设备端的IP地址
  • maxconn 指定最大连接数,默认值2000,一定要修改这个值,否则设备连接最大数量将会被限制在2000个连接内

当 HAProxy 设置了 check-send-proxy 与 send-proxy-v2 参数后,需要 EMQX 开启 proxy-protocol 协议。开启方式时修改 /etc/emqx/emqx.conf 配置文件,在 1883 监听端口配置 proxy-protocol = true

listeners.tcp.default {
  bind = "0.0.0.0:1883"
  max_connections = 500000
  proxy_protocol = true
}

5. 验证

   使用 MQTT客户端工具向NLB所在的IP地址发起连接请求,请求参数携带根CA证书,设备证书,设备私钥,详细信息如下图所示:
HAProxy终结TLS双向认证代理EMQX集群_第3张图片
  点击CONNECT按钮发起连接请求。
HAProxy终结TLS双向认证代理EMQX集群_第4张图片
  如上图所示,客户端成功连接到MQTT Broker。

6. 总结

   HAProxy 作为一款非常优秀的四层均衡程序,在大量的生产项目中得到广泛的应用,相较于NGINX在七层负载场景中广泛应用,四层负载均衡服务在TCP服务负载业务场景上有着更好的性能优势。云商的NLB服务作为高可靠的负载均衡服务,为何不直接将NLB的流量负载分发到MQTT Broker节点,还额外的安装HAProxy负载均衡程序,主要原因是云商NLB的功能通常比较基础,无法满足企业额外的定制化需求,所以,大量的业务场景中使用云商的NLB作为第一层负载入口,定制化的业务处理交给后边的HAProxy负载均衡服务实现。

你可能感兴趣的:(物联网连接平台,MQTT集群,EMQX集群,HAProxy,中间证书,双向认证)