如何在 AWS IoT Core 中使用 JITP?
我想设置一个即时预置 (JITP) 环境,其中具有在 AWS IoT Core 中注册的自定义根证书颁发机构 (CA)。
简短描述
要使用 AWS IoT Core 设置 JITP 环境,请先向 AWS IoT Core 注册您的 CA 证书。然后,将预置模板附加到您的 CA。
解决方法
**注意:**如果在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误消息,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
创建自签名的根 CA 和验证证书
先决条件:
安装 OpenSSL。
要创建自签名的根 CA 和验证证书,请执行以下操作:
-
创建设备根 CA 私钥并运行以下 OpenSSL 命令:
$ openssl genrsa -out deviceRootCA.key 2048 -
打开 VIM 文本编辑器,然后创建自定义 OpenSSL.conf 文件。有关 VIM 文本编辑器的更多信息,请参阅 Vim Tips Wiki 网站上的教程。
-
要创建自定义 OpenSSL.conf 文件,请运行以下 VIM 命令:
$ vi deviceRootCA_openssl.conf -
要编辑 .conf 文件,请按键盘上的 i。然后,将以下内容复制并粘贴到文件中:
[ req ] distinguished_name = req_distinguished_name extensions = v3_ca req_extensions = v3_ca [ v3_ca ] basicConstraints = CA:TRUE [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = IN countryName_min = 2 countryName_max = 2 organizationName = Organization Name (e.g., company) organizationName_default = AMZ -
要保存 .conf 文件,请按键盘上的 Esc,然后按键盘上的 :wq!。要退出文件,请按 Enter。
-
要确认 openSSL.conf 文件已创建,请运行以下 Linux 命令:
$ cat deviceRootCA_openssl.conf -
创建设备根 CA 证书签名请求 (CSR)。运行以下 OpenSSL 命令:
$ openssl req -new -sha256 -key deviceRootCA.key -nodes -out deviceRootCA.csr -config deviceRootCA_openssl.conf -
创建设备根 CA 证书。运行以下 OpenSSL 命令:
$ openssl x509 -req -days 3650 -extfile deviceRootCA_openssl.conf -extensions v3_ca -in deviceRootCA.csr -signkey deviceRootCA.key -out deviceRootCA.pem -
检索您要使用 JITP 的 AWS 区域的注册码。然后,运行以下 AWS CLI 命令:
$ aws iot get-registration-code --region us-east-2**注意:**将 us-east-2 替换为要使用 JITP 的区域。
-
创建验证密钥。运行以下 OpenSSL 命令:
$ openssl genrsa -out verificationCert.key 2048
- 创建验证证书 CSR。运行以下 OpenSSL 命令:
$ openssl req -new -key verificationCert.key -out verificationCert.csr
然后,在 Common Name(常用名称)字段中输入注册码。例如: 常用名称(服务器 FQDN 或您的名称)[]:xxxxxxxx8a33da。
将其他字段留空。
- 创建验证证书。运行以下 OpenSSL 命令:
$ openssl x509 -req -in verificationCert.csr -CA deviceRootCA.pem -CAkey deviceRootCA.key -CAcreateserial -out verificationCert.crt -days 500 -sha256
**重要事项:**当 AWS IoT Core 认证验证证书时,需要用到您的根 CA 区域的注册码。
有关更多信息,请参阅即时预置。
创建 JITP 模板
-
为您的 AWS IoT Core 服务创建 AWS Identity and Access Management (AWS IAM) 角色。将其命名为 JITPRole。有关说明,请参阅创建日志角色。
**重要事项:**在以下 JITP 模板中,您必须包含 IAM 角色的 Amazon 资源名称 (ARN)。
-
使用 VIM 文本编辑器创建 JITP 模板 JSON 文件。完成以下步骤:
-
创建 JITP 模板 JSON 文件。运行以下 VIM 命令:
$ vi jitp_template.json**注意:**确保使用文件名为 jitp_template.json 保存模板。
-
要编辑 JITP 模板,请按键盘上的 i。然后,将以下 JITP 模板复制并粘贴到文件中:
{ "templateBody":"{ \"Parameters\" : { \"AWS::IoT::Certificate::CommonName\" : { \"Type\" : \"String\" },\"AWS::IoT::Certificate::Country\" : { \"Type\" : \"String\" }, \"AWS::IoT::Certificate::Id\" : { \"Type\" : \"String\" }}, \"Resources\" : { \"thing\" : { \"Type\" : \"AWS::IoT::Thing\", \"Properties\" : { \"ThingName\" : {\"Ref\" : \"AWS::IoT::Certificate::CommonName\"}, \"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:Connect\\\" ], \\\"Resource\\\": [ \\\"arn:aws:iot:us-east-2:<ACCOUNT_ID>:client\\\/${iot:Connection.Thing.ThingName}\\\" ] }, { \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": [ \\\"iot:Publish\\\", \\\"iot:Receive\\\" ], \\\"Resource\\\": [ \\\"arn:aws:iot:us-east-2:<ACCOUNT_ID>:topic\\\/${iot:Connection.Thing.ThingName}\\\/*\\\" ] }, { \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": [ \\\"iot:Subscribe\\\" ], \\\"Resource\\\": [ \\\"arn:aws:iot:us-east-2:<ACCOUNT_ID>:topicfilter\\\/${iot:Connection.Thing.ThingName}\\\/*\\\" ] } ] }\" } } } }", "roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/JITPRole" }**注意:**将 roleArn 值替换为 AWS IoT Core 服务的 IAM 角色 ARN。使用您的 AWS 账户 ID 替换该值。请将 us-east-2 替换为您的 AWS 区域。
-
要保存 JITP 模板文件,请按键盘上的 Esc,然后按 :wq!。
-
选择 Enter 退出该文件。
**注意:**示例 JITP 模板中包含以下 IAM 策略:
您必须登录您的 AWS 账户才能查看策略链接。有关更多信息,请参阅预置模板。
向 AWS IoT Core 注册您的自签名根 CA 证书
-
在 AWS IoT Core 中将设备根 CA 注册为 CA 证书。
-
运行以下 register-ca-certificate AWS CLI 命令:
$ aws iot register-ca-certificate --ca-certificate file://deviceRootCA.pem --verification-cert file://verificationCert.crt --set-as-active --allow-auto-registration --registration-config file://jitp_template.json --region us-east-2**注意:**将 us-east-2 替换为要使用 JITP 的区域。
**注意:**使用参数 --registration-config 将您创建的 JITP 模板附加到 CA 证书。要返回 CA 证书的 ARN,请使用命令响应。
有关更多信息,请参阅注册您的 CA 证书。
创建设备证书并执行 JITP
**重要事项:**确保使用创建原始设备根 CA 文件的相同目录。
-
下载 RootCA1 并将其保存为文件名 awsRootCA.pem。
**注意:**RootCA1 用于对向 AWS IoT Core 的发布请求进行服务器端身份验证。有关更多信息,请参阅用于服务器身份验证的 CA 证书。
-
创建设备私钥。运行以下 OpenSSL 命令:
$ openssl genrsa -out deviceCert.key 2048 -
创建 CSR 设备。运行以下 OpenSSL 命令:
$ openssl req -new -key deviceCert.key -out deviceCert.csr**重要事项:**示例 JITP 模板要求 ThingName 值等于证书的 CommonName 值。该模板还要求 CountryName 值等于 CA 证书中的 Country 值。例如:
Country Name (two-letter code) []:IN Common Name (e.g. server FQDN or YOUR name) []: DemoThing本文中提供的 JITP 模板还使用了 AWS::IoT::Certificate::Country 证书参数,该参数需要您添加一个值。其他可能用到的证书参数包括: 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
-
创建设备证书。运行以下 OpenSSL 命令:
$ openssl x509 -req -in deviceCert.csr -CA deviceRootCA.pem -CAkey deviceRootCA.key -CAcreateserial -out deviceCert.crt -days 365 -sha256 -
将根 CA 证书和设备证书合并在一起。运行以下命令:
$ cat deviceCert.crt deviceRootCA.pem > deviceCertAndCACert.crt -
使用 Eclipse Mosquitto 对 AWS IoT Core 进行测试发布调用并启动 JITP 流程。
**注意:**您还可以使用 AWS Device SDK 对 AWS IoT Core 进行 Publish 调用。
Eclipse Mosquitto 测试发布调用命令示例
重要事项:在运行命令之前,将 a27icbrpsxxx-ats.iot.us-east-2.amazonaws.com 替换为您自己的端点。要确认您自己的端点,请打开 AWS IoT Core 控制台。然后,选择 Settings(设置)。您的端点显示在自定义端点窗格中。
$ mosquitto_pub --cafile awsRootCA.pem --cert deviceCertAndCACert.crt --key deviceCert.key -h a27icbrpsxxx-ats.iot.us-east-2.amazonaws.com -p 8883 -q 1 -t foo/bar -i anyclientID --tls-version tlsv1.2 -m "Hello" -dEclipse Mosquitto 测试发布调用命令的响应示例
Client anyclientID sending CONNECT Error: The connection was lost. // The error is expected for the first connect call注意:测试发布调用首次失败。当 AWS IoT Core 收到测试发布调用时,它会创建证书、策略和 Thing。它还将策略附加到证书,然后将证书附加到 Thing。下次执行 JITP 时,使用的是最初创建的 AWS IoT Core 策略。新的 AWS IoT Core 策略尚未创建。
-
通过执行以下操作确认所需资源已创建:
打开 AWS IoT Core 控制台。
选择 Manage(管理)。
选择 Things(物)。
选择 DemoThing。 -
验证证书是否已创建且处于活动状态。然后,选择策略并验证 IAM 策略是否已附加。
在常规操作中使用设备证书
注意:在发布命令中添加的客户端 ID 的值必须与 JITP 过程中创建的 ThingName 相匹配。添加到发布命令的主题名称还必须遵循 ThingName/* 的格式。在下次发布调用中,您可以使用 deviceCert.crt,而不是 deviceCertAndCACert.crt。
-
打开 AWS IoT Core 控制台。
-
选择 Test(测试)。
-
对于 Subscription Topic(订阅主题),输入 DemoThing/test。
-
运行以下对 AWS IoT Core 的 Eclipse Mosquitt 发布调用命令:
重要事项:在运行命令之前,将 a27icbrpsxxx-ats.iot.us-east-2.amazonaws.com 替换为自己的端点。要确认您自己的端点,请打开 AWS IoT Core 控制台。然后,选择 Settings(设置)。您的端点显示在自定义端点窗格中。此外,请确保使用由您的自定义根 CA 生成的自定义设备证书。
$ mosquitto_pub --cafile awsRootCA.pem --cert deviceCert.crt --key deviceCert.key -h a27icbrpsxxx-ats.iot.us-east-2.amazonaws.com -p 8883 -q 1 -t DemoThing/test -i DemoThing --tls-version tlsv1.2 -m "Hello" -d运行命令后,将在 AWS IoT Core 测试控制台上收到消息。
创建其他设备证书
要创建更多设备证书并将其注册到 AWS IoT Core,请重复创建设备证书并执行 JITP 部分中概述的步骤。
其他 JITP 模板
要从证书的 ** CommonName** 字段中获取 ThingName 值并在策略中提供管理员权限,请使用以下 JITP 模板:
{ "templateBody":"{ \"Parameters\" : { \"AWS::IoT::Certificate::CommonName\" : { \"Type\" : \"String\" },\"AWS::IoT::Certificate::Country\" : { \"Type\" : \"String\" }, \"AWS::IoT::Certificate::Id\" : { \"Type\" : \"String\" }}, \"Resources\" : { \"thing\" : { \"Type\" : \"AWS::IoT::Thing\", \"Properties\" : { \"ThingName\" : {\"Ref\" : \"AWS::IoT::Certificate::CommonName\"}, \"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::<ACCOUNT_ID>:role/JITPRole" }
要从证书的 ** CommonName** 字段中获取 ThingName 值并提供预定义的策略名称,请使用以下 JITP 模板:
{ "templateBody":"{ \"Parameters\" : { \"AWS::IoT::Certificate::CommonName\" : { \"Type\" : \"String\" },\"AWS::IoT::Certificate::Country\" : { \"Type\" : \"String\" }, \"AWS::IoT::Certificate::Id\" : { \"Type\" : \"String\" }}, \"Resources\" : { \"thing\" : { \"Type\" : \"AWS::IoT::Thing\", \"Properties\" : { \"ThingName\" : {\"Ref\" : \"AWS::IoT::Certificate::CommonName\"}, \"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\" : { \"PolicyName\" : \"Policy_Name\"} } } }", "roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/JITPRole" }
**重要事项:**将 Policy_Name 替换为要使用的策略名称。

