Skip to content

Obtaining a permanent certificate for Greengras IOT Device

0

Hello everyone,

I am currently working on connecting various devices to AWS via Greengras IOT. The Greengras components are running in Docker containers. However, I am currently having problems with the certificates.

At first I “only” worked with claim certificates, but had the problem that these are only valid for 24 hours and are not valid for reconnecting to AWS if there is an interruption. That's why I'm trying to create permanent certificates after registering with the calim certificates, but unfortunately I'm not getting anywhere.

Does anyone have a best practice with Docker and Greengras IOT on the subject of permanent certificates?

Here is a part of my current approach as a bash script, but it does not work as desired:

check_device_registration() {
    echo "Checking if the device is registered..."

    # Extract Thing Name from config.yaml
    thingName=$(grep 'ThingName:' "$CONFIG_FILE" | awk '{print $2}' | tr -d '"')

    if [ -z "$thingName" ]; then
        echo "Error: ThingName could not be extracted from $CONFIG_FILE."
        exit 1
    fi

    # Check the status of the device
    deviceStatus=$(aws iot describe-thing --thing-name "$thingName" --query 'thingTypeName' --output text 2>/dev/null || echo "NOT_FOUND")
    
    echo "Device status: $deviceStatus"

    if [ "$deviceStatus" = "NOT_FOUND" ]; then
        echo "The device is not yet registered. Waiting for registration..."
        return 1
    fi

    echo "The device is registered. Status: $deviceStatus"
    return 0
}

 Function to provision the permanent certificate
provision_permanent_certificate() {
    echo "Requesting permanent certificate..."

    # Device must be registered
    if ! check_device_registration; then
        echo "The device is not registered. Starting Greengrass for initial registration..."
        start_greengrass_initial
        if ! check_device_registration; then
            echo "Registration failed. Check the Greengrass configuration."
            exit 1
        fi
    fi

    MQTT_PUB_TOPIC="$aws/certificates/create/json"
    MQTT_SUB_TOPIC="$aws/certificates/create/accepted"
    ERROR_TOPIC="$aws/certificates/create/rejected"

    iotDataEndpoint=$(grep 'iotDataEndpoint:' "$CONFIG_FILE" | awk '{print $2}' | tr -d '"')

    if [ -z "$iotDataEndpoint" ]; then
        echo "Error: iotDataEndpoint could not be extracted from $CONFIG_FILE."
        exit 1
    fi

    echo "IoT Data Endpoint: $iotDataEndpoint"

    # Request certificate via MQTT
    mosquitto_pub \
        --cafile /greengrass-setup/AmazonRootCA1.pem \
        --cert "$CLAIM_CERT_PATH" \
        --key "$CLAIM_CERT_PATH" \
        -h "$iotDataEndpoint" \
        -p 8883 \
        -q 1 \
        -t "$MQTT_PUB_TOPIC" \
        -m "{}"

    echo "Waiting for response from AWS IoT Core..."

    mosquitto_sub \
        --cafile /greengrass-setup/AmazonRootCA1.pem \
        --cert "$CLAIM_CERT_PATH" \
        --key "$CLAIM_CERT_PATH" \
        -h "$iotDataEndpoint" \
        -p 8883 \
        -q 1 \
        -t "$MQTT_SUB_TOPIC" \
        -t "$ERROR_TOPIC" \
        | while read -r payload; do
            echo "Response received: $payload"
            if [[ "$payload" == *"certificatePem"* ]]; then
                echo "$payload" | jq -r '.certificatePem' > "$PERMANENT_CERT_PATH"
                echo "$payload" | jq -r '.privateKey' > "$PERMANENT_KEY_PATH"
                echo "Permanent certificate successfully created."
                break
            elif [[ "$payload" == *"errorMessage"* ]]; then
                echo "Error creating certificate: $payload"
                exit 1
            fi
        done
}

# Function to update `config.yaml` with permanent certificates
update_config_with_permanent_certificate() {
    echo "Updating configuration in $CONFIG_FILE..."

    # Ensure the file exists
    if [ ! -f "$CONFIG_FILE" ]; then
        echo "Error: $CONFIG_FILE not found."
        exit 1
    fi

    # Update certificate and key paths in `config.yaml`
    sed -i "s|claimCertificatePath:.*|claimCertificatePath: \"$PERMANENT_CERT_PATH\"|" "$CONFIG_FILE"
    sed -i "s|claimCertificatePrivateKeyPath:.*|claimCertificatePrivateKeyPath: \"$PERMANENT_KEY_PATH\"|" "$CONFIG_FILE"

    echo "Configuration updated successfully."

    # Restart Greengrass Nucleus
    restart_greengrass
}

if [ ! -d $GGC_ROOT_PATH/alts/current/distro ]; then
    # Install Greengrass via the main installer, but do not start running
    echo "Installing Greengrass for the first time..."
    parse_options
    start_greengrass_initial
else
    echo "Reusing existing Greengrass installation..."
fi

# Make loader script executable
echo "Making loader script executable..."
chmod +x $GGC_ROOT_PATH/alts/current/distro/bin/loader

echo "Starting Greengrass..."

# Start greengrass kernel via the loader script and register container as a thing
exec $GGC_ROOT_PATH/alts/current/distro/bin/loader &

# Background process for certificate provisioning and configuration update
(
    # Wait time to ensure that the Greengrass kernel has started and the device has been activated
    sleep 30

    # Provision the permanent certificate
    provision_permanent_certificate

    # Update the configuration with the permanent certificate
    update_config_with_permanent_certificate
) &

# Wait for the Greengrass kernel process
wait
2 Answers
1

When working with AWS IoT Greengrass in Docker containers, it's important to use permanent certificates rather than claim certificates for reliable and continuous device connectivity. Here's a best practice approach for handling permanent certificates with AWS IoT Greengrass in Docker:

  1. Create an AWS IoT thing: First, register your device as an AWS IoT thing in the AWS IoT Core console. This process will generate permanent X.509 certificates for your device.

  2. Download the certificates: After creating the thing, download the device certificate, private key, public key, and the Amazon Root CA certificate. These are the permanent credentials your device will use.

  3. Store certificates securely: Create a dedicated folder on your host machine to store these security resources. For example, you might create a folder like "certs" in your user's Downloads directory.

  4. Move certificates to the secure folder: Transfer the downloaded certificates and keys to this secure folder. Ensure you move the device certificate, private key, public key, and the Amazon Root CA certificate.

  5. Configure Docker volume: When running your Greengrass Docker container, use a volume mount to make these certificates available inside the container. This allows the container to access the certificates without embedding them in the image, which is more secure.

  6. Update Greengrass configuration: Ensure your Greengrass configuration file (config.json) points to the correct locations of these certificates within the container's file system.

  7. Run the Docker container: When starting your Greengrass Docker container, include the volume mount for the certificates. For example:

    docker run -it --rm --name aws-iot-greengrass \
      -v /path/to/certs:/greengrass/certs \
      -v /path/to/config:/greengrass/config \
      amazon/aws-iot-greengrass
    
  8. Implement certificate rotation: Although these certificates are long-lived, it's a good security practice to rotate them periodically. AWS IoT Greengrass supports automatic certificate rotation for the local MQTT server. You can configure the rotation period (between 7 and 30 days) in the Greengrass group settings.

By following these steps, you'll be using permanent certificates that don't expire after 24 hours, allowing your devices to maintain long-term connectivity with AWS IoT, even after interruptions. Remember to keep your certificates and private keys secure at all times, as they are used to authenticate your device to AWS IoT services.
Sources
Device authentication and authorization for AWS IoT Greengrass - AWS IoT Greengrass
Provision an AWS IoT thing to use as a Greengrass core - AWS IoT Greengrass
Running AWS IoT Greengrass in a Docker container - AWS IoT Greengrass
Device authentication and authorization for AWS IoT Greengrass - AWS IoT Greengrass

answered 2 years ago

  • Thank you for your answer.

    Unfortunately, this is a bit too manual for me, I would like to have an automated approach - sorry, but I had not communicated this before.

    I will add my current non-functioning script to my original question. This script is started when the docker container is started/built

1

The shell scripts assume a set of SigV4 credentials and then go down the process of generating the claim certificates. Prior to launching GreenGrass, you should generate and store permanent credentials (which can be via a claim process) and persist those for the next time the containers need to start. If you have SigV4 IAM credentials today, you can do that if the role permits the needed iot: actions.

AWS

answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.