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

news2024/11/30 18:49:02

文章目录

  • 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. 系统架构

在这里插入图片描述
  设备端携带设备证书向NLB所在的域名发起业务请求,NLB将流量转发到 HAProxy 负载均衡服务,HAProxy校验设备证书的有效性,当校验通过后终结TLS,将流量分发到某个MQTT Broker节点。HAProxy的负载策略可采用循环负载。

3. 证书签发

  使用 cfssl 工具签发设备证书。证书信任模型为:
在这里插入图片描述

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证书,设备证书,设备私钥,详细信息如下图所示:
在这里插入图片描述
  点击CONNECT按钮发起连接请求。
在这里插入图片描述
  如上图所示,客户端成功连接到MQTT Broker。

6. 总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年高教社杯数学建模国赛C题详细版思路

C 题 蔬菜类商品的自动定价与补货决策 2023年国赛如期而至,为了方便大家尽快确定选题,这里将对C题进行解题思路说明,以分析C题的主要难点、出题思路以及选择之后可能遇到的难点进行说明,方便大家尽快找到C题的解题思路。 难度排…

第六章 图 三、图的存储结构(邻接表、十字链表、邻接多重表)

一、邻接表法 (1)无向图 1.定义 与树的孩子表示法相似,以顺序表的数据域为头结点,往后存储一个单向链表,链表内的值表示与此结点相邻的结点。 2.度的计算 只需遍历某一结点的后接链表,就可以算出该节点…

Linux命令200例:Yum强大的包管理工具使用(常用)

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师&#xff0…

【Python小项目之Tkinter应用】随机点名/抽奖工具小优化:实现输入框人数限定与人名显示优化,保证结果人名在窗口内显示,如果内容显示超出则弹出警告窗口

文章目录 前言一、实现思路二、关键代码三、完整代码总结前言 老规矩,先看效果展示: 优化前: 对比来看,当显示人数较多时,优化前的窗口输出框在窗口分辨率不满足显示空间时,会造成人名显示不全的问题,而且只能单行显示,并无任何提示,这样会让用户误认为程序执行正确…

socket的使用 | TCP/IP协议下服务器与客户端之间传送数据

服务器端代码: import java.io.*; import java.net.ServerSocket; import java.net.Socket;public class theServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket new ServerSocket(9999); // 该行代码作用&#xff1…

Win7旗舰版64位桌面创建32位IE方法

很多Win7 64位旗舰版用户系统桌面上的IE8浏览器,打开后都是64位的,而很多网站并不兼容64位的IE浏览器,其实在Win764位系统中IE是分为64位和32位的,出现这样的情况可能是桌面上的IE图标指响的是64位的IE,我们只要重新添…

温控仪的工作原理

温控仪是调控一体化智能温度控制仪表,它采用了全数字化集成设计,具有温度曲线可编程或定点恒温控制、多重PID调节、输出功率限幅曲线编程、手动/自动切换、软启动、报警开关量输出、实时数据查询、与计算机通讯等功能,将数显温度仪表和ZK晶闸…

Discourse 应该保留多少备份

近期,我们在对 Discourse 进行恢复的时候,我们发现新的备份可能会导致不是所有的数据都能恢复到服务上。 这时候我们应该考虑让 Discourse 保留多少备份的问题? 在默认情况下,我们设置 Discourse 的备份是保留 5 个。这是官方的…

c语言初阶指针

目录 何为指针 地址大小 野指针 成因 如何规避 有效性 指针计算 -整数 ​编辑 指针比较运算 指针-指针 ​编辑 数组与指针关系 二级指针 指针数组 应用 何为指针 指针就是指针变量,用来存放内存空间的一个编号,将指针比作我们宾馆的客人&a…

Web存储

目录 什么是 HTML5 Web 存储? 方法 cookie webStorage 会话存储 sessionStorage 本地存储localStorage 什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据。 早些时候,本地存储使用的是 cookie。但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服…

Go 接口和多态

在讲解具体的接口之前,先看如下问题。 使用面向对象的方式,设计一个加减的计算器 代码如下: package mainimport "fmt"//父类,这是结构体 type Operate struct {num1 intnum2 int }//加法子类,这是结构体…

线性空间和线性变化

目录 考点一、线性空间的基与维数 1、线性空间 2、基底 3、子空间(线性子空间) ​编辑4、生成子空间 (1)、v1 n v2 (2)、v1 v2 5、求和子空间的方法 6、维数定理 7、例题 (1&#xf…

解锁前端Vue3宝藏级资料 第四章 VUE常用 UI 库 2 ( ailwind 后台框架)

4.5 ailwind 上面介绍的都是国内比较优秀的UI框架,现在我们在介绍一款国外比较流行的CSS UI框架ailwind 。官方网站https://tailwindcss.com/docs/guides/vite#vue CSShttps://flowbite.com/docs/getting-started/introduction/ 。这个ailwind 架构需要自己去写一些…

《基于区块链的数据资产评估实施指南》技术研讨会成功召开

2023年9月1日,《基于区块链的数据资产评估实施指南》(以下简称《指南》)技术研讨会在深圳召开,竹云科技作为主要参编单位出席此次研讨会。 中国科协决策咨询首席专家王春晖,中国社会科学院博士于小丽,中国…

Leetcode 易错题整理(三)73. 77. 78. 81. 90. 95.105. 130.

73. 矩阵置零 给定一个 *m* x *n* 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。** 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]笨方法&…

在很多公司里面会使用打tag的方式保留版本

:git tag|grep "xxx-dev“等分支来查看 2:git cherry-pick XXXXX 然后就是查看有冲突这些 git status 会出现相关的异常 然后解决相关的冲突 git add . git cherry-pick --continue git push XXX HEAD:refs/for/XXX 第一:git ta…

Excel自学三部曲_Part3:Excel工作场景分析实战

文章目录 一、Excel工作场景与知识点总结1. 学哪个Excel?(1)学习哪个版本的Excel?(2)Excel和WPS到底学哪个? 2. 怎么用Excel?(1)低量级数据的存储(2)一次性的数据处理…

解决使用torchstat时报错“AttributeError: module ‘numpy‘ has no attribute ‘long‘”等问题

背景 首先直接使用pip install torchstat安装。 使用torchstat查看模型参数和flops: from torchstat import stat stat(model.to(cpu), (2, 32, 32)) # 这里第二个参数取决于自己的模型输入大小报错1 运行报错如下: 核心错误为: “Attri…

uniapp分包 解决分多个包的问题

1. 分包可以分很多个, 但是在"optimization": { "subPackages": true } 里面只能写一个, 2. 想分多个包 , 在 pages.json 里面 的 subPackages 里面继续加 第三个 第四个即可 3. 保存之后 创建页面就可以看见多个包了

异常的顶级理解

目录 1.异常的概念与体系结构 1.1异常的体系结构 1.2异常的举例 1.3错误的举例 2.异常的分类 2.1编译时异常 2.2运行时异常 3.异常的处理 3.1异常的抛出throw 3.2try-catch捕获并处理 3.3finally 3.4 异常声明throws 4.自定义异常类 1.异常的概念与体系结构 1.1异常的…