Background introduction
In order to ensure the security of communication, the certificate based TLS 1.2 two-way authentication system is used for MQTT communication between Amazon IoT equipment and Amazon IoT Core. The so-called two-way authentication means that Amazon IoT device end needs to install Amazon IoT device certificate, and the CA certificate used to issue the certificate needs to be granted credit by Amazon IoT Core, so as to complete Amazon IoT device end authentication by Amazon IoT Core. In addition, Amazon IoT devices will also verify the identity of Amazon IoT Core.
In order to ensure the two-way secure connection between Amazon IoT devices and Amazon IoT Core, two types of certificates need to be installed on the Amazon IoT device side:
- Amazon IoT device certificate
- CA certificate for Amazon IoT platform
- Amazon IoT
https://aws.amazon.com/cn/iot/
When to use instant enrollment for device certificates
When users want to use the CA certificate purchased or self issued from a third party organization and connect the device with the device certificate issued by the CA certificate to Amazon IoT Core, they can use the instant registration function. If you want to directly use the device certificate issued by Amazon IoT CA certificate to register and activate the device, you can refer to the Amazon Certificate Vending Machine scheme.
- Amazon Certificate Vending Machine
https://aws.amazon.com/cn/blo...
The implementation steps are as follows:
- Create a CA certificate and register and activate it on Amazon IoT Core.
- Use this CA certificate to issue a device certificate and install it on Amazon IoT devices.
- Create Amazon Lambda function to realize automatic registration of device certificate on Amazon IoT Core.
- The first connection between Amazon IoT devices and Amazon IoT Core.
preparation
The Amazon IoT device in this article will use an Amazon Linux EC2 instance to simulate and use the MQTT Mosquitto Client tool to simulate the MQTT message interaction process. Amazon IoT devices in practical applications need to integrate Amazon IoT SDK to realize interaction with Amazon IoT Core. In addition, all the next operations take Amazon cloud Technology Beijing as an example.
Amazon AWSCLI, the command-line tool of Amazon cloud technology, is installed on Amazon Linux EC2 instance by default. If readers use other instances or their own computers, please refer to this link to install Amazon AWSCLI.
- Amazon Linux EC2
https://aws.amazon.com/cn/ec2/ - This link:
https://docs.aws.amazon.com/z...
Step 1: create a CA certificate and register and activate it on Amazon IoT Core
In a real scenario, a user's device certificate is often issued by an intermediate CA certificate rather than a root CA certificate. For convenience, this step will skip the intermediate CA certificate and directly issue the device certificate with the root certificate. And because the actual purchase of CA certificate will make the author pay N months' salary, here we will use OpenSSL to issue the certificate. Users can choose different issuance methods according to their actual situation.
Log in to Amazon EC2 instance and execute the following command to create private key and corresponding CA certificate:
$ 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
Slide left and right to see more
We need to register this CA certificate with Amazon IOT Core. For security, Amazon IOT Core provides a corresponding audit process to ensure that you hold both the CA certificate and the corresponding private key. Therefore, before finally registering the CA certificate, We also need to generate an intermediate certificate for verifying the identity of the CA certificate and the private key holder according to the process (please note that this certificate is not the CA certificate created above). The following Amazon AWSCLI command will return a randomly generated authentication code, which will be bound to your account. Record this authentication code and we will use it soon.
$ aws iot get-registration-code
Use OpenSSL again to generate the private key and certificate request file for authentication (Amazon CSR – Amazon Certificate Signing Request).
$ openssl genrsa -out Verification_Private.key 2048 $ openssl req -new -key Verification_Private.key -out Verification.csr
Slide left and right to see more
In the process of creating Amazon CSR, you will be prompted to enter the following contents and fill the authentication code recorded in the previous step into Common Name:
...Organization Name (eg, company) []:Organizational Unit Name (eg, section)Common Name (e.g. server FQDN or YOUR name) []: XXXXXREGISTRATIONCODEXXXXX...
Next, use the CA certificate and private key, and the Amazon CSR created above to generate an intermediate certificate for authentication.
$ openssl x509 -req -in Verification.csr -CA CA_Certificate.pem -CAkey CA_Private.key -CAcreateserial -out Verification.crt -days 365 -sha256
Slide left and right to see more
Finally, import the CA certificate and intermediate certificate through the following command, and Amazon IoT Core will complete the registration and activation of the CA certificate. At the same time, enable the automatic registration of device certificates when the device is connected to Amazon IoT Core by setting – allow auto registration. The output of this command will return the ID(caCertificateId) of the corresponding CA certificate on Amazon IoT Core.
$ aws iot register-ca-certificate --ca-certificate file://CA_Certificate.pem --verification-certificate file://Verification.crt --set-as-active --allow-auto-registration
Slide left and right to see more
Step 2: use CA certificate to issue equipment certificate
After we have created and registered the CA certificate, we can start issuing the equipment certificate with this CA certificate. The steps are as follows:
Create a private key for the device certificate Key and the corresponding certificate request file Device_Certificate.csr.
$ openssl genrsa -out Device.key 2048 $ openssl req -new -key Device.key -out Device_Certificate.csr
Slide left and right to see more
Use CA certificate, CA certificate private key and certificate request file to issue device certificate 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
Slide left and right to see more
After creating the device certificate and installing it on the device, you may ask, how do I register and use the device certificate? Of course, you can complete the registration on Amazon IoT Core through Amazon AWSCLI command line or even graphical interface, but in the face of thousands of Amazon IoT devices, no one should want to do it manually. Next, we will introduce how to use Amazon Lambda function to automatically complete the registration process of device certificate when the device connects to Amazon IoT Core for the first time.
Step 3: create Amazon Lambda function and Amazon IoT rules to activate and attach the device certificate on Amazon IoT Core
When an Amazon IoT device connects to the Amazon IoT Core for the first time, if its integrated device certificate is issued by a CA certificate registered on the Core, the corresponding device certificate will be automatically registered. The default state after registration is "PENDING_ACTIVATION", which means that although the device certificate has been successfully registered, it is still in the state of waiting to be activated. Meanwhile, this connection action will send a message to MQTT Topic "$aws/events/certificates/registered /" of Amazon IoT Core by default. The message event will be in the following format:
{ "certificateId": "<certificateID>", "caCertificateId": "<caCertificateId>", "timestamp": "<timestamp>", "certificateStatus": "PENDING_ACTIVATION", "awsAccountId": "<awsAccountId>", "certificateRegistrationTimestamp": "<certificateRegistrationTimestamp>" }
Slide left and right to see more
As we all know, the execution of Amazon Lambda function can be triggered by events. Next, we will do two things:
- Create an Amazon Lambda function to receive incoming events, execute code logic to activate the device certificate and attach a Policy to give the device corresponding permissions.
- Create an Amazon IoT rule, subscribe to the MQTT Topic "$aws/events/certificates/registered /", and when a message is sent to this Topic, forward the message to the Amazon Lambda function for processing (activate the certificate and attach the Policy).
First, let's create this Amazon Lambda function:
- Log in to Amazon Console and enter Amazon Lambda page.
- Amazon Lambda
https://console.amazonaws.cn/...
- Click "create function" and select "create from scratch".
- Fill in "name", select "Node.js 6.10" for running language, and select "create custom role" for role.
- In the new pop-up window, select "create new Amazon IAM role" for Amazon IAM role, fill in the role name, click "view policy document" and click "Edit".
- Click "Edit" to pop up a window, prompting that you must read the relevant documents before editing. Here, we directly click the OK button. Of course, if you have time, it is recommended to read the document first.
- Replace the existing Policy with the following Policy. You can see here that we have added the permission to update the certificate and attach Policy to Amazon Lambda function. Click allow to complete the configuration of roles and policies.
{ "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": "*" } ] }
Slide left and right to see more
7. Click Create function to enter the function configuration interface. The current code of the replacement function is:
/** 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) { //It is also written in the certificateARN according to the actual deployment area. 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(); //Here you can replace it with the topic name you want var topicName = `JITR/test`; var certificateARN = `arn:aws-cn:iot:${region}:${accountId}:cert/${certificateId}`; var policyName = `Policy_${certificateId}`; //Define policies and grant permissions to allow IoT devices to connect, publish, subscribe and accept messages var policy = { "Version": "2012-10-17", "Statement": [ { "Action": [ "iot:Publish", "iot:Subscribe", "iot:Connect", "iot:Receive" ], "Effect": "Allow", "Resource": [ "*" ] } ] }; /* Create 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); /* Attach Policy to device certificate */ 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); /* Activate certificate */ 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); } }); }); }); }
Slide left and right to see more
8. Click "save" in the upper right corner of the page to complete the creation of Amazon Lambda function.
After the Amazon Lambda function is created, we continue to create Amazon IoT rules:
- Enter Amazon IoT interface.
- Click "action" on the left side of the page, and then click "create" in the upper right corner.
- Fill in the "name" and "description" of the rule on the create rule page, and fill in an asterisk "*" in the "attribute" column.
- Fill in "$aws/events/certificates/registered /" in the "subject filter criteria" in the create rule page. Note that the ID of the CA certificate previously issued with OpenSSL should be replaced. This ID can be obtained by clicking "security" - > "CA" on the left side of Amazon IoT interface.
- Click "add operation" in setting one or more operations, select "call Amazon Lambda function to transfer message data", and then click "configure operation".
- Function nameselect the name of the Amazon Lambda function you created earlier, and then click Add action.
7. Click "create rule" to complete the configuration of Amazon IoT rules.
So far, the Amazon Lambda function and Amazon IoT rule are created. Next, let's try to connect the device to Amazon IoT Core.
Step 4: the first connection between Amazon IoT device and Amazon IoT Core
In order to simulate a device, you can install the Amazon IoT SDK and call Amazon cloud technology through your own code to realize all functions. Here, in order to simplify the steps and save time, we choose to directly install the MQTT Mosquitto Client tool on Amazon EC2 created earlier.
- MQTT Mosquitto Client:
https://mosquitto.org/
Log in to Amazon EC2 instance and execute the following command:
$ 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 #If the execution of the above command depends on the missing error, you can add -- skip broken and execute it again $ sudo yum install mosquitto mosquitto-clients -y --skip-broken
Slide left and right to see more
Go to the cert directory you created earlier.
$ cd cert
Merge CA certificate and device certificate into a new certificate to form a valid certificate chain.
$ cat Device_Certificate.crt CA_Certificate.pem > Device_CA_Certificate.crt
Slide left and right to see more
Execute mosquitto_ The pub command publishes a message to the corresponding topic, which is also the first connection between the device and Amazon IoT Core. If you recall the previous steps, so far our device certificate only exists on the device and has not been registered on Amazon IoT Core, then the next time to witness a miracle is coming!
$ 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
Slide left and right to see more
- The - cafile in the command is the CA certificate of Amazon IoT Core, which is used by the device to verify the identity of Amazon IoT Core. This file can be obtained through this link
- - cert in the command is the certificate chain after merging CA certificate and device certificate
- - key in the command is the private key of the device
- - h in the command is the access point of Amazon IoT Core, which can be obtained by clicking "Settings" in the lower left corner of Amazon IoT interface
- - t in the command is the topic you want to publish the message to. Here I publish it to JITR/test. You can choose the topic you want to publish
- The - i in the command can be named as you want
After executing this command for the first time, you will see the following error messages. Why?
Client anyclientID sending CONNECT Error: The connection was lost.
In fact, when the device connects to Amazon IoT Core for the first time, the device certificate has not been registered, so TLS authentication will fail. This connection action will publish a registration message to "$aws/events/certificates/registered /". After receiving this message, Amazon Lambda function will complete the registration of device certificate and attach Policy. Then we can execute this command again.
$ 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
Slide left and right to see more
The output is as follows:
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
Slide left and right to see more
It should be noted here that in the actual environment, the user's code logic is responsible for handling this process, that is, after the first connection failure, it is necessary to automatically reconnect one or more times to complete the certificate registration and device activation.
At this time, enter the Amazon IoT interface, click Security on the left, and you can see that our device certificate has been registered and activated in the certificate page.
Reference link
- Just-in-Time Registration of Device Certificates on Amazon IoT:
https://aws.amazon.com/blogs/...
Author of this article
Guo song
Amazon cloud technology solution architect
Responsible for architecture consulting and design optimization of enterprise customers, and committed to the application and promotion of Amazon IoT and storage services in domestic and global enterprise customers. Before joining Amazon cloud technology, he worked as a system engineer in EMC R & D center and had in-depth research on high availability architecture, scheme and performance tuning of enterprise storage applications.