• Share this article:

Tutorial: Connecting Eclipse Kura to AWS IoT

Friday, October 23, 2015 - 13:49 by Benjamin Cabé

Just a few weeks ago, Amazon Web Services (AWS) announced that they added the ability for their customers to manage IoT solutions. More specifically, they are offering a managed IoT platform that allows to connect your devices using HTTP or MQTT, and that integrates with other AWS services to simplify things like message processing, persistence in S3 or DynamoDB, … you name it! And of course, this is meant to scale to billions of devices, although I have to admit I have not tested that just yet ?

In this article, I will show you how you can connect your Eclipse Kura gateway to AWS IoT. Since the authorization and overall security mechanisms in AWS IoT heavily rely on certificates, the only tricky bit will be for us to properly configure the Kura gateway so as it establishes a trusted connection to the AWS backend.

Prerequisites

  • You need to make sure that you are running Kura 1.3 or later, as it includes some fixes to be compatible with AWS IoT,
  • You will, of course, need to have an AWS account to be able to use the AWS IoT beta.

Provision your thing, certificate and policy in AWS IoT

Most of the operations that will allow you to manage your AWS IoT fleet can be performed either from the Web UI, or using the AWS CLI command line tool.

While you will probably want to use the CLI when you will be familiar with the platform, I suggest that you start your first experiments using the web interface.

So you need to create a “Thing”, with an attached certificate and policy to allow it to communicate. The easiest way to go through this is to create the thing from the web console, and then use the “connect wizard” to connect it. See the screenshots below, this should be pretty straightforward

You will end up with 3 files that you need to download:

  • A public/private key pair, just like what you used for e.g. SSH or GitHub. AWS IoT keeps track of the public key, and you will use the private key to encrypt the communications.
  • A certificate used by your client (in our case Kura), to authenticate the server.

Create a Java keystore

In Java, anything involving certificates is typically done using a so-called keystore: a secured storage facility for your certificates and cryptographic keys.

We will be able to add the AWS IoT certificates and keys in our keystore right from the Kura Web UI, but we first need to manually create the keystore. We will seed this keystore with the root Certificate Authority that is used to sign AWS IoT’s certificate.

sudo mkdir /opt/eclipse/security
cd /opt/eclipse/security
curl https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem > /tmp/root-CA.pem 
sudo keytool -import -trustcacerts -alias verisign -file /tmp/root-CA.pem -keystore cacerts -storepass changeit

This will warn you that the certificate is already installed in the system-wide keystore, but add it anyways.

Setup SSL communication settings in Kura

First, we need to make sure that the SSLManagerService is properly configured to use our freshly created keystore.

Kura SSL options

  • ssl.default.protocol: TLSv1.2,
  • ssl.default.trustStore: /opt/eclipse/security/cacerts (this should be the default value already,
  • ssl.keystore.password: changeit (or whichever password you picked earlier, when creating the keystore).

Next, in the ‘Settings’ section of the Kura UI, we have access to a pretty convenient way to add new keys or certificate to your keystore. This is where we want to add our private key, and AWS IoT’s certificate, that will be used for SSL mutual authentication.

Note that you first need to convert your private key in PKCS #8 format:
openssl pkcs8 -topk8 -inform PEM -outform PEM -in your-private.pem.key -out outKey.pem -nocrypt

Now all is left to do is head over to the “SSL Mutual Authentication” tab in the settings, and input the following:

SSL Mutual Authentication settings

  • Private key: the contents of the file in which you just put the PKCS8 version of the private key,
  • Private key storage password: changeit (or whichever password you picked earlier, when creating the keystore),
  • Public key: the contents of the certificate file,
  • Storage alias: this has to be the same information you have in the MqttDataTransport config section for topic.context.account-name. Default value is account-name. This alias is important since it’s used by Kura to actually use the correct key/certificate pair when establishing the MQTT communication.

A few last tweaks

As there are several limitations in the MQTT broker available at AWS IoT, you will need to change some of the default settings in Kura. In particular, the broker won’t let you subscribe or publish on topics prefixed by the ‘$’ sign (except for the $aws/ topic hierarchy).

    • CloudService: adjust the topic.control-prefix setting so as it doesn’t include a dollar sign. This prefix control where things like your device “birth certificate” are being published. If it has a dollar-prefix, you will be in trouble since AWS will just drop your MQTT connection!
    • MqttDataTransport: change the lwt.topic so as it does not have a topic with a dollar prefix anymore. And, last but not least, change the broker URL to the one associated with your AWS IoT account. It should be something like: mqtts://AHFXKRXXXXXXX.iot.us-east-1.amazonaws.com:8883 (mind the mqtts protocol, and the port 8883)

That’s it! You should be good to go!

From now on, all your Kura bundles that are using the DataService or the CloudService will be talking to the AWS IoT backend. Therefore if your Kura application is sending JSON payloads, you will be able to set up custom rules to store your data in DynamoDB or invoke Lambda functions. You may also want to experiment with the Thing Shadow API to have the ability to manage your gateway or its apps even when it is offline.

And you? What are you going to build with Eclipse Kura and AWS IoT?

The post Tutorial: Connecting Eclipse Kura to AWS IoT appeared first on Benjamin Cabé.