MQTT Paho + Mosquitto 快速搭建 & 双向认证

1 篇文章 3 订阅

今天继续聊SOA的话题,前面聊过了SOME/IPDDS,很多文章提到SOA协议,还会把HTTP和MQTT也放进来讨论。但个人认为,目前只有SOME/IP和DDS适合作为车载SOA的中间件方案,而HTTP和MQTT则更适合应用于车联网云端交互的场景。

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,因此易于实现。这些特点使得它对很多场景来说都是很好的选择,包括受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT),这些场景要求很小的代码封装或者网络带宽非常昂贵。

MQTT运行在TCP/IP之上,它有以下特点:

  • 使用发布/订阅消息模式,提供了一对多的消息分发和应用之间的解耦。

  • ​消息传输不需要知道负载内容。

  • 提供三种等级的服务质量:“最多一次”,尽操作环境所能提供的最大努力分发消息。消息可能会丢失。例如,这个等级可用于环境传感器数据,单次的数据丢失没关系,因为不久之后会再次发送;“至少一次”,保证消息可以到达,但是可能会重复;“仅一次”,保证消息只到达一次。

  • 很小的传输消耗和协议数据交换,最大限度减少网络流量。

  • 连接异常断开时,能通知到相关各方。

如图,不管对于CP还是AP Autosar,都没有提供MQTT的支持。因此,对于跑Autosar的ECU来说,很难实施MQTT Client,更不要说Broker了。对于非Autosar的ECU来说,MQTT Client的实施是容易的,但是能不能作为Broker就得打个问号了。前面讨论过几种通信模型,MQTT是典型的Broker模型:

互联网通常具备性能强大的后端服务器,完全有能力部署Broker,承受百万级别的连接,还可以支持身份认证、动态主题、主题过滤、集群等,尤其是主题的管理,我认为是不可或缺的功能点,ECU可以实现吗?即使可以,我想对性能的挑战也会不小。因此,对于非Autosar的ECU来说,MQTT更多的应用场景是实现MQTT的客户端,与云端进行通信,可能还需要进行云端消息与车载SOA消息间的转化,从而实现远程控制、远程升级、大数据采集等常见功能。

下面我以初步体验一下MQTT作为小目标,快速搭建了一个Paho MQTT Client + Mosquitto MQTT Broker的试验环境,先简单介绍一下它俩:

Eclipse Mosquito 是一个开源(EPL/EDL许可)消息代理,它实现了MQTT协议版本5.0、3.1.1和3.1。Mosquito是轻量级的,适用于从低功耗单板机到全服务器的所有设备。

Eclipse Paho 以各种编程语言提供了MQTT客户端的开源(EPL/EDL许可)实现:

以前觉得Eclipse是做IDE的,还不咋好用,又肤浅了。

下面以Paho C 同步接口为例,实现两个客户端,一个订阅主题,一个发布主题消息,通过Broker进行通信,关于下载和安装,依然写在README中,关注公众号回复“演示代码”就可以看到完整Demo代码的Github链接。运行结果如下:

从这个示例,可以看出,两个客户端之间彼此独立,它们只分别与Broker进行通信,代码比较简单,按照官方示例的调用顺序,配置通信参数就可以了,用Wireshark抓取数据包(3.4.2版本完美支持MQTT协议):

现在问题来了,在互联网环境中,这样的通信是非常不安全的,所有消息几乎都在裸奔,并且只要连接建立起来,任何应用都可以订阅/发布任何主题的任何消息,显然,这是不能接受的。那么,如何实现常用的双向认证呢?首先,在编译Paho C++ Client库时需要打开PAHO_WITH_SSL开关,接下来用脚本(在生产环境中,可以定制生成证书的脚本)简单制作测试用的CA:

mkdir myCA
wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh
chmod +x generate-CA.sh
# 生成服务端证书
./generate-CA.sh server
# 用生成的CA,生成客户端证书
openssl genrsa -out client.key 2048
openssl req -new -out client.csr -key client.key -subj "/CN=client/O=example.com"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ./ca.srl -out client.crt -days 3650 -addtrust clientAuth

简单测试一下,CA是否可用:

openssl verify -CAfile ca.crt server.crt
openssl verify -CAfile ca.crt client.crt

创建配置文件ca_test.conf:

listener 8883
cafile /home/lxl/Develop/myCA/ca.crt
certfile /home/lxl/Develop/myCA/server.crt
keyfile /home/lxl/Develop/myCA/server.key
require_certificate true
use_identity_as_username true

用这个配置文件启动mosquitto:

mosquitto -c ./ca_test.conf

用mosquitto提供的测试程序,验证SSL连接是否成功:

mosquitto_sub -h 127.0.0.1 -p 8883 -t "TestTopic" --cafile /home/lxl/Develop/myCA/ca.crt --cert /home/lxl/Develop/myCA/client.crt --key /home/lxl/Develop/myCA/client.key
mosquitto_pub -h 127.0.0.1 -p 8883 -t "TestTopic" -m "this is SSL" --cafile /home/lxl/Develop/myCA/ca.crt --cert /home/lxl/Develop/myCA/client.crt --key /home/lxl/Develop/myCA/client.key

验证OK后,可以着手改代码了,主要是在建立连接前配置SSL选项的参数(具体可以查看完整代码):

MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
conn_opts.ssl = &ssl_opts;
conn_opts.ssl->trustStore = "/home/lxl/Develop/myCA/ca.crt";
conn_opts.ssl->keyStore = "/home/lxl/Develop/myCA/client.crt";
conn_opts.ssl->privateKey = "/home/lxl/Develop/myCA/client.key";
conn_opts.ssl->enableServerCertAuth = true;

运行效果和前面基本一致,再用Wireshark捕获一下数据包看看:

Nice,终于不再裸奔啦~ 

双向认证只是安全措施的一种,还可以加持其他措施,如身份认证、针对主题的权限管理等,以增强安全性。

最后,和HTTP相比,MQTT是为物联网而生的协议,主要体现在:它比HTTP更加轻量,协议更精简,消息头更短,这些都提高了它的响应时间和吞吐量,并降低了开销和功耗。MQTT也有不适用的场景,比如大文件、音视频等,就要考虑其他传输方案了。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值