Need a proper MKR 1500 - AWS IoT Core Tutorial

Hey All,

I've been following quite a few different posts over the last 2 days trying to get my MKR 1500 on AWS IoT core.

Today I realised there's no way to just pass Certificates as strings (as one youtube vid suggested).

Theres a tutorial which has a lot of details: https://docs.arduino.cc/tutorials/mkr-wifi-1010/securely-connecting-an-arduino-mkr-wifi-1010-to-aws-iot-core/

A few have referenced this. But my changes to it for my LTE-M Mkr 1500 dont work.

  1. My LTE-M module connects to the internet
  2. Connects to another MQTT broker (HiveMQ mqtt-dashboard.com port 443)
  3. Freezes at connecting to AWS

I followed the tutorial precisely, ran the encryption on board, generated a Cert, uploaded it, created a policy allowing all to the ARN of * And still not working/frozen at "connecting to AWS.

Code:

// Library imports
#include <ArduinoMqttClient.h>
#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <MKRNB.h>

// Secrets: AWS IoT Core and SIM settings
#define SECRET_PINNUMBER ""  // Your SIM PIN (leave empty if none)
#define SECRET_BROKER "XYZXYZXYZ-ats.iot.eu-north-1.amazonaws.com"  // AWS IoT Core endpoint
const char SECRET_CERTIFICATE[] = R"( 
-----BEGIN CERTIFICATE-----
MIICzjCCAbagAwIBAgIVAMoFbPBneSsNWCTM35knoJXmdXXLMA0GCSqGSIb3DQEB....

(Generated using the ECCX8 example sketch, ask to create private key and

then upload to AWS. Then when policy is done click download 

and you get a device cert - this is the device cert section.)

....
iFQpqumjDWXeZx02QXDuguzPWnE4lKMvxh8CBIXAbCXfsX6b2LVd503zpHyE+iW3
XHw=
-----END CERTIFICATE-----
)";

// AWS IoT Core and MQTT variables
const char apn[] = "iot.1nce.net";  // Your APN for the 1NCE SIM card
const char* broker = SECRET_BROKER;
const char* certificate = SECRET_CERTIFICATE;
const char* client_id = "Hopper2";  // Set your client ID here

// Cellular network objects
NB nbAccess(false);     // Use for non-blocking mode
NBClient nbClient;        // For the TCP connection
BearSSLClient sslClient(nbClient); // SSL client using BearSSL and ECC508
MqttClient mqttClient(sslClient);  // MQTT client using BearSSL
GPRS gprs;  // GPRS object for handling cellular connections

void setup() {
  Serial.begin(115200);
  while (!Serial);

  Serial.println("Connecting to cellular network...");

  // Connect to the cellular network (NB-IoT or LTE-M)
  if (nbAccess.begin(apn) != NB_READY) {
    Serial.println("Failed to connect to cellular network. Check SIM card or APN settings.");
    while (1);  // Stay in loop for debugging
  }

  Serial.println("Connected to cellular network.");

  // Attach GPRS (Data connection) using the APN and passing NULL for username and password
  if (gprs.attachGPRS(apn) != GPRS_READY) {
    Serial.println("Failed to attach GPRS. Check APN settings.");
    while (1);  // Stay in loop for debugging
  }

  Serial.println("Connected to LTE-M with internet access.");

  // Initialize ECC508 chip
  if (!ECCX08.begin()) {
    Serial.println("No ECCX08 present!");
    while (1);
  }

  // Set the SSL callback for the current time (used to validate server certificates)
  ArduinoBearSSL.onGetTime(getTime);

  // Set the ECCX08 slot to use for the private key and the certificate
  sslClient.setEccSlot(0, certificate);

  // Optional, set the client ID used for MQTT, if not set it will use a default ID
  mqttClient.setId(client_id);  // Setting client ID to "Hopper2"

  // Set the message callback function
  mqttClient.onMessage(onMessageReceived);
}

void loop() {
  // Keep the MQTT client connected
  if (!mqttClient.connected()) {
    connectMQTT();
  }

  // Poll for incoming messages
  mqttClient.poll();

  // Publish a simple message to AWS IoT Core
  publishMessage();

  // Delay to avoid publishing too frequently
  delay(10000);  // Send a message every 10 seconds
}

void connectMQTT() {
  Serial.print("Attempting to connect to MQTT broker: ");
  Serial.println(broker);

  while (!mqttClient.connect(broker, 8883)) {
    // Failed, retry
    Serial.print(".");
    delay(5000);
  }

  Serial.println();
  Serial.println("You're connected to the MQTT broker");
  mqttClient.subscribe("arduino/incoming");
}

unsigned long getTime() {
  // Get the current time from the cellular network (LTE-M)
  return nbAccess.getTime();
}

void publishMessage() {
  Serial.println("Publishing message");

  // Send message, the Print interface can be used to set the message contents
  mqttClient.beginMessage("arduino/outgoing");
  mqttClient.print("Hello from Hopper2! Current millis: ");
  mqttClient.print(millis());
  mqttClient.endMessage();
}

void onMessageReceived(int messageSize) {
  // We received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");

  // Use the Stream interface to print the message contents
  while (mqttClient.available()) {
    Serial.print((char)mqttClient.read());
  }

  Serial.println();
}

This method of cert - generates an on board private key, you copy that private key from serial and then save it in a txt file and upload it to AWS. Then create policy allow all and attach and activate.

That should be it.

If any of you can solve this, please let's post the final code as working code for 1500.

Thank you so much to anyone who can help

Hey All,

So I think the issue is larger than just AWS - there are updated steps to connect to Azure IoT here
https://docs-content.arduino.cc/tutorials/mkr-nb-1500/securely-connecting-an-arduino-nb-1500-to-azure-iot-hub/

But, there are a lot of posts about either not being able to connect to secure ports, or even if connected it might cut out.

I'm not using Azure but I tried both AWS and HiveMQ. HiveMQ let's you upload a signed public key.

For AWS/HiveMQ you cannot self-sign, you need it signed from a trusted CA authority. So create a cert request then sign it with OpenSSL or another. From which you are given a signed device certificate.

This gets uploaded to HiveMQ/AWS / other TLS MQTT broker - and for me still didn't work.

It may be a case of these brokers not trusting OpenSSL / needing a different authority. But then you are generally paying for a signature.

There isn't the option to use self signed with most providers.

So, if anyone has got this working for an example other than Azure - self signed, please let me know.

Right now I think the Tutorial should be updated to include a CSR walkthrough which is what most providers will need.

On top of that, the tutorial should include who/where the cert is being signed - to make sure that the signature is trusted and ideally another paid service isnt needed.

If that isn't done, technically this device is not capable of secure comm / TLS.

I think I'm gonna contact support and just send them this post, I'm going to create an unsecured MQTT broker with user/pass but TLS is pretty important.

Hey Everyone, just an update on this.

  1. RootCA Certificate Not Trusted.

So, there is a command to ping HiveMQ but using the RootCA.
What you do is use the same rootCA you used to sign the Arduino certificates but instead of using the arduino public and private key, you can create any public and private key on your computer. sign them with that RootCA and then you ping HiveMQ or any website.

This tells you if your RootCA is trusted.

Hive MQ uses "Lets Encrypt" - Obviously if you use OpenSSL to sign the cert, that means you dont use Lets Encrypt.

HiveMQ actually wont trust your certificates. And this might be the same for many providers.

Again, please ask ChatGPT for the commands to do this, and then give chatGPT the output from SSL- It will say error or something.

THEN if this is the case, there is something you can do to get any give domain you wnat to trust your RootCA - again, chatGPt for the command.

Then your trusted. So once you can do this you can Ping or SSH the domain from your computer and get an auth response.

  1. Second part of my problem - I am able to ping the HiveMQ domain from my computer but not from my Arduino. HiveMQ has my RootCA uploaded. Same RootCA used to sign my computer private key and arduino private key.

This means I have a firewall blocking me on my 1nce Sim network.

I am actually not using MQTT anymore

I've just deployed a CoAP / LwM2M which works well - this is the advice from 1nce for rural IoT applications.

However - if you are using MQTT please look into the first issue I had (any given domain will not necessarily trust your RootCA) and resolve that.

Then you can trying to ping/ssh a domain after you are trusted (you do not need credentials to do this, its not establishing the MQTT connection, it just shows if you are trusted now or not).

If no bueno, means you have a firewall issue.

Okay, last thing, please ask ChatGPT 1o these questions if you are confused - Certificates is NOT a simple topic, because you are multiple components to both client and server keys (public,private,signature,root) -> Each of these is used in a different way.

Having ChatGPT explain it step by step is the best bet. Good luck to you all.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.