AWS IoT Greengrass Installation
The following guide provides the steps to install AWS IoT Greengrass V2 on an Eurotech IoT Gateway. The process will install AWS IoT Greengrass V2 with automatic resource provisioning. Please refer to the AWS IoT Greengrass V2 Documentation for altenative installation methods.
Prepare the Eurotech Gateway
Create the default system user and group that runs components on your device.
sudo useradd --system --create-home ggc_user
sudo groupadd --system ggc_group
sudo usermod -aG docker idt_ggc_user
sudo visudo
root ALL=(ALL:ALL) ALL
Provide AWS credentials to the device
Provide your AWS credentials to your device so that the installer can provision the required AWS resources. Run the following commands to provide the credentials to the AWS IoT Greengrass Core software.
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Download AWS IoT Greengrass Core software
Download the AWS IoT Greengrass Core Installer and prepare for the installation.
sudo mkdir -p /opt/aws/
cd /opt/aws/
sudo curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip --output greengrass-nucleus-latest.zip
sudo unzip greengrass-nucleus-latest.zip -d GreengrassInstaller
sudo rm greengrass-nucleus-latest.zip
sudo java -jar ./GreengrassInstaller/lib/Greengrass.jar --version
Install AWS IoT Greengrass Core software
Run the AWS IoT Greengrass Core installer. Replace argument values in your command as follows. - region. The AWS Region in which to find or create resources (e.g. us-east-1) - EurotechIoTGatewayGreengrassCore. The name of the AWS IoT thing for your Greengrass core device. If the thing doesn't exist, the installer creates it. - MyGreengrassCoreGroup. The name of AWS IoT thing group for your Greengrass core device. If the thing group doesn't exist, the installer creates it and adds the thing to it. - GreengrassV2IoTThingPolicy. The name of the AWS IoT policy that allows the Greengrass core devices to communicate with AWS IoT and AWS IoT Greengrass. If the AWS IoT policy doesn't exist, the installer creates a permissive AWS IoT policy with this name. - GreengrassV2TokenExchangeRole. The name of the IAM role that allows the Greengrass core device to get temporary AWS credentials. If the role doesn't exist, the installer creates it and creates and attaches a policy named GreengrassV2TokenExchangeRoleAccess. - GreengrassCoreTokenExchangeRoleAlias. The alias to the IAM role that allows the Greengrass core device to get temporary credentials later. If the role alias doesn't exist, the installer creates it and points it to the IAM role that you specify.
The following command sets up the AWS IoT Greengrass Core software as a system service that runs when this device boots. The system service name is greengrass. For more information on the GreengrassInstaller arguments, please refer to the AWS IoT Greengrass Documentation.
cd /opt/aws/
sudo -E java -Droot="/opt/aws/greengrass/v2" -Dlog.store=FILE \
-jar ./GreengrassInstaller/lib/Greengrass.jar \
--aws-region region \
--thing-name EurotechIoTGatewayGreengrassCore \
--thing-group-name MyGreengrassCoreGroup \
--thing-policy-name GreengrassV2IoTThingPolicy \
--tes-role-name GreengrassV2TokenExchangeRole \
--tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
--component-default-user ggc_user:ggc_group \
--deploy-dev-tools \
--provision true \
--setup-system-service true
Configure AWS IoT Greengrass nucleus
Run the following command to check the status of the Greengrass system service. sudo systemctl status greengrass.service
To enable the nucleus to start when the device boots. sudo systemctl enable greengrass.service
To stop the nucleus from starting when the device boots. sudo systemctl disable greengrass.service
To start the AWS IoT Greengrass Core software. sudo systemctl start greengrass.service
To stop the AWS IoT Greengrass Core software. sudo systemctl stop greengrass.service
To view the log messages of the AWS IoT Greengrass Core software. sudo journalctl -u greengrass.service -f
If AWS IoT Greengrass Core service should not find the java executable in the path, please add a link to java under /usr/bin. For example, add a symbolic link like the following: sudo ln -s /usr/java/bin/java /usr/bin/java
Eurotech recommends to use the following configuration of JVM options for teh AWS IoT Greengrass nucleus configuration:
./bin/greengrass-cli component details --name aws.greengrass.Nucleus
nano aws_greengrass_Nucleus.json
{
"aws.greengrass.Nucleus": {
"MERGE": {
"jvmOptions": "-Xmx64m -XX:+UseSerialGC -XX:TieredStopAtLevel=1"
}
}
}
sudo mkdir artifacts
sudo mkdir recipes
sudo ./bin/greengrass-cli deployment create \
--recipeDir recipes \
--artifactDir artifacts \
--merge "aws.greengrass.Nucleus=2.5.3" \
--update-config aws_greengrass_Nucleus.json
./bin/greengrass-cli deployment status -i 80b76202-1982-4de2-a4e9-2b142ede8154
./bin/greengrass-cli component details --name aws.greengrass.Nucleus
For other AWS IoT Greengrass configuration options please refer to the AWS IoT Greengrass documentation.
AWS IoT Greengrass Installation with Hardware Security Integration
Create the AWS IoT Thing
Get the AWS IoT data endpoint for your AWS account.
aws iot describe-endpoint --endpoint-type iot:Data-ATS
{
"endpointAddress": "a1rm1gogglx99n-ats.iot.us-east-1.amazonaws.com"
}
Get the AWS IoT credentials endpoint for your AWS account.
aws iot describe-endpoint --endpoint-type iot:CredentialProvider
{
"endpointAddress": "c3s9r3bwgw6exe.credentials.iot.us-east-1.amazonaws.com"
}
Create an AWS IoT thing
aws iot create-thing --thing-name REGATE-10-14-GreengrassCoreHSM
{
"thingName": "REGATE-10-14-GreengrassCoreHSM",
"thingArn": "arn:aws:iot:us-east-1:332696098873:thing/REGATE-10-14-GreengrassCoreHSM",
"thingId": "dc732ab7-6b3f-44d9-8575-21d9fc1732d0"
}
Add the AWS IoT thing to a thing group.
aws iot add-thing-to-thing-group --thing-name REGATE-10-14-GreengrassCoreHSM --thing-group-name EurotechGreengrassCoreGroup
Create the certificate from a private key in an HSM
On the device, create the certificate from a private key in an HSM. Eurotech gateways use a TPM 2.0 hardware security module. The AWS IoT Greengrass certificate will be loaded in the TPM Owner Hierarchy.
Initialize TPM 2.0 Storage Root Key
If the TPM has not been initialized, create a Storage Root Key (SRK) and persist it with the following command.
sudo mkdir -p /opt/aws/tpm2/
sudo chmod 777 /opt/aws/tpm2/
cd /opt/aws/tpm2/
tpm2_createprimary -C o -G rsa -g sha256 \
-a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt" \
-c srk.ctx
tpm2_evictcontrol -C o -c srk.ctx 0x81000001
Create a private key for the AWS IoT Thing
Create a private key for the AWS IoT Thing under the Storage Root Key. We will call that key Local Device ID (LDevID) and we will make it persistent at 0x81000002.
tpm2_create -C 0x81000001 \
-a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|sign|decrypt|noda" \
-G rsa2048:null:null -g sha256 \
-u ldevid.pub -r ldevid.priv
tpm2_load -C 0x81000001 -u ldevid.pub -r ldevid.priv -c ldevid.ctx
tpm2_evictcontrol -C o -c ldevid.ctx 0x81000002
Create a CSR and a Certificate for the AWS IoT Thing
Create a certificate signing request (CSR) from the private key. AWS IoT uses this CSR to create a thing certificate for the private key that you generated in the HSM.
openssl req -new -engine tpm2tss -keyform engine -key 0x81000002 \
-config openssl-devids.conf -reqexts ldevid \
-out ldevid.csr
Copy the CSR from the device to your development computer.
On the host, use the CSR file to create and download the certificate for the AWS IoT thing to your development computer.
mkdir greengrass-v2-certs
aws iot create-certificate-from-csr --set-as-active --certificate-signing-request=file://ldevid.csr --certificate-pem-outfile greengrass-v2-certs/ldevid.pem.crt
{
"certificateArn": "arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d",
"certificateId": "162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d",
"certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIVAJHaEri69bhONajM7gb3g8Kenm6qMA0GCSqGSIb3DQEB\nCwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\nIEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0yMjAyMTUyMTEx\nNTJaFw00OTEyMzEyMzU5NTlaMEAxETAPBgNVBAoMCEV1cm90ZWNoMRgwFgYDVQQD\nDA9SRUdBVEUtMTAtMTQtMzYxETAPBgNVBAUTCDAxMDIwMzA0MIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1iJp5z0d7eiwFZf+J/epxX6xeDr7iZ9eUwS\n65fwBRGaTLNMjD6NdV1zH/8ClWrYN/gnKosjzji6AHb2cyDj9b8tnQCEakJfLSh6\nwpID0wdJyM7RHqqQw4ZNKn2JDXqam2XGZCZBt3UDeOKxTm5mS2A4LgmkNpoEdqof\nNJJmNYsckowN8j/SIKD9b5FouI4//qF1zUmmzeidqS2HFno0FZnrdIcUZdJfTLYf\n6zn1g3hCFkpa1xE2k3vidrP36HStbjzcj9PNaFzbTdwpUx+7gzsxl2kC8AoZygoO\n0g1kN6GrCYPSHTASAWbQXQJzJw/RSnjlIj3QvnB2ce10XH6+DQIDAQABo2AwXjAf\nBgNVHSMEGDAWgBTSuW1XP6mpLBsdpakikv5OXfq7XzAdBgNVHQ4EFgQUZsEqsvf9\nfiov7or3EnzTYvoHOnEwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwDQYJ\nKoZIhvcNAQELBQADggEBAAOGtPIu3C1UIwUYenfWyGJkPXlAIWc/C2enbQ17LH9J\nvvMptXumiPUsuk4gSbfgI639YkD70nkvUO2uFvwtFC4We//jmx2E+Oe4xJQ457Yo\nrn/Yftt5RTcyFq9ggsXhylps4ae0WbR7bYOg+JBOeaoi9R0hhf4k3qB44kMz1Hc1\nE+JcFbwPqh+80oz7cd6V5oaKz1rT5Lle7R8FTUMuC1wXMHMb5n4QjFgSvnzKdko3\nAvfdOTB2dicIJ2qKeMsu0COchZFVNSzxGA2KKuyKtarg/S+A4xn3dc6bHQ9LlHXQ\niUAt+TLCcO72BcErkYYEST8sje3CLur2a++n4uoWLCo=\n-----END CERTIFICATE-----\n"
}
Copy the certificate to the device.
Attach the certificate to the AWS IoT thing.
aws iot attach-thing-principal --thing-name REGATE-10-14-GreengrassCoreHSM --principal arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d
Create and attach an AWS IoT policy that defines the AWS IoT permissions for your Greengrass core device.
nano greengrass-v2-iot-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Receive",
"iot:Connect",
"greengrass:*"
],
"Resource": [
"*"
]
}
]
}
aws iot create-policy --policy-name EthGreengrassV2IoTThingPolicy --policy-document file://greengrass-v2-iot-policy.json
{
"policyName": "EthGreengrassV2IoTThingPolicy",
"policyArn": "arn:aws:iot:us-east-1:332696098873:policy/EthGreengrassV2IoTThingPolicy",
"policyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"iot:Publish\",\n \"iot:Subscribe\",\n \"iot:Receive\",\n \"iot:Connect\",\n \"greengrass:*\"\n ],\n \"Resource\": [\n \"*\"\n ]\n }\n ]\n}\n",
"policyVersionId": "1"
}
Attach the AWS IoT policy to the AWS IoT thing's certificate.
aws iot attach-policy --policy-name EthGreengrassV2IoTThingPolicy --target arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d
Create a token exchange IAM role
nano device-role-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "credentials.iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
aws iam create-role --role-name EthGreengrassV2TokenExchangeRole --assume-role-policy-document file://device-role-trust-policy.json
{
"Role": {
"Path": "/",
"RoleName": "EthGreengrassV2TokenExchangeRole",
"RoleId": "AROAU25R3TA4QZW5HN3HB",
"Arn": "arn:aws:iam::332696098873:role/EthGreengrassV2TokenExchangeRole",
"CreateDate": "2022-02-15T21:44:59+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "credentials.iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
Create a file that contains the access policy document that the token exchange role requires.
nano device-role-access-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:DescribeCertificate",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
"s3:GetBucketLocation"
],
"Resource": "*"
}
]
}
aws iam create-policy --policy-name EthGreengrassV2TokenExchangeRoleAccess --policy-document file://device-role-access-policy.json
{
"Policy": {
"PolicyName": "EthGreengrassV2TokenExchangeRoleAccess",
"PolicyId": "ANPAU25R3TA4UJAMA4QXI",
"Arn": "arn:aws:iam::332696098873:policy/EthGreengrassV2TokenExchangeRoleAccess",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2022-02-15T21:46:42+00:00",
"UpdateDate": "2022-02-15T21:46:42+00:00"
}
}
Attach the IAM policy to the token exchange role.
aws iam attach-role-policy --role-name EthGreengrassV2TokenExchangeRole --policy-arn arn:aws:iam::332696098873:policy/EthGreengrassV2TokenExchangeRoleAccess
Create an AWS IoT role alias that points to the token exchange role.
aws iot create-role-alias --role-alias EthGreengrassCoreTokenExchangeRoleAlias --role-arn arn:aws:iam::332696098873:role/EthGreengrassV2TokenExchangeRole
{
"roleAlias": "EthGreengrassCoreTokenExchangeRoleAlias",
"roleAliasArn": "arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias"
}
Create and attach an AWS IoT policy that allows your Greengrass core device to use the role alias to assume the token exchange role.
nano greengrass-v2-iot-role-alias-policy.json
{
"Version":"2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:AssumeRoleWithCertificate",
"Resource": "arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias"
}
]
}
aws iot create-policy --policy-name EthGreengrassCoreTokenExchangeRoleAliasPolicy --policy-document file://greengrass-v2-iot-role-alias-policy.json
{
"policyName": "EthGreengrassCoreTokenExchangeRoleAliasPolicy",
"policyArn": "arn:aws:iot:us-east-1:332696098873:policy/EthGreengrassCoreTokenExchangeRoleAliasPolicy",
"policyDocument": "{\n \"Version\":\"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"iot:AssumeRoleWithCertificate\",\n \"Resource\": \"arn:aws:iot:us-east-1:332696098873:rolealias/EthGreengrassCoreTokenExchangeRoleAlias\"\n }\n ]\n}\n",
"policyVersionId": "1"
}
Attach the AWS IoT policy to the AWS IoT thing's certificate.
aws iot attach-policy --policy-name EthGreengrassCoreTokenExchangeRoleAliasPolicy --target arn:aws:iot:us-east-1:332696098873:cert/162a88d1009eb6b0f257ed8e0163d5cb3ad4b570eeb0a8e45f160ac8894ed03d
Import the AWS IoT Thing Certificate into the HSM
If not already done, initialize a PKCS11 store in the TPM 2. A store creates a primary object under the owner hierarchy and each primary object is mapped to a slot. Make sure to define the /etc/tpm2_pkcs11/
directory to store the PKCS11 supporting information for the tpm2_tools, tpm2_ptool, and the libpcks11 library.
After creating a slot, now one needs to create a token. This is accomplished with the addtoken command for tpm2-ptool, using the primary object ID from previous step. A token is created and a unique name called a label is provided. The label is used in subsequent commands to reference the token.
Now link private key for the AWS IoT Thing to PKCS#11 'aws' token with ldevid key-label. Then, install the AWS IoT Thing device certificate in the same slot with the same key-label.
cd /opt/aws/tpm2/
tpm2_ptool link --label='aws' --userpin='1234' --key-label="ldevid" ldevid.pub ldevid.priv
tpm2_ptool addcert --label='aws' --key-label='ldevid' ldevid.pem.crt
tpm2_ptool listobjects --label 'aws'
Install the AWS IoT Greengrass Core software
Install the AWS IoT Greengrass Core software.
Download the Amazon root certificate authority (CA) certificate. AWS IoT certificates are associated with Amazon's root CA certificate by default.
sudo mkdir -p /opt/aws/greengrass/v2
sudo chmod 755 /opt/aws/greengrass
sudo curl -o /opt/aws/greengrass/v2/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
Download the AWS IoT Greengrass Core software.
curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip
unzip greengrass-nucleus-latest.zip -d GreengrassInstaller && rm greengrass-nucleus-latest.zip
java -jar ./GreengrassInstaller/lib/Greengrass.jar --version
Download the PKCS#11 provider plugin to a file named aws.greengrass.crypto.Pkcs11Provider.jar.
curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/Pkcs11Provider/aws.greengrass.crypto.Pkcs11Provider-latest.jar > GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar
Create a configuration file named config.yaml to provide to the installer.
nano GreengrassInstaller/config.yaml
---
system:
certificateFilePath: "pkcs11:object=ldevid;type=cert"
privateKeyPath: "pkcs11:object=ldevid;type=private"
rootCaPath: "/opt/aws/greengrass/v2/AmazonRootCA1.pem"
rootpath: "/opt/aws/greengrass/v2"
thingName: "REGATE-10-14-GreengrassCoreHSM"
services:
aws.greengrass.Nucleus:
componentType: "NUCLEUS"
version: "2.5.3"
configuration:
awsRegion: "us-east-1"
iotRoleAlias: "EthGreengrassCoreTokenExchangeRoleAlias"
iotDataEndpoint: "a1rm1gogglx99n-ats.iot.us-east-1.amazonaws.com"
iotCredEndpoint: "c3s9r3bwgw6exe.credentials.iot.us-east-1.amazonaws.com"
aws.greengrass.crypto.Pkcs11Provider:
configuration:
name: "tpm2_pkcs11"
library: "/usr/lib/pkcs11/libtpm2_pkcs11.so.0.0.0"
slot: 2
userPin: 1234
Run the installer.
sudo -E java -Droot="/opt/aws/greengrass/v2" -Dlog.store=FILE \
-jar ./GreengrassInstaller/lib/Greengrass.jar \
--trusted-plugin ./GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar \
--init-config ./GreengrassInstaller/config.yaml \
--component-default-user ggc_user:ggc_group \
--setup-system-service true
If needed, the Greengrass configuration can be updated as follows.
sudo systemctl stop greengrass.service
sudo nano /opt/aws/greengrass/v2/config/effectiveConfig.yaml
sudo java -Droot="/opt/aws/greengrass/v2" \
-jar /opt/aws/greengrass/v2/alts/current/distro/lib/Greengrass.jar \
--start false \
--init-config /opt/aws/greengrass/v2/config/effectiveConfig.yaml
sudo systemctl start greengrass.service
sudo journalctl -u greengrass.service -f
sudo tail -100f /opt/aws/greengrass/v2/