Contents

Device <-> AWS MQTT Connectivity

Introduction

Today I will show how to connect the IoT Device (represented as an IoT Thing) to the AWS IoT Core.

As a starting point, I will use the IoT Thing that we configured in my previous post.

Let’s review our current setup:

On-Premise and Cloud
On-Premise and Cloud

I will use the mosquitto client to test the connectivity between IoT Device and the AWS IoT Core.

Preparation

We need to copy credentials to our IoT Device:

  • Private Key
  • Certificate (corresponding to above Private Key)
  • AWS Root CA Certificate (used to validate the AWS IoT Core endpoint)
1
2
3
4
lmtx@lmtx:~/iot$ ls -1
5f9379fcd2-certificate.pem.crt  # Device Certificate
5f9379fcd2-private.pem.key      # Device Private Key
AmazonRootCA1.pem               # AWS Root CA Certificate

💡Note: Please remember that this approach is for demonstration purposes only! In the production deployment, the Private Key should not leave the IoT Device. I will cover production-ready credentials management in the future.

Connection setup

Let’s quickly review how the secure connection is established between the IoT Device and the AWS IoT Core.

IoT Device <-> AWS IoT Core connection
IoT Device <-> AWS IoT Core connection

During the connection setup, the IoT Device presents the x509 Device Certificate.

AWS IoT Core verifies if that certificate:

  • exists in the Thing Registry
  • is active
  • has a proper Policy attached

The Device certificate corresponds to the Device Private Key. Private Key is securely stored on the Device and should not be exposed.

The x509 Certificate and Private Key are used as the proof of identity of the IoT Device.

AWS IoT Core presents its certificate. The Device verifies if that is the certificate it expects:

  • if yes - that is the valid AWS IoT endpoint,
  • otherwise - that is some fake server and Device should drop the connection.

The Amazon Root CA certificate corresponds to the Amazon Private Key (securely stored at AWS).

This way, both parties established trust, confirmed identities, and started TLS encrypted MQTT communication.

You can find more details in AWS documentation.

Connect - first try

Before we can connect, we need to get the AWS IoT Core Data Endpoint. We can find it in the IoT Core Settings:

AWS IoT Core Data Endpoint
AWS IoT Core Data Endpoint

Execute the following command to connect from the IoT Device to the AWS IoT Core:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mosquitto_pub \
  -h a1pmmrdn6yc5il-ats.iot.eu-west-1.amazonaws.com \
  -i TempSensor1 \
  --key 5f9379fcd2-private.pem.key \
  --cert 5f9379fcd2-certificate.pem.crt \
  --cafile AmazonRootCA1.pem \
  -t test \
  -m '{"m":"ok"}' \
  -d \
  -q 1

where:
-h : mqtt host to connect to (the AWS IoT Core Data Endpoint),
-i : id to use for this client,
--key : client private key for authentication,
--cert : client certificate for authentication,
--cafile : path to a file containing trusted CA certificates to enable encrypted communication,
-t : mqtt topic to publish to,
-m : message payload to send,
-d : enable debug messages,
-q : quality of service level to use for all messages (the QoS 1 ensures that every message will be delivered at least once)

Let’s try to send a MQTT message from our IoT Device to the AWS IoT Core:

1
2
3
lmtx@lmtx:~/iot$ mosquitto_pub -h a1pmmrdn6yc5il-ats.iot.eu-west-1.amazonaws.com -i TempSensor1 --key 5f9379fcd2-private.pem.key --cert 5f9379fcd2-certificate.pem.crt --cafile AmazonRootCA1.pem -t test -m '{"m":"ok"}' -d -q 1
Client TempSensor1 sending CONNECT
Error: The connection was lost.

We received an error: The connection was lost.

AWS IoT Core Logs

To investigate this issue, we will enable the AWS IoT Core Logs.

AWS IoT Core Logs
AWS IoT Core Logs

Click on the Create role button to create a IAM Role that allows AWS IoT Core Service to send logs to the CloudWatch Service.

You can name the Role anyway you want. I will name mine the AWSIoTCoreLogsRole.

Set Info as the Log level.

AWS IoT Core Logs
AWS IoT Core Logs

Once we enabled logs, let’s send the MQTT message once more.

1
2
3
lmtx@lmtx:~/iot$ mosquitto_pub -h a1pmmrdn6yc5il-ats.iot.eu-west-1.amazonaws.com -i TempSensor1 --key 5f9379fcd2-private.pem.key --cert 5f9379fcd2-certificate.pem.crt --cafile AmazonRootCA1.pem -t test -m '{"m":"ok"}' -d -q 1
Client TempSensor1 sending CONNECT
Error: The connection was lost.

We failed (as expected).

Let’s check the CloudWatch logs to get more details.

AWS CloudWatch
AWS CloudWatch

AWS CloudWatch - Log groups
AWS CloudWatch - Log groups

Our IoT Device was not authorized to send the MQTT message (AUTHORIZATION_FAILURE).

AWS CloudWatch - Log events
AWS CloudWatch - Log events

IoT Device use the Private Key and Certificate for authentication.

To authorize our IoT Device, we need to attach the Policy to the Device Certificate.

AWS IoT Policy
AWS IoT Policy

AWS IoT Policy

Let’s switch to the AWS IoT Core service and create the Policy.

Create a Policy
Create a Policy

Create a Policy
Create a Policy

This Policy grants permission to:

  • connect to AWS IoT Core with client ID TempSensor1 (that is the client ID used by our IoT Device)
  • publish MQTT messages to the test topic (this restricts our IoT Device to publish only to the specified MQTT topic)

The same Policy in JSON format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:eu-west-1:693854281758:client/TempSensor1"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:eu-west-1:693854281758:topic/test"
    }
  ]
}

We need to attach this Policy to the Device Certificate.

Attach the Policy
Attach the Policy

Attach the Policy
Attach the Policy

AWS MQTT test client

We will use the AWS MQTT test client to check if the AWS IoT Core received our message.

Let’s subscribe to the test topic - the MQTT topic our IoT Device is allowed to publish to.

AWS MQTT test client
AWS MQTT test client

Connect - second try

Finally, we are ready to retry the IoT Device <-> AWS IoT Core MQTT communication.

1
2
3
4
5
6
lmtx@lmtx:~/iot$ mosquitto_pub -h a1pmmrdn6yc5il-ats.iot.eu-west-1.amazonaws.com   -i TempSensor1   --key 5f9379fcd2-private.pem.key   --cert 5f9379fcd2-certificate.pem.crt   --cafile AmazonRootCA1.pem   -t test   -m '{"m":"ok"}'   -d   -q 1
Client TempSensor1 sending CONNECT
Client TempSensor1 received CONNACK (0)
Client TempSensor1 sending PUBLISH (d0, q1, r0, m1, 'test', ... (10 bytes))
Client TempSensor1 received PUBACK (Mid: 1, RC:0)
Client TempSensor1 sending DISCONNECT

Our IoT Device was able to send the MQTT message to the AWS IoT Core!

AWS MQTT test client
AWS MQTT test client

Summary

Let’s summarize what we covered today:

  • copied required credentials to the IoT Device,
  • used the MQTT Client to test the connection between the IoT Device and the AWS IoT Core,
  • enabled the AWS IoT Core Logs,
  • used the AWS CloudWatch Service to debug the connection issue,
  • created the AWS IoT Policy and attached it to the Device Certificate,
  • successfully sent the MQTT message from our IoT Device to the AWS IoT Core.

Updated connection diagram:

On-Premise and Cloud
On-Premise and Cloud

Support quality content❤️ Donate💰

Sign up for news: (by subscribing you accept the privacy policy)