MQTT连接AWS IoT

MQTT连接AWS IoT
THEDIMQTT常见连接方式
MQTT(Message Queuing Telemetry Transport)支持多种不同的连接方式,主要体现在传输层协议和安全特性的选择上。下面分别介绍常见的几种连接方式及其区别和适用场景。
明文TCP连接(tcp)
- URI格式:
mqtt://<broker-address>:1883
- 端口:1883(默认)
- 安全性:无加密,明文传输
- 客户端认证:常为用户名/密码(可选)
- 适用场景:
- 内网环境/本地测试
- 对安全性要求不高的应用
- 缺点:
- 数据易被窃听/篡改,不建议在公网环境使用
- 备注:
- AWS IoT Core等云服务不允许明文MQTT
单向TLS加密(ssl/tls)
- URI格式:
ssl://<broker-address>:8883
- 端口:8883(默认)
- 安全性:TLS加密,客户端校验服务端证书CA根证书
- 客户端认证:通常为用户名/密码,也可仅凭CA根证书
- 适用场景:
- 需要加密传输但不强制客户端证书认证的应用
- 缺点:
- 客户端未被服务端验证,安全性一般
- 备注:
- 部分云服务支持,但AWS IoT Core不支持单向,只支持双向认证
双向TLS/证书认证(ssl_mutual_auth)
- URI格式:
ssl://<broker-address>:8883
或mqtts://<broker-address>:8883
- 端口:8883
- 安全性:TLS加密,双向证书认证(mTLS)
- 客户端认证:必须加载CA根证书、客户端证书、客户端私钥
- 适用场景:
- 高安全需求(如工业物联网、金融、云服务)
- AWS IoT Core等云服务的推荐/强制方式
- 优点:
- 服务端和客户端都能确认对方身份,安全性高
基于WebSocket的MQTT(ws/wss)
ws(明文WebSocket)
- URI格式:
ws://<broker-address>:80
- 端口:80
- 安全性:无加密,明文
- 适用场景:内网、开发测试、受限于Web环境
- URI格式:
wss(加密WebSocket)
- URI格式:
wss://<broker-address>:443
- 端口:443
- 安全性:TLS加密
- 适用场景:
- 需要穿越防火墙/代理
- Web App、云平台集成
- 备注:AWS IoT Core支持wss方式,不支持ws
- URI格式:
设备安全模块/硬件加密(ssl_ds)
- 说明:证书和密钥存储在安全芯片/模块(如TPM、ATECC)内,提升物理安全。
- 适用场景:高安全需求的物联网设备
预共享密钥TLS(ssl_psk)
- URI格式:
ssl://<broker-address>:8883
- 端口:8883
- 安全性:TLS加密,认证基于PSK(Pre-Shared Key)
- 客户端认证:通过预共享密钥
- 适用场景:
- 设备资源受限,无法安全存储证书
- 缺点:
- PSK管理复杂,不如证书灵活
- AWS IoT Core不支持此方式
选择建议
- 本地测试:
tcp 或 ws
- 公网/生产环境:ssl_mutual_auth 或 wss
- AWS IoT Core:
强烈建议使用 ssl_mutual_auth(双向证书认证)
小结对比表
方式 | 安全性 | 端口 | 认证类型 | 适用云服务 |
---|---|---|---|---|
tcp | 低 | 1883 | 可选用户名密码 | 无 |
ssl | 较高 | 8883 | 服务器证书 | 有些支持 |
ssl_mutual_auth | 很高 | 8883 | 双向证书 | AWS/阿里云等 |
ssl_psk | 较高 | 8883 | PSK密钥 | 少数支持 |
ws | 低 | 80 | 可选 | 无 |
wss | 很高 | 443 | 可选 | AWS/阿里云等 |
推荐生产环境优先使用TLS加密和证书双向认证,保障设备和数据安全。
例程:使用MCU连接至AWS IoT
快速连接
- 在AWS IoT的连接界面,执行图中步骤,使用ping测试是否连通。
该服务器地址的作用:
- AWS IoT Core 设备连接地址
- 这是你所有物联网设备(比如 MCU、网关、传感器等)连接到 AWS IoT 云服务时要用的服务器地址。
- 设备在进行 MQTT/TLS 或 WSS 连接时,服务器地址就是这一串。
- 唯一标识你的 AWS IoT 实例
- 每个 AWS 账号在每个区域的 IoT Core 都有唯一的 endpoint,类似于你的“云端大门”。
- 设备必须通过这个 endpoint 才能连接和收发数据。
- 用于连通性测试
- 在当前页面建议用 ping 命令测试该 endpoint,确认你的设备能正常访问 AWS 云端(网络连通性OK)。
- 只有 ping 通这个 endpoint,设备后续才能成功连接和通信。
- 创建新事物Thing(第一次使用的话),并取名
- 选择对应的平台和SDK语言,后续AWS会准备相应语言的示例代码、依赖包、工具指令、帮助快速连接设备。
这里我们选择windows 和 python
- 下载对应的连接工具包。该数据包中包含python测试连接的脚本,以及相应的
CA根证书
、客户端证书
、客户端私钥
。这三个证书在后面的双向认证会使用
- 解压后在根目录运行该脚本后,会先准备环境。然后目录下会出现根证书root-CA.crt和python的sdk,同时此处的订阅和本地的终端上都能订阅到消息,即测试连接成功
手动创建物品Things连接
创建Things
- 在管理->所有设备下->物品,可以我们的创建的
Things
进行管理,之前快速连接的Things也会出现在这里。
我们可以在此页面直接创建Things
- 选择创建单个物品或多个物品,然后点击下一步即可
配置Things属性、证书
- 配置相关物品属性、证书
- 创建自定义物品名称,其他配置可选,同时设备影子是用于设备与AWS同步使用,这里我们不使用
- 配置设备证书,这里我们使用AWS IoT的自动生成。包括root-CA、公有密钥和私有密钥
物品证书策略附加与创建
- 将策略附加到证书
AWS IoT策略
(Policy)类似于一组“权限规则”,控制你的物联网设备(通过证书、IAM或其它身份)对AWS IoT资源的访问能力。
它本质上和IAM策略很像,但专门用于设备和IoT资源,主要作用是:
- 授权设备发布(Publish)/订阅(Subscribe)特定主题(Topic)
- 授权设备连接(Connect)到特定客户端ID
- 控制哪些消息流向设备,哪些操作被允许
这里可以看到之前创建的一些策略,但是我们通常对不同Things会有不同的策略,所以我们要新建策略,点击新建策略
创建策略页面:
自定义策略的名称:MY_SHT20_POLICY
,下方的选择允许
策略效果
策略操作:选择对应的策略操作,包括CONNECT(连接到AWS权限)、PUBLISH(发布权限)。这里我们选择所有权限(用 * 表示)
策略资源:填写允许访问的资源 ARN
格式通常为:
Topic发布:arn:aws:iot:ap-northeast-2:你的账号ID:topic/你的topic名
Topic订阅:arn:aws:iot:ap-northeast-2:你的账号ID:topicfilter/你的topic名
Connect:arn:aws:iot:ap-northeast-2:你的账号ID:client/你的clientId
通配符:
我们可以使用
*
作为通配符(如允许所有 topic,可以写arn:aws:iot:ap-northeast-2:你的账号ID:topic/*
),但不建议无脑填*
,要遵循最小权限原则。
IoT策略是一个JSON对象,我们通常使用JSON来配置更方便,选择生成器右边的JSON
格式中:”Effect”、”Action” 、”Resource” 分别对应上述的策略效果、策略操作、策略资源,生成器中对应的填写也会在这边同步
基本策略示例如下:共有三个部分,分别是对不同资源的,不同权限分配
第一部分:
允许发布和接收消息
效果:
允许(Allow)被附加此策略的设备/证书对指定的3个MQTT主题(topic)进行如下操作:
- iot:Publish:向指定 topic 发布消息
- iot:Receive:接收从这些 topic 发送来的消息
- iot:PublishRetain:发布带有 Retain 标记的消息(即保留消息)
只限于这3个指定的topic:
/sdk/test/java
,/sdk/test/python
,/sdk/test/js
。其余设备向其余topic发布消息都不行
第二部分:
允许订阅主题过滤器
效果:
允许设备/证书 订阅(Subscribe)这3个主题(topic)过滤器。
主题过滤器(topic filter)用于 MQTT 订阅操作,控制设备能订阅哪些主题。未出现topic将会订阅失败
例如,设备可以通过这些过滤器订阅
/sdk/test/java
等topic的消息。
第三部分:
允许连接(Connect)
允许设备以指定的Client ID连接到 AWS IoT Core,
具体是:
sdk-java
basicPubSub
- 以及所有以
sdk-nodejs-
开头的 Client ID(因为sdk-nodejs-*
使用了通配符)只有用这些 Client ID 连接时才被允许,否则连接将会连不上
证书全OK,但是连接不上
所以一定要在这里配置指定的client_id,同时连接mqtt时一定要指定对应策略允许的client_Id
策略示例1:
全部操作全部资源都允许
1 | { |
"Action": "*"
表示允许所有操作(如 Connect、Publish、Subscribe、Receive 等)。"Resource": "*"
表示对所有资源(全部 topic、全部 clientId、全部 topicfilter)都允许。这样配置后,连接的MCU可以以任意Client_id连接AWS,同时向任意Topic发布任意消息,订阅任意Topic
⚠️ 注意:最小权限原则是最佳实践,实际生产建议只授权需要的操作和资源。
仅在开发或调试阶段用全允许策略,防止误操作或安全隐患。
策略示例2:
指定资源允许(SHT20温湿度举例)
1 | { |
我们回到之前创建Things附加策略到证书的页面,可以发现已经多了新附加的策略,我们选择相应策略,然后创建Things即可
下载证书
点击创建后将会出现提供下载的证书,出现的所有证书都要下载,最好像快速连接的做法那样将所有证书下载后保存到一起
设备证书:
- 作用:这是分配给你设备的唯一标识凭证(公钥证书),用于证明设备身份。
- 用途:设备连接 AWS IoT Core 时,需携带此证书进行身份认证。
密钥文件:
- 作用:用于加密和解密通讯内容,确保数据安全。每个证书都配有一对密钥:公钥和私钥。
- 公有密钥文件(Public Key):一般不直接使用,主要用于加密、验证签名等。
- 私有密钥文件(Private Key):必须妥善保存,只下载一次! 设备用它和证书配合完成身份认证。
- 用途:设备连接 AWS IoT 时,需同时用到证书文件和私钥文件。
- 注意:私钥丢失后无法再次下载,只能重生成新证书。
根CA证书:
- 作用:这是 AWS IoT 使用的权威机构签发的根证书,用于验证 AWS 云端的身份,是 TLS 连接的信任基础。
- 用途:设备在连接 AWS IoT Core 时需要用到根 CA 证书,确认自己连接的是“真正的”AWS服务器而非冒充者。
- 选择:有多种加密算法(RSA 2048、ECC 256)可供选择,下载一种与你设备SDK/固件兼容的即可,我们一般选择RSA。
一般只会使用三个证书进行双向认证
pem.crt:客户端证书
private.key:私钥
ca.crt:根CA证书
物品证书策略修改与删除
找到对应的物品,点击进入
这里可以看到物品的证书,我们这里可以对证书进行操作,也可以进行分离证书和重新创建证书
点击证书进入就是策略,可以对证书附加的策略进行删除和修改
MCU连接AWS
我们使用指定策略进行连接,使用类似于ESP32的W800MCU进行连接
策略:
指定资源允许(SHT20温湿度举例)
1 | { |
AWS只能通过双向TLS/证书认证(ssl_mutual_auth),所以我们需要在AWS生成证书的时候保存的三个证书:CA根证书
、客户端证书
和私钥
,将其放到项目根目录下
在MQTT测试客户端处找到我们的**端点(ENEPOINT)**的链接:
配置中,设置对应的wifi并连接,以及服务器的URL,使用ssl或者mqtts。
使用文件嵌入代码的功能,加载对应的三个证书
配置MQTT
:对应的URL
、三个证书
、认证模式:选择双向认证
client_id:
这个参数需要看AWS上的策略,这里是只能允许sht20连接,所以我们必须设置为sht20,否则将连接不上。如果策略允许所有client连接,可以不用指定,使用默认client_id即可
启动MQTT
:注意要使用SNTP同步MCU系统时间,否则会出现TLS握手失败的问题。以下是正常发布和订阅,以及未连接上的情况
正常mqtt连接成功发布和订阅
:
未同步时间:SSL handshake失败,return -0x2700
946684800这个时间是2000-01-01 00:00:00,设备时间不对
mbedtls_ssl_handshake returned -0x2700
这是 mbedtls 的通用 TLS 握手失败错误,常见原因是证书校验失败。
如果设备时间不对,mbedtls 会认为证书“未生效”或“已过期”,导致握手失败。
客户端id不被允许:SSL handshake成功,mqtt连接失败
该情况是同步时间,client_id不对,就会导致证书通过,mqtt连接不上