Skip to content

Commit b534183

Browse files
authored
Greengrass local auth demo (#1831)
This PR adds a demo for connecting a device to a Greengrass core using the new feature that allows using custom CAs. For more info on the feature, see: https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-release-2022-11-15.html
1 parent 032f799 commit b534183

File tree

13 files changed

+2416
-4
lines changed

13 files changed

+2416
-4
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ jobs:
3939
-DCLAIM_PRIVATE_KEY_PATH="key/path" \
4040
-DPROVISIONING_TEMPLATE_NAME="template-name" \
4141
-DDEVICE_SERIAL_NUMBER="00000" \
42-
-DCSR_SUBJECT_NAME="CN=Fleet Provisioning Demo"
42+
-DCSR_SUBJECT_NAME="CN=Fleet Provisioning Demo" \
43+
-DGREENGRASS_ADDRESS="greengrass-address"
4344
- name: Build Demos
4445
run: |
4546
make -C build/ help | grep demo | tr -d '. ' | xargs make -C build/
@@ -84,7 +85,8 @@ jobs:
8485
-DCLAIM_PRIVATE_KEY_PATH="key/path" \
8586
-DPROVISIONING_TEMPLATE_NAME="template-name" \
8687
-DDEVICE_SERIAL_NUMBER="00000" \
87-
-DCSR_SUBJECT_NAME="CN=Fleet Provisioning Demo"
88+
-DCSR_SUBJECT_NAME="CN=Fleet Provisioning Demo" \
89+
-DGREENGRASS_ADDRESS="greengrass-address"
8890
- name: Build Demos
8991
run: |
9092
make -C build/ help | grep demo | tr -d '. ' | xargs make -C build/

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
* [Configuring the AWS IoT Fleet Provisioning demo](#configuring-the-aws-iot-fleet-provisioning-demo)
5151
* [Configuring the S3 demos](#configuring-the-s3-demos)
5252
* [Setup for AWS IoT Jobs demo](#setup-for-aws-iot-jobs-demo)
53+
* [Setup for the Greengrass local auth demo](#setup-for-the-greengrass-local-auth-demo)
5354
* [Prerequisites for the AWS Over-The-Air Update (OTA) demos](#prerequisites-for-the-aws-over-the-air-update-ota-demos)
5455
* [Scheduling an OTA Update Job](#scheduling-an-ota-update-job)
5556
* [Building and Running Demos](#building-and-running-demos)
@@ -491,6 +492,9 @@ The following creates a job that specifies a Linux Kernel link for downloading.
491492
--document '{"url":"https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.5.tar.xz"}'
492493
```
493494

495+
#### Setup for the Greengrass local auth demo
496+
497+
For setting up the Greengrass local auth demo, see [the README in the demo folder](./demos/greengrass/greengrass_demo_local_auth/README.md).
494498

495499
#### Prerequisites for the AWS Over-The-Air Update (OTA) demos
496500

demos/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ if(NOT ${OpenSSL_FOUND})
4848
"ota_demo_core_http"
4949
"ota_demo_core_mqtt"
5050
"shadow_demo_main"
51+
"greengrass_demo_local_auth"
5152
)
5253
message( WARNING "OpenSSL library could not be found. Demos that use it will be excluded from the default target." )
5354
foreach(demo_name ${openssl_demos})
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
set( DEMO_NAME "greengrass_demo_local_auth" )
2+
3+
# Include MQTT library's source and header path variables.
4+
include( ${CMAKE_SOURCE_DIR}/libraries/standard/coreMQTT/mqttFilePaths.cmake )
5+
6+
# Include backoffAlgorithm library file path configuration.
7+
include( ${CMAKE_SOURCE_DIR}/libraries/standard/backoffAlgorithm/backoffAlgorithmFilePaths.cmake )
8+
9+
# CPP files are searched for supporting CI build checks that verify C++ linkage of the coreMQTT library
10+
file( GLOB DEMO_FILE "${DEMO_NAME}.c*" )
11+
12+
# Demo target.
13+
add_executable(
14+
${DEMO_NAME}
15+
"${DEMO_FILE}"
16+
"openssl_posix.c"
17+
${MQTT_SOURCES}
18+
${MQTT_SERIALIZER_SOURCES}
19+
${BACKOFF_ALGORITHM_SOURCES}
20+
)
21+
22+
find_package(OpenSSL)
23+
24+
target_link_libraries(
25+
${DEMO_NAME}
26+
PUBLIC
27+
clock_posix
28+
sockets_posix
29+
${OPENSSL_LIBRARIES}
30+
)
31+
32+
target_include_directories(
33+
${DEMO_NAME}
34+
PUBLIC
35+
${MQTT_INCLUDE_PUBLIC_DIRS}
36+
${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS}
37+
${CMAKE_CURRENT_LIST_DIR}
38+
${LOGGING_INCLUDE_DIRS}
39+
)
40+
41+
set_macro_definitions(TARGETS ${DEMO_NAME}
42+
REQUIRED
43+
"GREENGRASS_ADDRESS"
44+
"ROOT_CA_CERT_PATH"
45+
"THING_NAME"
46+
"CLIENT_CERT_PATH"
47+
"CLIENT_PRIVATE_KEY_PATH")
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Greengrass local auth demo
2+
3+
This demo shows connecting a device using coreMQTT to a Greengrass core using
4+
local authentication. This feature is available since version [v2.9.0](https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-release-2022-11-15.html)
5+
6+
Connecting to a Greengrass core is similar to connecting to IoT core. The
7+
device's Thing will need to be registered on IoT core just as with connecting
8+
directly. When setting up the Greengrass core, use your own Root CA, and
9+
provision the connecting device with the Root CA used for the Greengrass core.
10+
11+
To read more about using Greengrass with custom CAs, see the docs on
12+
[offline authentication](https://docs.aws.amazon.com/greengrass/v2/developerguide/offline-authentication.html).
13+
14+
This demo uses macros in demo_config.h for provisioned data; the following need
15+
to be set:
16+
17+
- `GREENGRASS_ADDRESS`
18+
- Set this to the IP of the Greengrass core.
19+
- `ROOT_CA_CERT_PATH`
20+
- Set this to the path to the CA certificate for the Greengrass core custom
21+
CA.
22+
- `CLIENT_CERT_PATH`
23+
- Set this to the client cert downloaded from IoT core when setting up the
24+
Thing.
25+
- `CLIENT_PRIVATE_KEY_PATH`
26+
- Set this to the client private key downloaded from IoT core when setting up
27+
the Thing.
28+
- `THING_NAME`
29+
- Set this to the Thing name configured in IoT core.
30+
31+
These macros can also be set on the cmake command like follows:
32+
33+
```sh
34+
cmake -S . -Bbuild -DGREENGRASS_ADDRESS="<your-gg-core-ip>" -DROOT_CA_CERT_PATH="<your-path-to-custom-root-ca>" -DCLIENT_CERT_PATH="<your-client-certificate-path>" -DCLIENT_PRIVATE_KEY_PATH="<your-client-private-key-path>" -DTHING_NAME="<your-registered-thing-name>"
35+
```
36+
37+
## Setting up the prerequisites
38+
39+
### Creating the Thing
40+
41+
See the [Getting Started section of the README](../../../README.md#getting-started)
42+
for setting up this repo and your AWS IoT account. Use the Thing credentials
43+
generated for the above macros.
44+
45+
### Setting up a Greengrass Core
46+
47+
For setting up the Greengrass core, see [the Greengrass getting started guide](https://docs.aws.amazon.com/greengrass/v2/developerguide/getting-started.html)
48+
49+
### Creating a custom CA
50+
51+
Next you will need to set up a Root CA for your Greengrass device.
52+
53+
On the Greengrass core, run the following command:
54+
55+
```sh
56+
openssl req -x509 -new -nodes -key ca.key -sha256 -days 1826 -out ca.crt
57+
```
58+
59+
This will create a custom CA cert ca.crt and private key ca.key.
60+
61+
### Configuring the GG core for local auth and MQTT
62+
63+
Deploy the following components to your Greengrass core:
64+
- aws.greengrass.clientdevices.Auth
65+
- aws.greengrass.clientdevices.mqtt.Moquette
66+
- aws.greengrass.clientdevices.mqtt.Bridge
67+
- aws.greengrass.clientdevices.IPDetector
68+
69+
Set the configuration for the aws.greengrass.clientdevices.Auth component based
70+
off the [provided config](./greengrass_auth_conf.json). Ensure the certificate
71+
paths match the files created for your custom CA above.
72+
73+
This config will allow associated Things to publish and subscribe to any topic
74+
on the Greengrass core broker.
75+
76+
In the page for the Greengrass core in your AWS account, ensure that you
77+
associate your Thing with the Greengrass core under the Cloud Discovery tab.
78+
79+
Afterwards, you can configure and run this demo.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* AWS IoT Device SDK for Embedded C 202108.00
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
* this software and associated documentation files (the "Software"), to deal in
7+
* the Software without restriction, including without limitation the rights to
8+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
* the Software, and to permit persons to whom the Software is furnished to do so,
10+
* subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in all
13+
* copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#ifndef CORE_MQTT_CONFIG_H_
24+
#define CORE_MQTT_CONFIG_H_
25+
26+
/* Configure name and log level for the MQTT library. */
27+
#ifndef LIBRARY_LOG_NAME
28+
#define LIBRARY_LOG_NAME "MQTT"
29+
#endif
30+
#ifndef LIBRARY_LOG_LEVEL
31+
#define LIBRARY_LOG_LEVEL LOG_INFO
32+
#endif
33+
34+
#include "logging_stack.h"
35+
36+
/**
37+
* @brief Determines the maximum number of MQTT PUBLISH messages, pending
38+
* acknowledgement at a time, that are supported for incoming and outgoing
39+
* direction of messages, separately.
40+
*
41+
* QoS 1 and 2 MQTT PUBLISHes require acknowledgement from the server before
42+
* they can be completed. While they are awaiting the acknowledgement, the
43+
* client must maintain information about their state. The value of this
44+
* macro sets the limit on how many simultaneous PUBLISH states an MQTT
45+
* context maintains, separately, for both incoming and outgoing direction of
46+
* PUBLISHes.
47+
*
48+
* @note The MQTT context maintains separate state records for outgoing
49+
* and incoming PUBLISHes, and thus, 2 * MQTT_STATE_ARRAY_MAX_COUNT amount
50+
* of memory is statically allocated for the state records.
51+
*/
52+
#define MQTT_STATE_ARRAY_MAX_COUNT ( 10U )
53+
54+
/**
55+
* @brief Number of milliseconds to wait for a ping response to a ping
56+
* request as part of the keep-alive mechanism.
57+
*
58+
* If a ping response is not received before this timeout, then
59+
* #MQTT_ProcessLoop will return #MQTTKeepAliveTimeout.
60+
*/
61+
#define MQTT_PINGRESP_TIMEOUT_MS ( 5000U )
62+
63+
#endif /* ifndef CORE_MQTT_CONFIG_H_ */
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* AWS IoT Device SDK for Embedded C 202108.00
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
* this software and associated documentation files (the "Software"), to deal in
7+
* the Software without restriction, including without limitation the rights to
8+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
* the Software, and to permit persons to whom the Software is furnished to do so,
10+
* subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in all
13+
* copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#ifndef DEMO_CONFIG_H_
24+
#define DEMO_CONFIG_H_
25+
26+
/**
27+
* @brief IP or hostname of the Greengrass core.
28+
*
29+
* #define GREENGRASS_ADDRESS "...insert here..."
30+
*/
31+
32+
/**
33+
* @brief Greengrass MQTT broker port number.
34+
*/
35+
#ifndef MQTT_PORT
36+
#define MQTT_PORT ( 8883 )
37+
#endif
38+
39+
/**
40+
* @brief Path of the file containing the Greengrass core's root CA certificate.
41+
*
42+
* @note This certificate should be PEM-encoded.
43+
*
44+
* #define ROOT_CA_CERT_PATH "...insert here..."
45+
*/
46+
47+
/**
48+
* @brief Path of the file containing the client certificate.
49+
*
50+
* Refer to the AWS documentation below for details regarding client
51+
* authentication.
52+
* https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html
53+
*
54+
* @note This certificate should be PEM-encoded.
55+
*
56+
* #define CLIENT_CERT_PATH "...insert here..."
57+
*/
58+
59+
/**
60+
* @brief Path of the file containing the client's private key.
61+
*
62+
* Refer to the AWS documentation below for details regarding client
63+
* authentication.
64+
* https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html
65+
*
66+
* @note This private key should be PEM-encoded.
67+
*
68+
* #define CLIENT_PRIVATE_KEY_PATH "...insert here..."
69+
*/
70+
71+
/**
72+
* @brief Device Thing name.
73+
*
74+
* This should the Thing name created on IoT core with the above certificate.
75+
*
76+
* #define THING_NAME "...insert here..."
77+
*/
78+
79+
#endif /* ifndef DEMO_CONFIG_H_ */
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"certificateAuthority": {
3+
"privateKeyUri": "file:///home/user/ca.key",
4+
"certificateUri": "file:///home/user/ca.crt"
5+
},
6+
"deviceGroups": {
7+
"formatVersion": "2021-03-05",
8+
"definitions": {
9+
"MyDeviceGroup": {
10+
"selectionRule": "thingName: *",
11+
"policyName": "DemoClientDevicePolicy"
12+
}
13+
},
14+
"policies": {
15+
"DemoClientDevicePolicy": {
16+
"AllowConnect": {
17+
"statementDescription": "Allow client devices to connect.",
18+
"operations": [
19+
"mqtt:connect"
20+
],
21+
"resources": [
22+
"*"
23+
]
24+
},
25+
"AllowPublish": {
26+
"statementDescription": "Allow client devices to publish to all topics.",
27+
"operations": [
28+
"mqtt:publish"
29+
],
30+
"resources": [
31+
"*"
32+
]
33+
},
34+
"AllowSubscribe": {
35+
"statementDescription": "Allow client devices to subscribe to all topics.",
36+
"operations": [
37+
"mqtt:subscribe"
38+
],
39+
"resources": [
40+
"*"
41+
]
42+
}
43+
}
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)