This post was originally written on DevOpStar. Check it out here
If you've ever been through the process of setting up a new device with AWS IoT Core then you'll probably recall a sense of unease when creating new certificates for your devices. I'm an advocate of allowing people to create and manage their own devices, however a set of guardrails are needed to ensure that a level of consistency is adhered to. Because of this AWS Certificate Vending is a core part of all my projects.
In this post I'll be describing a pattern called Certificate Vending that can help create and manage a number of devices within an account in a secure & repeatable way.
AWS IoT Introduction
Creating a new AWS IoT device usually looks like this:
- Thing - The representation of the new device you plan to connect to AWS IoT
-
Certificate - A private and public x509 key for authenticating your device.
- Attached to the Thing
-
Policy - Permission scope of the certificate.
- Policy can contain one or more Certificates.
While setting up these settings in the UI is simple, it does leave room for human error. Because of this we'll be learning how to manage all this using Certificate Vending.
Certificate Vending Machine
The Certificate Vending Machine (CVM) was was originally an AWS Labs project. Overtime it hasn't been getting the love and care it deserves; with pull requests left open for months.
Note: A good portion of this code is based on the work done by brightsparc in his fork of aws-iot-certificate-vending-machine.
Prerequisites
Before deploying you'll need to pull down the repository for the project
t04glovern / serverless-cvm
Based on awslabs/aws-iot-certificate-vending-machine; this deployment uses Serverless framework instead
Serverless Certificate Vending Machine
Based on awslabs/aws-iot-certificate-vending-machine this deployment uses Serverless framework instead
Serverless Certificate Vending Machine is a pattern for managing AWS IoT Devices in a secure and repeatable way. Learn how to deploy your own CVM and onboard new devices.
Setup Serverless
npm install -g serverless
serverless config credentials --provider aws --key <ACCESS KEY ID> --secret <SECRET KEY>
Requirements
serverless plugin install -n serverless-pseudo-parameters
Add the following to the serveress.yml
file
plugins:
- serverless-pseudo-parameters
Env File
Create a copy of env.yml.sample
as env.yml
and update the IOT_DATA_ENDPOINT
variable with the endpoint address from the following commnad
aws iot describe-endpoint --endpoint-type iot:Data-ATS
# {
# "endpointAddress": "XXXXXX-ats.iot.us-east-1.amazonaws.com"
# }
Deploy
npm install
serverless deploy
# api keys:
# None
# endpoints:
# GET - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert
# ANY - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/shadow
# functions:
# cvm: serverless-cvm-dev-cvm
# layers:
# None
Create Device
Replace the device token…
git clone https://github.com/t04glovern/serverless-cvm
Also ensure you have the following:
- AWS CLI Setup & Authenticated
- NodeJS Installed & Updated
Serverless Setup
Serverless Certificate Vending Machine (CVM) deploys using the Serverless framework. This can be setup on your local system using the following commands:
npm install -g serverless
serverless config credentials --provider aws --key {ACCESS KEY ID} --secret {SECRET KEY}
There are a couple environment variables that are used for Certificate Vending that have to be set in a configuration file called env.yml
. Make a copy of env.yml.sample
as a base and then update the IOT_DATA_ENDPOINT
with your Amazon Trust Services endpoint.
You can obtain your endpoint by running the following command:
aws iot describe-endpoint --endpoint-type iot:Data-ATS
# {
# "endpointAddress": "XXXXXX-ats.iot.us-east-1.amazonaws.com"
# }
An example of the env.yml
can be seen below:
dev:
IOT_DATA_ENDPOINT: XXXXXX-ats.iot.us-east-1.amazonaws.com
CVM Deploy
Deploying Serverless Certificate Vending Machine is as easy as running the following:
npm install
serverless deploy
# api keys:
# None
# endpoints:
# GET - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert
# ANY - https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/shadow
# functions:
# cvm: serverless-cvm-dev-cvm
# layers:
# None
The output shows the endpoints used to generate certificates and update device shadows.
CVM Create Device
To create a new device we need to add a record to the DynamoDB table that manages device certificates.
- serialNumber - Unique ID for the device being added
- deviceToken - Secret token that will be provided later to make changes and generate certificates
Create a new device to test with by running the following command:
aws dynamodb put-item \
--table-name iot-cvm-device-info \
--item '{"deviceToken":{"S":"1234567890"},"serialNumber":{"S":"devopstar-iot-01"}}'
CVM Retrieve Certificate
To retrieve the certificate details, navigate to the endpoint that follows (replace with your endpoint ID):
https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890
Alternatively the following script can be used that makes use of jq to parse the response and save them to files for you
#!/bin/bash
# https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890
ENDPOINT_URL="$1"
# Retrieve Certs
certificates=$(curl $ENDPOINT_URL)
certificatePemCrt=$(echo $certificates | jq '.certificatePem')
certificatePemKey=$(echo $certificates | jq '.keyPair.PrivateKey')
certificateRootCa=$(echo $certificates | jq '.RootCA')
# Save to files
echo -n $certificatePemCrt | sed 's/\\n/\n/g' | sed 's/"//g' > certs/iot-certificate.pem.crt
echo -n $certificatePemKey | sed 's/\\n/\n/g' | sed 's/"//g' > certs/iot-private.pem.key
echo -n $certificateRootCa | sed 's/\\n/\n/g' | sed 's/"//g' > certs/iot-root-ca.crt
It can be executed with the following script and parameter:
./create_certs.sh "https://XXXXXX.execute-api.us-east-1.amazonaws.com/dev/getcert?serialNumber=devopstar-iot-01&deviceToken=1234567890"
This will create the certs below in the certs
folder
- iot-certificate.pem.crt: certificatePem
- iot-private.pem.key: keyPair.PrivateKey
- iot-root-ca.crt: RootCA
These three files are all you'll need in order to connect your device to AWS IoT.
Learn More
If you're interesting in learning more or continuing on your IoT Adventure, be sure to check out some of the following tutorials that leverage this:
- Amazon Alexa controlled IoT Traffic Lights
- AWS Sumerian Magic Cube
- Create a Private VPN using AWS IoT Button, SNS & CloudFormation
I encourage you to check out the course I produced on AWS IoT: The Hobbyists Guide to Home Automation
Top comments (0)