背景介绍
为了保障通信的安全性,Amazon IoT设施与Amazon IoT Core的MQTT通信应用基于证书的TLS 1.2双向认证体系。所谓的双向认证,即意味着Amazon IoT设施端需装置Amazon IoT设施证书,并且,签发该证书所应用的CA证书须要被Amazon IoT Core授信,从而实现Amazon IoT Core对Amazon IoT设施端的认证。并且,Amazon IoT设施也会验证Amazon IoT Core的身份。
为了保障Amazon IoT设施和Amazon IoT Core的双向平安对接,对于Amazon IoT设施端,须要装置两类证书:
- Amazon IoT设施证书
- Amazon IoT平台的CA证书
- Amazon IoT
https://aws.amazon.com/cn/iot/
何时应用设施证书的即时注册
当用户心愿应用从第三方机构购买或者自签发的CA证书,并将由CA证书签发的设施证书的设施连贯到Amazon IoT Core时,能够利用即时注册性能来实现。如果心愿间接利用Amazon IoT CA证书签发的设施证书对设施进行注册激活,能够参考Amazon Certificate Vending Machine计划。
- Amazon Certificate Vending Machine
https://aws.amazon.com/cn/blo…
实现步骤如下:
- 创立CA证书并在Amazon IoT Core上注册和激活。
- 应用该CA证书签发设施证书并装置在Amazon IoT设施上。
- 创立Amazon Lambda函数实现设施证书在Amazon IoT Core上的主动注册。
- Amazon IoT设施与Amazon IoT Core的第一次连贯。
筹备工作
本文中的Amazon IoT设施会应用一台Amazon Linux EC2实例模仿,并应用MQTT Mosquitto Client工具来模仿MQTT音讯交互过程。理论利用中的Amazon IoT设施须要集成Amazon IoT SDK以实现和Amazon IoT Core的交互。此外,接下来的所有操作都是以亚马逊云科技北京区为示例。
Amazon Linux EC2实例上默认装置了亚马逊云科技命令行工具Amazon AWSCLI,如读者应用其余实例或者本人的电脑,请参考此链接来装置Amazon AWSCLI。
- Amazon Linux EC2
https://aws.amazon.com/cn/ec2/ - 此链接:
https://docs.aws.amazon.com/z…
第一步:创立CA证书并在Amazon IoT Core上注册和激活
在实在场景中,用户的设施证书常常是由两头CA证书 (Intermediate CA Certificate) 签发而来,而不是由根CA签发(Root CA Certificates)。为了不便起见,本步骤会跳过两头CA证书,间接用根证书签发设施证书。并且因为理论购买CA证书会让笔者付出N个月的薪水,这里咱们会应用OpenSSL来自签发证书,用户能够依据本人的理论状况抉择不同的签发形式。
登陆Amazon 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证书注册到Amazon IOT Core。为了平安,Amazon IOT Core提供了相应的审核流程确保你同时持有CA证书和对应的私钥。因而,在最终注册CA证书之前,咱们还须要依照流程生成一份用于验证CA证书和私钥持有者身份的两头证书(请留神这份证书并不是下面创立的CA证书)。上面这个Amazon AWSCLI命令会返回一个随机生成的认证码,这个认证码会和你的账户绑定。记录下这个认证码,很快咱们就会用到。
$ aws iot get-registration-code
再次应用OpenSSL生成用于验证身份的私钥和证书申请文件(Amazon CSR – Amazon Certificate Signing Request)。
$ openssl genrsa -out Verification_Private.key 2048
$ openssl req -new -key Verification_Private.key -out Verification.csr
左右滑动查看更多
在创立Amazon CSR的过程中,你会被提醒输出如下一些内容,将前一步记录下的认证码填入到Common Name中:
…Organization Name (eg, company) []:Organizational Unit Name (eg, section)Common Name (e.g. server FQDN or YOUR name) []: XXXXXREGISTRATIONCODEXXXXX…
接下来,应用CA证书和私钥,以及下面创立的Amazon CSR来生成一份用于验证身份的两头证书。
$ openssl x509 -req -in Verification.csr -CA CA_Certificate.pem -CAkey
CA_Private.key -CAcreateserial -out Verification.crt -days 365 -sha256
左右滑动查看更多
最初,通过如下命令导入CA证书和两头证书,Amazon IoT Core会实现CA证书的注册和激活。同时,通过设置–allow-auto-registration的形式开启设施连贯Amazon IoT Core时设施证书的主动注册。这个命令的输入会返回对应CA证书在Amazon IoT Core上的ID(caCertificateId)。
$ aws iot register-ca-certificate --ca-certificate
file://CA_Certificate.pem --verification-certificate
file://Verification.crt --set-as-active --allow-auto-registration
左右滑动查看更多
第二步:应用CA证书签发设施证书
当咱们创立并注册好CA证书之后,就能够开始用这个CA证书来签发设施证书了,步骤如下:
创立一个设施证书的私钥Device.key和对应的证书申请文件Device_Certificate.csr。
$ openssl genrsa -out Device.key 2048
$ openssl req -new -key Device.key -out Device_Certificate.csr
左右滑动查看更多
应用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
左右滑动查看更多
在创立好设施证书并在设施上装置实现后,你可能要问,那我如何注册并应用设施证书呢?你当然能够通过Amazon AWSCLI命令行甚至图形界面在Amazon IoT Core上实现注册,然而面对着千千万万的Amazon IoT设施,应该没有人想这样手动去做。接下来咱们就会介绍利用Amazon Lambda函数,在设施第一次连贯Amazon IoT Core时,主动实现设施证书的注册过程。
第三步:创立Amazon Lambda函数和Amazon IoT规定实现设施证书在Amazon IoT Core上的激活和权限附加
当Amazon IoT设施第一次连贯Amazon IoT Core时,如果它集成的设施证书是由已在Core上注册的CA证书签发而来,那么相应的设施证书会实现主动注册,注册后的默认状态为“PENDING_ACTIVATION”,意味着尽管设施证书曾经胜利注册,然而还处于期待激活的状态。同时,这个连贯动作默认会发一条音讯到Amazon IoT Core的MQTT Topic “$aws/events/certificates/registered/”上,这条音讯事件会是如下的格局:
{
"certificateId": "<certificateID>",
"caCertificateId": "<caCertificateId>",
"timestamp": "<timestamp>",
"certificateStatus": "PENDING_ACTIVATION",
"awsAccountId": "<awsAccountId>",
"certificateRegistrationTimestamp": "<certificateRegistrationTimestamp>"
}
左右滑动查看更多
大家都晓得Amazon Lambda函数的执行能够由事件来触发,那么接下来咱们会做两件事:
- 创立一个Amazon Lambda函数,接管传入的事件,执行代码逻辑去激活设施证书并附加上一条Policy去给予这个设施相应的权限。
- 创立一Amazon IoT规定,订阅MQTT Topic “$aws/events/certificates/registered/”,当有音讯发到这个Topic上时,将音讯转发给Amazon Lambda函数解决(激活证书并附加 Policy)。
首先,咱们来创立这个Amazon Lambda函数:
- 登陆到Amazon Console并进入Amazon Lambda页面。
- Amazon Lambda
https://console.amazonaws.cn/…
- 点击 “创立函数”后抉择“从头开始创作”。
- 填入“名称”,运行语言选择 “Node.js 6.10”,角色抉择“创立自定义角色”。
- 在新弹出的窗口中,Amazon IAM角色抉择“创立新的Amazon IAM角色”,填入角色名称,点击“查看策略文档”,点击“编辑”。
- 点击“编辑”会弹出一个窗口,提醒在编辑之前务必读一下相干文档,这里咱们间接点击确定按钮。当然如果有工夫的话,还是倡议先读一下文档。
- 用如下的策略替换现有策略,能够看到这里咱们为Amazon Lambda函数增加了更新证书和附加Policy的权限,点击“容许”实现角色和策略的配置。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws-cn:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"iot:UpdateCertificate",
"iot:CreatePolicy",
"iot:AttachPrincipalPolicy"
],
"Resource": "*"
}
]
}
左右滑动查看更多
7.点击创立函数进入函数配置界面,替换函数以后的代码为:
/**
This node.js Lambda function code creates and attaches an IoT policy to the
just-in-time registered certificate. It also activates the certificate. The Lambda
function is attached as a rule engine action to the registration topic
$aws/events/certificates/registered/<caCertificateID>
**/
var AWS = require('aws-sdk');
exports.handler = function (event, context, callback) {
// 依据理论部署区域写入,在certificateARN一处也是。
var region = "cn-north-1";
var accountId = event.awsAccountId.toString().trim();
var iot = new AWS.Iot({
'region': region,
apiVersion: '2015-05-28'
});
var certificateId = event.certificateId.toString().trim();
//这里你能够替换成你想要的topic名称
var topicName = `JITR/test`;
var certificateARN = `arn:aws-cn:iot:${region}:${accountId}:cert/${certificateId}`;
var policyName = `Policy_${certificateId}`;
//定义Policy并赋予权限,容许IoT设施连贯,公布,订阅和承受音讯
var policy = {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Connect",
"iot:Receive"
],
"Effect": "Allow",
"Resource": [
"*"
]
}
]
};
/*
创立Policy
*/
iot.createPolicy({
policyDocument: JSON.stringify(policy),
policyName: policyName
}, (err, data) => {
//Ignore if the policy already exists
if (err && (!err.code || err.code !== 'ResourceAlreadyExistsException')) {
console.log(err);
callback(err, data);
return;
}
console.log(data);
/*
附加Policy到设施证书上
*/
iot.attachPrincipalPolicy({
policyName: policyName,
principal: certificateARN
}, (err, data) => {
//Ignore if the policy is already attached
if (err && (!err.code || err.code !== 'ResourceAlreadyExistsException')) {
console.log(err);
callback(err, data);
return;
}
console.log(data);
/*
激活证书
*/
iot.updateCertificate({
certificateId: certificateId,
newStatus: 'ACTIVE'
}, (err, data) => {
if (err) {
console.log(err, err.stack);
callback(err, data);
} else {
console.log(data);
callback(null, "Success, created, attached policy and activated the certificate " + certificateId);
}
});
});
});
}
左右滑动查看更多
8.点击页面右上角的“保留”来实现Amazon Lambda函数的创立。
在Amazon Lambda函数创立实现后,咱们持续创立Amazon IoT规定:
- 进入Amazon IoT界面。
- 点击页面左侧的“口头”,而后点击右上角的“创立”。
- 在创立规定页面中填入规定的“名称”和“形容”,在“属性”一栏填入一个星号“*”。
- 在创立规定页面中的“主题筛选条件”里填入“$aws/events/certificates/registered/”,留神这外面的要替换成之前用OpenSSL签发的CA证书的ID,这个ID能够通过在Amazon IoT界面的左侧点击“平安”->“CA”来取得。
- 在设置一个或多个操作中点击“增加操作”, 抉择“调用Amazon Lambda函数,传递音讯数据”,而后点击“配置操作”。
- 函数名称抉择之前创立的Amazon Lambda函数名称,而后点击“增加操作”。
7. 点击“创立规定”实现Amazon IoT规定的配置。
到此为止,Amazon Lambda函数和Amazon IoT规定创立实现。接下来,咱们来尝试连贯设施到Amazon IoT Core上。
第四步:Amazon IoT设施与Amazon IoT Core的第一次连贯
为了模仿一台设施,你能够装置Amazon IoT SDK,通过本人的代码调用亚马逊云科技来实现所有的性能。这里咱们为了简化步骤和节约工夫,抉择间接在之前创立的Amazon EC2上装置MQTT Mosquitto Client工具。
- MQTT Mosquitto Client:
https://mosquitto.org/
登陆到Amazon 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
# 如果下面的命令执行时报依赖短少的谬误,能够加上--skip-broken再执行一遍即可
$ sudo yum install mosquitto mosquitto-clients -y --skip-broken
左右滑动查看更多
进入到之前创立的cert目录。
$ cd cert
合并CA证书和设施证书到一个新的证书造成无效的证书链。
$ cat Device_Certificate.crt CA_Certificate.pem > Device_CA_Certificate.crt
左右滑动查看更多
执行mosquitto_pub命令去公布一个音讯到对应的topic下面,这也是设施与Amazon IoT Core的第一次连贯。如果你回忆一下之前的步骤,到目前为止咱们的设施证书还只存在于设施下面,并没有在Amazon IoT Core上注册,那么接下来见证奇观的时刻就要到啦!
$ mosquitto_pub --cafile root-CA.crt --cert Device_CA_Certificate.crt --key Device.key -h xxxxxxxxxxxxxx.iot.cn-north-1.amazonaws.com.cn -p 8883 -q 1 -t JITR/test -i anyclientID --tls-version tlsv1.2 -m "Hello" -d
左右滑动查看更多
- 命令中的-cafile是Amazon IoT Core的CA证书,用于设施去验证Amazon IoT Core的身份,这个文件能够通过此链接取得
- 命令中的-cert是合并CA证书和设施证书后的证书链
- 命令中的-key是设施的私钥
- 命令中的-h是Amazon IoT Core的接入点,能够通过在Amazon IoT界面中左下角点击“设置”取得
- 命令中的-t是你要公布音讯到哪一个topic 上,这里我是公布到JITR/test,你能够抉择本人想要公布的topic
- 命令中的-i能够依照你心愿的名字命名
在第一次执行这个命令后,你会看到如下的报错,那么这是为什么呢?
Client anyclientID sending CONNECT
Error: The connection was lost.
实际上设施在第一次连贯Amazon IoT Core的时候,设施证书还没有注册,所以TLS认证会失败。这个连贯动作会公布一条注册音讯到 “$aws/events/certificates/registered/”下面,接下来Amazon Lambda函数接管到这个音讯后,会实现设施证书的注册,附加Policy,那么咱们再次执行这个命令就能够胜利了。
$ mosquitto_pub --cafile root-CA.crt --cert Device_CA_Certificate.crt --key Device.key -h xxxxxxxxxxxxxx.iot.cn-north-1.amazonaws.com.cn -p 8883 -q 1 -t JITR/test -i anyclientID --tls-version tlsv1.2 -m "Hello" -d
左右滑动查看更多
输入如下:
Client anyclientID sending CONNECT
Client anyclientID received CONNACK
Client anyclientID sending PUBLISH (d0, q1, r0, m1, 'JITR/test', ... (5 bytes))
Client anyclientID received PUBACK (Mid: 1)
Client anyclientID sending DISCONNECT
左右滑动查看更多
这里要留神的是,在理论环境中,用户的代码逻辑里要负责解决这一个过程,也就是说在第一次连贯失败后须要主动重连一次或屡次来实现证书的注册与设施的激活。
这时进入Amazon IoT界面,点击左侧的平安后,在证书页面中能够看到咱们的设施证书曾经注册实现并激活了。
参考链接
- Just-in-Time Registration of Device Certificates on Amazon IoT:
https://aws.amazon.com/blogs/…
本篇作者
郭松
亚马逊云科技解决方案架构师
负责企业级客户的架构征询及设计优化,同时致力于Amazon IoT和存储服务在国内和寰球企业客户的利用和推广。退出亚马逊云科技之前在EMC研发核心负责零碎工程师,对企业级存储利用的高可用架构,计划及性能调优有深入研究。
发表回复