#iot-devices #aws-iot #iot #aws #encryption #device-shadow #fleet-provisioning

iot_device_bridge

设备与云IoT(例如AWS)之间的桥梁

3个稳定版本

1.1.1 2022年7月4日
1.1.0 2022年6月23日
1.0.0 2022年6月5日

#26 in #iot-devices

MIT许可证

135KB
2.5K SLoC

iot-device-bridge

此仓库包含用于IoT MQTT消息、车队配置和设备阴影的Rust组件库和运行应用程序。

IoT桥设计

IoT Bridge Design

图示显示了基本设计,其中用连续线指示当前已实现的组件。

这些组件实现以下功能

  • 基本配置操作(配置属性存储在config.yaml文件中)
  • 基本消息客户端操作
    • 连接到云IoT(AWS IoT Core或其他系统)
    • 通过MQTT连接到设备(可以扩展到其他消息系统,如AMQP、DDS/ROS2)
    • 监听传入的事件
    • 订阅主题
    • 发布到主题
  • 车队配置实现AWS "通过声明进行配置"工作流程,带有CreateCertificateFromCsr
  • 基本设备适配器操作
    • 将设备事件主题映射到IoT主题
    • 过滤设备传入的事件
    • 将消息格式标准化为标准(cloudevents.io)并扩展
  • 设备阴影(AWS)
    • device_shadow
      • 设置事件映射规则
      • 设置事件过滤规则
    • iot_shadow
      • 证书轮换请求(通过在云阴影中设置参数,IoT桥开始基于CSR的证书更新)
      • 关于负载加密的方法和密码的加密信息(适用时待定)
      • 关于负载匿名化的方法和密码的加密信息(适用时待定)

有关详细信息,请参阅artifacts下载处的IoT桥代码文档

IoT桥任务交互

IoT桥广泛使用异步多线程处理。以下图形总结了任务交互。这是一个在Gitlab和Github的markdown中清晰可见的mermaid绘制,但在某些其他环境中(如crates.io)可能不可见。

备注:device_interfaceiot_interface不是明确的IoT桥任务,而是对应于相应的消息接口的连接。

sequenceDiagram
  participant DI as device_interface
  participant DM as device_monitor_thread
  participant DR as device_receiver_thread
  participant DS as device_shadow_thread
  participant IS as iot_shadow_thread
  participant IT as iot_transmitter_thread
  participant IR as iot_receiver_thread
  participant IM as iot_monitor_thread
  participant II as iot_interface

  II-)IM: receive MQTT message
  IM-)IR: receive event
  IR->>IR: connector_aws::on_iot_event
  alt event for IoT Shadow
    IR-)IT: send response to IoT
    IR-)IS: send shadow value
    IS->>IS: trigger cert rotation
  else event for Device Shadow
    IR-)IT: send response to IoT
    IR-)DS: send shadow value
    DS->>DS: device_adapter::on_receive_device_shadow
  end

  DI-)DM: receive MQTT message
  DM-)DR: receive event 
  DR->>DR: device_adapter::on_device_event
  DR-)IT: send device message to IoT
  IT-)II: send MQTT device message to IoT

设备阴影交互

基于设备影子 - MQTT 主题中的参考架构。该实现区分了设备状态(Rust 中的对象 struct)和本地影子(设备状态的副本 serde_json::Value,包含额外信息)。下面的序列图涵盖了主要的“正面”情况(即,没有拒绝)。

观察:当属性的值设置为 null 时,不会发送 UPDATE_DELTA。

sequenceDiagram
  participant D as Device State
  participant I as IoT Bridge
  participant L as Shadow @ Device
  participant R as Shadow @ Cloud
  participant C as Cloud Application

  Note right of L: Shadow Subscription
  L-)R: SUBSCRIBE (UPDATE_ACCEPTED, UPDATE_REJECTED, UPDATE_DELTA) 

  Note right of L: Fleet Provisioning
  I-)R: UPDATE[reported] (Initialize IoT Bridge / Connector State Shadow at Provisioning with Defaults)
  I-)R: UPDATE[desired & reported] (Initialize Device State Shadow at Provisioning with Defaults)
  R-)L: UPDATE_ACCEPTED (Device State)
  L->>D: Transform & Store

  Note right of L: IoT Bridge Start
  I-)R: UPDATE[reported] (Send IoT Bridge / Connector State)
  L-)R: GET (Get Device State Shadow at Start)
  R-)L: GET_ACCEPTED
  L->>D: Transform & Store

  Note right of L: Change by Cloud Application (filtering / mapping)
  C->>R: UPDATE[desired] (filter/map change)
  R-)L: UPDATE_DELTA (Device State Shadow)
  par Shadow@Device to Shadow@Cloud
    L-)R: UPDATE[reported] (Device State Shadow)
  and Shadow@Device to Device State
    L-)D: Transform & Store
  end

  Note right of L: Certificate Rotation by Cloud Application
  C->>R: UPDATE[desired] (cert rotation request)
  R-)L: UPDATE_DELTA (IoT Bridge / Connector State Shadow)
  par Shadow@Device to Shadow@Cloud
    L-)R: UPDATE[reported] (IoT Bridge / Connector State Shadow)
  and Shadow@Device to IoT Bridge / Connector
    L-)I: Initiate Certificate Rotation
  end
  I->>I: Execute Certificate Rotation

IoT 桥接配置

IoT 桥接配置部分 device 是针对特定设备的,这里不予讨论。

iot 部分配置了与 IoT 基础设施的连接——以下主要关注 AWS 解决方案。

以下所有值仅为占位符,请用您专有的值替换。

IoT 连接

如果不需要考虑特定要求,以下元素可以保持定义不变。

  shadow_name: iot_shadow
  client_registration_status: INITIAL
  ca_path: AmazonRootCA1.pem

以下元素针对组/设备群的 IoT 连接特定。

  iot_topic_prefix: SPDIF/X320/16A8/
  client_id: 16A8_99998
  endpoint: ENDPOINTID-ats.iot.eu-central-1.amazonaws.com
  port: 8883

设备群配置

对于 AWS 设备群配置,以下配置元素应相应准备并存储,例如,在 device-iot.config/certs 文件夹中

  claim_cert_path: ClaimCertificate.pem
  claim_priv_key_path: ClaimPrivateKey.pem
  claim_pub_key_path: ClaimPubKey.pem

此外,还需要设备群配置模板,并应引用(例如,provisioning_template_name: iot-16A8-prov-templ)以及相应的配置策略和设备策略。有关详细信息,请参阅 AWS 文档。

注册状态 client_registration_status: INITIAL 触发设备群配置。成功注册后,状态变为 REGISTERED:thingname

以下列出的客户端(设备实例)特定元素将在设备群配置期间生成

  client_cert_path: IotCertificate.pem
  client_priv_key_path: IotPrivateKey.pem
  client_pub_key_path: IotPubKey.pem

数据负载加密

在高保密性环境中,除了使用安全通道(如 mTLS)之外,可能还需要在数据负载中进行加密。这对于源(设备)和事件接收者之间的端到端保密性特别有趣。实现数据负载加密的功能使用基于 AES-GCM-256 和 HKDF-SHA256 的 ECIES(椭圆曲线集成加密方案),并使用 secp256k1 曲线。

该方法在 Golang、Python、Rust 和 Typescript 等可互操作的库中实现...即,这些语言也用于后端(例如,Golang 中的解密 lambda 函数 – 请参阅测试文件夹中的 decryption-lambda-go)。

此加密框架被标准化为:ISO/IEC 18033-2:2006,并在 标准高效密码学组的第 5.1 章中描述。

加密可以“开启/关闭”,并且公钥应通过 IotShadow 分发,例如。

{
  "iot_registration_status": {
    "Registered": "98765"
  },
  "data_encryption_config": {
    "method": "EciesSecp256k1",
    "public_key": [
      4,89,117,155,81,243,172,179,
      90,195,137,53,151,179,94,29,
      83,81,109,41,239,43,231,104,
      14,189,163,2,229,86,3,148,
      164,194,250,198,166,60,62,162,
      124,188,178,137,87,61,52,245,
      18,210,207,175,130,234,120,161,
      45,205,156,7,34,37,164,106,
      128
    ]
  }
}

备注:秘密显然存储在安全设施中,如 AWS Secret Manager。

依赖关系

~18–33MB
~561K SLoC