QUIC 双向认证、DDS 代理功能升级

简介: 三月,NanoMQ发布了0.17版本,主要对2个重要功能进行了升级:MQTT over QUIC的双向认证和DDS协议转换代理的序列化代码自动生成。

QUIC 双向认证、DDS 代理功能升级.png

春分时节,万物复苏,NanoMQ 项目又如期为大家献上了最新的 0.17 版本。这一版本主要对 2 个重要功能进行了升级:MQTT over QUIC 的双向认证和 DDS 协议转换代理的序列化代码自动生成。另外还新增了 QUIC 传输层的配置参数,增加了 Retain 消息的持久化,以及发布了 NanoSDK 0.9 版本等诸多更新。

QUIC 双向认证 & 新增配置参数

自从 1994 年提出了 SSL 协议的原始规范以来,TLS 协议也经过了多次版本的更新。最新推出的 TLS 1.3 有望成为有史以来最安全但也最复杂的 TLS 协议。相较于 TLS 1/1.1/1.2,1.3 版本具备更快的连接协商速度,新的密钥协商机制 PSK 和更安全的加密哈希算法。

QUIC 在功能层面等价于 TCP+TLS, 并且已采用最新的 TLS 1.3 代替其原有加密协议(QUIC Crypto)。QUIC 协议默认基于 TLS 1.3 完成数据加密连接,且依赖其实现了0-RTT(1-RTT)快速重连握手功能。

MQTT 3.1.1 5.0 over QUIC.png

MQTT 3.1.1/5.0 over QUIC

当使用 TLS 进行数据加密传输时,如需要验证客户端合法性,经常会使用到双向认证。在之前的 NanoMQ 版本中, MQTT over QUIC 桥接默认只使用单向认证。从 0.17 版本开始用户能够通过配置开启 QUIC(TLS 1.3)的双向认证。

如何使用 QUIC 的双向认证

首先确认自己使用的 NanoMQ 版本已开启了 QUIC 选项,目前使用双向认证只需在配置中设置对应的客户端证书和私钥等文件路径,注意这部分配置无论是使用传统的 TCP 模式还是 QUIC 模式都一样有效:

旧配置文件格式:

bridge.mqtt.emqx.tls.enable=false
bridge.mqtt.emqx.tls.key_password=yourpass
bridge.mqtt.emqx.tls.keyfile=/etc/certs/key.pem
bridge.mqtt.emqx.tls.certfile=/etc/certs/cert.pem
bridge.mqtt.emqx.tls.cacertfile=/etc/certs/cacert.pem

HOCON 格式:

## 在 bridge 段落中的 connector 部分

bridges.mqtt {
    nodes = [
        {
            name = emqx
            enable = true
            connector {
                ......
                conn_properties = {
                    ......
                }
                # # Ssl config ##
                # # Ssl config is also valid when working in MQTT over QUIC mode ##
                ssl {
                    enable = false
                    key_password = "yourpass"
                    keyfile = "/etc/certs/key.pem"
                    certfile = "/etc/certs/cert.pem"
                    cacertfile = "/etc/certs/cacert.pem"
                }
            }

NanoMQ 的 MQTT over TCP 部分采用的是 MbedTLS 库进行加解密,与标准的 TCP 连接不同,QUIC 部分采用的是 MsQUIC 子模块项目内置的 OpenSSL API。OpenSSL 和 MbedTLS 两个目前最流行的 SSL 库在 NanoMQ 项目中可以同时兼容运行。

目前 NanoMQ 的 MQTT over QUIC 桥接功能暂时不支持 Windows 环境下运行。由于平台兼容性问题,在 Windows 环境中需要替换使用 schannel 来进行 TLS/SSL 加解密。计划在后续的版本中完成 Winodws 环境适配。

新增 QUIC 传输层配置参数

根据用户反馈,为了保持连接不断来克服一些极端弱网情况,新版本暴露了 2 个 QUIC 传输层参数供用户自行配置调优。

  • quic_initial_rtt 初始的 RTT(Round Trip Time) 预测值。QUIC 采用单向递增的 Packet Number 来标识数据包,即时是重传包也有独特的编号,不会引起重传的歧义性,这样采样 RTT 的测量更准确。QUIC 通过 ACK 记录的接收的数据报文和 ACK 报文之间的延迟来估算RTT,RTT 用于丢失检测和触发重传。这一值就是初始估计网络中的 RTT 情况,用户可以根据实际网络环境设置合理的 RTT 来保证连接不断。
  • quic_send_idleTimeout重置 QUIC 传输层拥塞控制检测的最大空闲时间。拥塞控制会修改内部发送的滑动窗口大小,此值影响 QUIC 传输层对于网络变动的敏感度和自动流控。

配置选项如下:

bridge.mqtt.emqx.quic_initial_rtt=60
bridge.mqtt.emqx.quic_send_idleTimeout=60

IDL 序列化代码生成工具

此前我们提到需要用户自己根据 IDL 格式来开发转 JSON 的序列化/反序列化代码,未来将提供一个自动化的代码生成工具。为了方便 MQTT 用户能够简单快速上手 DDS Proxy 功能,3 月这一工具正式发布:NanoMQ 推出了 IDL 代码生成器功能:idl-serial-code-gen。此工具能够根据用户的 DDS IDL 文件来自动生成 JSON 序列化和反序列化代码。

由于 DDS 协议为不可读不可直接分析的二进制流,为了提高系统的可互操作性,需要将 DDS 系统的数据在 NanoMQ 中进行必要的转换以供其他中间件如 eKuiper 分析使用。idl-serial-code-gen 工具可以自动生成代码来完成 IDL 结构体和 JSON 格式文本之间的互相转换。

目前 idl-serial-code-gen 工具支持以下 IDL 特性。

  • Primitive types
  • Structs
  • String and string with template
  • Sequence template
  • Enums
  • Part of Annotations

在上一版本的 NanoMQ DDS Proxy 中,默认所有主题都使用同一个 IDL 结构体定义,这限制了单实例能够转接的数据类型。新版本新增了 DDS 主题和 MQTT 主题的对应配置选项,供用户配置转发的 Topic 对应关系。

forward_rules = {
      ## DDS to MQTT
    dds_to_mqtt = {
        from_dds = "MQTTCMD/topic1"
        to_mqtt = "DDS/topic1"
        struct_name = "remote_control_result_t"
    }
    ## MQTT to DDS
    mqtt_to_dds = {
        from_mqtt = "DDSCMD/topic1"
        to_dds = "MQTT/topic1"
        struct_name = "remote_control_req_t"
    }
}

同理 nanomq_cli 工具命令行启动时也需要指定结构体名称:启动DDS客户端订阅DDS主题 MQTT/topic1 并指定接收的结构体名称 remote_control_req_t。

$ ./nanomq_cli ddsproxy sub -t "MQTT/topic1" --struct "remote_control_req_t"

目前默认 DDS 和 MQTT 主题之间一一对应,不允许一个 MQTT 主题上转接多个 DDS 主题。

编译 IDL 代码生成器 idl-serial-code-gen

编译 IDL 代码生成器 idl-serial

$ git clone https://github.com/nanomq/idl-serial.git
$ cd idl-serial
$ mkdir build && cd build
$ cmake -G Ninja ..
$ ninja 
$ sudo ninja install

编译完成生成可执行文件 idl-serial-code-gen

生成 Json<->Struct 转换代码

使用 idl 文件 dds_structs.idl 生成 C 代码 idl_convert.cidl_convert.h

## 生成C代码 idl_convert.c 和 idl_convert.h
$ ./idl-serial-code-gen  dds_structs.idl  idl_convert

编译NanoMQ与DDS Proxy

  1. 将以上步骤中生成的代码文件 idl_convert.cidl_convert.h 拷贝到 nanomq_cli/dds2mqtt 路径下
  2. 通过 cmake 参数 IDL_FILE_PATH 指定 idl 文件路径 (不指定则默认为工程路径下的 etc/idl/dds_type.idl)
$ git clone https://github.com/emqx/nanomq.git
$ cd nanomq
## 拷贝以上生成的文件到 nanomq_cli/dds2mqtt/路径下
$ cp {YOUR_PATH}/idl_convert.* nanomq_cli/dds2mqtt
$ mkdir build && cd build
$ cmake -G Ninja -DIDL_FILE_PATH={IDL_PATH} -DCMAKE_PREFIX_PATH={DDS_LIBRARY_PATH} -DBUILD_DDS_PROXY=ON ..
$ ninja 
$ sudo ninja install

目前虽然有了自动化代码生成工具,但 DDS Porxy 功能编译安装过程较为繁琐,对于不熟悉工程结构和 DDS 操作的用户来说比较困难。下一版本将通过 Cmake 来集成这一工具并自动化编译过程,无需再手动生成源码文件和拷贝文件到工程下。

NanoSDK 0.9 版本发布

与 NanoMQ 0.17 一同发布的还有 NanoSDK 0.9 版本。这一版本将 NanoMQ 中创新的 MQTT over QUIC 多流连接功能和在桥接中使用的新的回调函数同步至 NanoSDK。NanoSDK 0.10 版本也在筹备开发中,将提供 MQTT5 over QUIC 协议支持和继续增加类 Paho 的使用方法。

其他修复和更新

NanoMQ 0.17 版本还有一些小功能更新:

  1. 支持 Retain 消息持久化至 SQLite3: 根据用户需求,为 NanoMQ 新增了,当开启 SQLite 的消息缓存和持久化功能时默认存储所有的 Retain 消息至 SQLite。
  2. MQTT5 桥接增加更多配置参数: 为 MQTT5 桥接新增了遗愿消息相关的配置参数。

此外还有一些问题修复和优化:

  1. 修复桥接连接中拒绝接受带有 Subscription Identifier 消息的问题。
  2. 修复桥接连接接收到 Retain 消息时会造成数据类型不兼容而导致的协议错误断开。
  3. 修正了 HTTP API api/v4/clients 中获取到的错误的会话保持状态。
  4. 修改了 Broker 的行为:当客户端使用会话保持功能并断开连接时, 之前 Broker 希望能够复用此 Socket 等待客户端自动重连,而不会主动关闭。如今已修改为普通关闭操作。此功能的讨论:点击查看
  5. 在 NanoNNG 模块中更新了新的 nng_mqtt_quic_open_conf API 用于开启 QUIC 连接。
  6. 优化 CMakeList 修复 OpenSSL 和 MbedTLS 库在编译阶段造成的不兼容问题。

即将到来

NanoMQ 项目目前的重点是提升 NanoSDK 的易用性和支持 MQTT5 over QUIC 桥接,并且将继续完善 DDS 协议代理功能和提供更多更丰富的文档和教程。原计划中的 SOME/IP 协议代理将推迟至下一个版本发布。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/nanomq-newsletter-202303

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
24天前
|
数据采集 传感器 监控
多协议网关BL110钡铼6路RS485转MQTT协议云网关
BL110钡铼6路RS485转MQTT协议云网关是一款高性能、易配置的工业级设备,适用于各种需要远程监控和数据采集的物联网应用场景。通过将传统RS485设备的数据转换为MQTT协议并上传至云平台,实现了设备的远程管理和智能控制,极大地提升了系统的管理效率和响应速度。
28 2
|
7月前
|
安全 算法 网络协议
HTTPS:如何确保您的网站数据传输安全?
HTTPS:如何确保您的网站数据传输安全?
428 2
|
7月前
|
安全 网络安全 数据安全/隐私保护
HTTP代理SSL连接:保障网络安全的重要协议
HTTP代理SSL连接:保障网络安全的重要协议
101 0
|
7月前
|
Web App开发 网络协议 安全
C# | 实现QUIC协议的客户端与服务端
QUIC(Quick UDP Internet Connections)是一种基于UDP协议的可靠、安全、高效的传输协议,由Google开发。它是HTTP/3协议的基础,并被视为未来互联网传输层协议的重要候选者之一。 与TCP不同,QUIC协议使用多路复用(Multiplexing)技术,可以在一个连接上同时传输多个数据流,这些数据流可以独立于彼此进行流量控制和拥塞控制,从而提高了传输效率。此外,QUIC协议还支持零RTT握手,即在第一次连接时就可以发送数据,进一步减少了延迟。
242 0
C# | 实现QUIC协议的客户端与服务端
|
Java 应用服务中间件 网络安全
企业级Nginx实战-配置Https单向认证、双向认证
企业级Nginx实战-配置Https单向认证、双向认证
554 0
企业级Nginx实战-配置Https单向认证、双向认证
EMQ
|
网络协议 中间件 物联网
QUIC 多流桥接、新增 DDS 协议转换代理
即将发布的超轻量 MQTT Broker NanoMQ 0.16为用户提供了2个重要新功能:MQTT over QUIC的多流桥接和DDS协议转换代理,拓宽了其弱网桥接传输性能和在边缘端的使用场景。
EMQ
350 0
QUIC 多流桥接、新增 DDS 协议转换代理
|
域名解析 存储 缓存
网络基础之应用层协议,组织方式,自定义协议和http协议https协议简单介绍(2)
我们在之前的文章里讲过,应用层是应用在各个程序之间的数据沟通,其实应用层协议是面向程序员的,因为这些协议都是程序员写的,是方便程序员在编写程序时完成各个应用程序之间的沟通
122 0
网络基础之应用层协议,组织方式,自定义协议和http协议https协议简单介绍(2)
|
JSON 移动开发 网络协议
网络基础之应用层协议,组织方式,自定义协议和http协议https协议简单介绍(1)
我们在之前的文章里讲过,应用层是应用在各个程序之间的数据沟通,其实应用层协议是面向程序员的,因为这些协议都是程序员写的,是方便程序员在编写程序时完成各个应用程序之间的沟通
163 0
网络基础之应用层协议,组织方式,自定义协议和http协议https协议简单介绍(1)
|
负载均衡
新功能:阿里云负载均衡SLB支持HTTPS虚拟主机功能(SNI)
新功能:负载均衡SLB支持HTTPS虚拟主机功能(SNI)
6012 0
|
负载均衡 监控 网络安全
使用 SLB 部署 HTTPS 业务(单向认证)|学习笔记
快速学习使用 SLB 部署 HTTPS 业务(单向认证)
522 0
使用 SLB 部署 HTTPS 业务(单向认证)|学习笔记