亚马逊AWS官方博客

AWS IoT 物联网系列 | 第二篇:使用模版自动化 IoT 设备创建及证书注册过程 (Just-In-Time Provisioning)

AWS IoT 物联网系列博客

当前物联网环境中,设备类型多种多样,连接方式不一而足。为了帮助读者更好的理解并运用 AWS IoT 相关服务,我们提供了一个完整的 IoT 起步指南,包含设备的注册及上线、设备管理、用户身份及权限管理以及成本控制,通过这一系列的起步指南,也可以快速了解到 AWS IoT 服务如何与 Amazon Alexa 语音助手进行集成。AWS IoT 物联网系列共8篇,本篇是该系列的第一篇,其他篇链接请在本文结尾处查看。

 


背景介绍

利用即时注册(JITR)功能,可以快速的进行设备证书注册及设备上线。但是配置相关 Lambda 函数的方式相对复杂。使用本文介绍的即时部署(JITP)功能,可以简化 IoT 规则和 Lambda 函数的步骤,直接在注册设备 CA 证书的同时附加上一个自定义好的模版。在设备第一次连接 AWS IoT 平台的时候,JITP 会参照该模版的定义来完成设备证书的注册和设备在云端的创建过程。

需要特别注意的是,JITP 作为一个相对比较新的功能,目前在 AWS 中国区还没有部署。如果设备需要连接 AWS 中国区,还是需要使用 JITR 来完成证书注册及设备上线。但对于一些需要在海外使用 AWS 的用户,可以利用这个功能对设备进行设备注册控制。

从上图 JITR 和 JITP 两种方式的对比中可以看出, JITP 简化了部分流程。

JITP 的实现步骤如下:

  1. 创建 CA 证书, 模版和相应的 IAM 权限。
  2. 在 AWS IoT 平台上注册和激活 CA 证书并附加模版。
  3. 使用该 CA 证书签发设备证书并安装在 IoT 设备上。
  4. IoT 设备与 AWS IoT 平台的第一次连接。

本文中的 IoT 设备将会使用一台 Amazon Linux EC2 实例进行模拟,并使用 MQTT Mosquitto Client 工具来模拟 MQTT 终端,IoT 设备的配置工作会在这台 EC2 实例上进行。

创建 CA 证书,模版和相应的 IAM 权限

  • 登陆 EC2 实例并执行如下命令创建私钥和对应的 CA 证书:
$ mkdir cert
$ cd cert
$ openssl genrsa -out CA_Private.key 2048
$ openssl req -x509 -new -nodes -key CA_Private.key -sha256 -days 365 -out CA_Certificate.pem
  • 在最后一步创建 CA 证书时会要求填入 CSR 相关信息,请按照实际情况填写:
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

由于 JITP 是通过模版定义来注册设备证书和创建设备,因此模版中相应的权限必不可少。下面我们在 IAM 中来创建一个角色并赋予相应的权限。

  1. 登陆到 AWS Console 并进入 IAM 页面。
  2. 点击页面左侧的角色后,点击创建角色按钮。
  3. 在创建角色页面选择“AWS产品”中的 IoT,然后点击”下一步:权限”。
  4. 在这个页面中不需要做任何改动,直接点击”下一步:审核”
  5. 填写角色名称“JITP”后,点击创建角色。
  6. 角色创建完成后,点击角色名称 JITP 并记录下角色ARN(arn:aws:iam::12345678910:role/JITP)。

在准备好角色和权限后我们开始创建模版,这个模版会在之后注册 CA 证书的时候一起提交给 AWS IoT Core。

这里的模版实际上就是一个 JSON 文档,里面包含两部分。一部分是参数(Parameters),另一部分是资源(Resource).

Parameters部分你可以定义如下内容:

  • AWS::IoT::Certificate::Country
  • AWS::IoT::Certificate::Organization
  • AWS::IoT::Certificate::OrganizationalUnit
  • AWS::IoT::Certificate::DistinguishedNameQualifier
  • AWS::IoT::Certificate::StateName
  • AWS::IoT::Certificate::CommonName
  • AWS::IoT::Certificate::SerialNumber
  • AWS::IoT::Certificate::Id

在下面的模版中我们定义了两个 Parameters,一个是 AWS::IoT::Certificate::Country,另一个是 AWS::IoT::Certificate::Id。这样在设备首次连接 IoT 平台时,设备证书中对应的这两个字段会被抽取出来用于 Resources 中 Thing 的创建。第二行的 roleARN 是前面创建的角色 JITP 的 ARN(Amazon Resource Names),如果按照步骤做的话应该已经记录下来了。

{
 "templateBody":"{ \"Parameters\" : { \"AWS::IoT::Certificate::Country\" : { \"Type\" : \"String\" }, \"AWS::IoT::Certificate::Id\" : { \"Type\" : \"String\" } }, \"Resources\" : { \"thing\" : { \"Type\" : \"AWS::IoT::Thing\", \"Properties\" : { \"ThingName\" : {\"Ref\" : \"AWS::IoT::Certificate::Id\"}, \"AttributePayload\" : { \"version\" : \"v1\", \"country\" : {\"Ref\" : \"AWS::IoT::Certificate::Country\"}} } }, \"certificate\" : { \"Type\" : \"AWS::IoT::Certificate\", \"Properties\" : { \"CertificateId\": {\"Ref\" : \"AWS::IoT::Certificate::Id\"}, \"Status\" : \"ACTIVE\" } }, \"policy\" : {\"Type\" : \"AWS::IoT::Policy\", \"Properties\" : { \"PolicyDocument\" : \"{\\\"Version\\\": \\\"2012-10-17\\\",\\\"Statement\\\": [{\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\": [\\\"iot:*\\\"],\\\"Resource\\\" : [\\\"*\\\"]}]}\" } } } }",
 "roleArn":"arn:aws:iam::1234567890:role/JITP"
}

我们将这段 JSON 代码保存到 EC2 实例中~/cert 文件夹里面的一个文件中,文件名为 provisioning-template.json。

这个模版实际上规定了在设备连接时, AWS IoT Core 会创建两样东西,一个是 Thing(设备在云上的映射),另外一个是 Policy(操作权限),您可以从模版中 Resources中看到,并且接下来 JITP 还会自动做三件事:

  • 将 Policy 赋予证书
  • 将证书挂载到 Thing 上面
  • 更新证书状态为 Active

在 AWS IoT 平台上注册和激活 CA 证书并附加模版

有了之前的准备工作,我们可以开始注册CA证书和模版到AWS IOT Core。 为了安全,AWS IOT Core提供了相应的审核流程确保你同时持有CA证书和对应的私钥。因此,在最终注册CA证书之前,我们还需要利用CA证书生成一张用于验证CA证书和私钥持有者身份的中间证书。下面这个AWSCLI命令会返回一个随机生成的认证码,这个认证码会和你的账户绑定。记录下这个认证码,很快我们就会用到。

$ aws iot get-registration-code

使用 OpenSSL 生成用于验证身份的私钥和证书请求文件(CSR – Certificate Signing Request):

$ openssl genrsa -out Verification_Private.key 2048

$ openssl req -new -key Verification_Private.key -out Verification.csr

在创建 CSR 的过程中,你会被提示输入如下一些内容,将前一步记录下的认证码填入到 Common Name 中:

...
 Organization Name (eg, company) []:
 Organizational Unit Name (eg, section)
 Common Name (e.g. server FQDN or YOUR name) []: XXXXXREGISTRATIONCODEXXXXX
 ...

接下来,使用 CA 证书和私钥,以及上面创建的 CSR 来生成一份用于验证身份的证书:

$ openssl x509 -req -in Verification.csr -CA CA_Certificate.pem -CAkey CA_Private.key -CAcreateserial -out Verification.crt -days 365 -sha256

最后,通过如下命令导入 CA 证书和中间证书完成 CA 证书的注册和激活。同时,通过设置–allow-auto-registration 的方式,开启设备连接至 IoT Core 时设备证书的自动注册,并通过–registration-config 绑定模版到 CA 证书上。这个命令的输出会返回对应 CA 证书在 AWS IoT Core 上的证书 arn (certificateArn)和证书 ID (caCertificateId).

$ aws iot register-ca-certificate --ca-certificate file://CA_Certificate.pem --verification-certificate file://Verification.crt --set-as-active --allow-auto-registration --registration-config file://provisioning-template.json

这时如果你进入 IoT Core 服务,点击左侧的安全—>CA,会看到我们的 CA 已经注册到了AWS IoT 平台上了。

使用 CA 证书签发设备证书

当我们创建并注册好CA证书之后,就可以开始用这个CA证书来签发设备证书了,步骤如下:

1.创建一个设备证书的私钥 Device.key 和对应的证书请求文件 Device_Certificate.csr:

$ openssl genrsa -out Device.key 2048
$ openssl req -new -key Device.key -out Device_Certificate.csr

2. 使用 CA 证书,CA 证书私钥和证书请求文件签发设备证书 Device_Certificate.crt:

$ openssl x509 -req -in Device_Certificate.csr -CA CA_Certificate.pem -CAkey CA_Private.key -CAcreateserial -out Device_Certificate.crt -days 365 -sha256

IoT 设备与 AWS IoT 的第一次连接

你可以在你的 IoT 设备上安装 AWS IoT SDK,通过自己的代码调用 SDK 来实现所有的功能。这里我们为了简化步骤和节约时间,选择利用 EC2 上安装 MQTT Mosquitto Client 工具来模拟 MQTT 终端。

1.登陆到 EC2 实例并执行如下命令:

$ sudo wget http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo -O /etc/yum.repos.d/mqtt.repo
 $ sudo yum install mosquitto mosquitto-clients -y

2. 如果上面的命令执行时报依赖缺少的错误,可以加上--skip-broken再执行一遍即可

$ sudo yum install mosquitto mosquitto-clients -y --skip-broken

3. 进入到之前创建的 cert 目录

$ cd cert

4. 合并 CA 证书和设备证书到一个新的证书形成有效的证书链:

$ cat Device_Certificate.crt CA_Certificate.pem > Device_CA_Certificate.crt

5. 执行 mosquitto_pub 命令去发布一个消息到对应的 topic 上面,这也是设备与 IoT Core 的第一次连接。如果你回想一下之前的步骤,到目前为止我们的设备证书还只存在于设备上面,并没有在 IoT Core 上注册,那么接下来我们尝试发送一条消息。

$ mosquitto_pub --cafile root-CA.crt --cert Device_CA_Certificate.crt --key Device.key -h xxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com -p 8883 -q 1 -t JITP/test -i anyclientID --tls-version tlsv1.2 -m "Hello" -d
  • 命令中的--cafile 是 IoT 平台的 CA 证书,用于设备去验证 AWS IoT 平台的身份,这个文件可以通过此链接获得。
  • 命令中的--cert 是合并 CA 证书和设备证书后的证书链。
  • 命令中的--key 是设备的私钥。
  • 命令中的-h 是 AWS IoT 平台的接入点,可以通过在 AWS IoT 界面中左下角点击“设置”获得。
  • 命令中的-t 是你要发布消息到哪一个 topic 上,这里我是发布到 JITP/test,你可以选择自己想要
  • 发布的 topic.
  • 命令中的-i 可以按照你希望的名字命名

6. 成功连接并发布消息后会有如下的输出,并且如果你登录 IoT 界面,点击左侧的安全--->证书后可以看到设备证书已经注册并激活了。

Client anyclientID sending CONNECT
Client anyclientID received CONNACK
Client anyclientID sending PUBLISH (d0, q1, r0, m1, 'JITP/test', ... (5 bytes))
Client anyclientID received PUBACK (Mid: 1)
Client anyclientID sending DISCONNECT

参考链接

Setting Up Just-in-Time Provisioning with AWS IoT Core

本篇作者