Amazon AWS IoT Core: sending an MQTT message via WebSocket from the browser - amazon-web-services

I'm building a webapp which should send and receive MQTT messages to and from IoT Core.
I read that Amazon AWS IoT Core does support MQTT over WebSocket so I created a test "thing", created an IAM user and attached a policy with full access to the IoT functions (connect, subscribe, send etc..).
The documentation says that the AWS SDK for JavaScript can be used in a browser environment:
So I created my webpp and imported the library
var awsIot = require('aws-iot-device-sdk');
But I get some errors:
Can't resolve 'path
Can't resolve 'fs'
Can't resolve 'tls
After searching online it seems that these libraries are only supported by node.js and not the browser.

It has to do with the fact that webpack has removed polyfills in their new version. You have to add code below to your webpack.config.js fallback location and install them of course.
Or you can switch into webpack v4.
module.exports = {
...
resolve: {
fallback: {
"fs": false,
"path":false,
"tls":false
},
}
}

Related

Publish to MQTT topic in AWS IoT from Ionic 5

I am using ionic 5 for a mobile app that runs on iOS and Android. How can I publish a message to an MQTT topic in AWS IoT from Ionic 5? I have generated certificates for the client authentication in AWS IoT already. Are there any libraries available for this?
You can use a variety of MQTT client libraries in the Ionic 5 app to send messages to an MQTT subject in Amazon IoT. Paho MQTT JavaScript Client Library is one such library.
The steps below can be used to incorporate this library into the Ionic 5 app:
With npm, add the Paho MQTT JavaScript client library to your Ionic application.
npm install paho-mqtt
Import the library into your Ionic application, then build a new MQTT
client object.
import { Client } from 'paho-mqtt';
const client = new Client('wss://your-aws-iot-endpoint', 'your-client-id');
Use the client object and your generated certificates to establish a
connection to the Amazon IoT MQTT broker.
Using the send method of the client object, you can send messages to
an MQTT topic after the client has established a connection.
Use certificate-based authentication in place of username and
password by using the following code:
const options = {
useSSL: true,
userName: 'your-aws-iot-username',
password: 'your-aws-iot-password',
ssl: {
key: 'path/to/your/device-private-key.pem',
cert: 'path/to/your/device-certificate.pem',
ca: 'path/to/your/ca-certificate.pem',
},
onSuccess: () => console.log('MQTT client connected'),
onFailure: (error) => console.error('MQTT client connection failed:', error),
};
Using the send method of the client object as before, you can publish
messages to an MQTT topic after the client has established a
connection.
const topic = 'your-mqtt-topic';
const message = new Message('your-message-payload');
message.destinationName = topic;
client.send(message);

How to use librdkafka with OIDC and Azure AD as token provider for OAUTHBEARER?

Problem
I want to use Kafka OIDC with Azure AD as a token provider, but I'm stuck on some strange errors.
I have read many azure docs pages and tried their examples from https://github.com/Azure/azure-event-hubs-for-kafka - all those worked for me when I tested with python and C++.
Including oauth(which uses Azure AD) examples listed in https://github.com/Azure/azure-event-hubs-for-kafka/tree/master/tutorials/oauth/python
Errors
When I attempted to use the credentials from the registered app's webpage following the https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc and using the v2 endpoint, I ended up with ERROR|rdkafka#producer-1| [thrd:app]: rdkafka#producer-1: sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap: SASL authentication error: Invalid URI: The format of the URI could not be determined. (after 272ms in state AUTH_REQ).
For the v1 without the scope, the error is similar - FAIL|rdkafka#producer-1| [thrd:sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap]: sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap: SASL authentication error: Invalid URI: The format of the URI could not be determined. (after 259ms in state AUTH_REQ).
Setup
Again, all the existing examples I tested work for me, but none of those uses OIDC.
The configuration I'm using is below - what should I use in sasl.oauthbearer.token.endpoint.url, sasl.oauthbearer.config to make this work?
conf->set("bootstrap.servers", "myhub.servicebus.windows.net:9093", errstr);
conf->set("security.protocol", "SASL_SSL", errstr);
conf->set("sasl.mechanism", "OAUTHBEARER", errstr);
conf->set("sasl.oauthbearer.method", "oidc", errstr);
conf->set("sasl.oauthbearer.client.id", "***", errstr);
conf->set("sasl.oauthbearer.client.secret", "***", errstr);
conf->set("sasl.oauthbearer.token.endpoint.url", "https://login.microsoftonline.com/***/oauth2/v2.0/token", errstr);
conf->set("sasl.oauthbearer.scope", "api://***/.default", errstr);
Links
Confluent Kafka OIDC - https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=186877575
C++ librdkafka OIDC - https://github.com/edenhill/librdkafka/blob/b871fdabab84b2ea1be3866a2ded4def7e31b006/src/rdkafka_sasl_oauthbearer_oidc.c#L242
Github issues question - https://github.com/Azure/azure-event-hubs-for-kafka/issues/223
Edited:
Further debugging with debug=all revealed that OAUTHBEARER token is received while the app fails on SASL Authentication Sequence.
SASL OAUTHBEARER client in state client-first-message
Send SASL Kafka frame to broker
Sent SaslAuthenticateRequest
Received SaslAuthenticateResponse
Invalid URI: The format of the URI could not be determined.
Okay, Azure responded that Kafka OIDC isn't tested on their side and may not be supported by the broker.
But I tested that it works with Kafka OIDC - I will contribute with the examples to their repo soon.
The problem was using scope for the registered app(api://{app-id}/.default) vs scope for the namespace(https://myhub.servicebus.windows.net/.default) - latter one is correct.
That, in turn, led to receiving the incorrect token-type and Invalid URI format - what really helped here was example from the confluent-kafka with no azure dependencies involved https://github.com/confluentinc/confluent-kafka-python/blob/master/examples/oauth_producer.py

Connect react native mobile app to AWS websocket API

I am building a card game on mobile, with React Native and Expo. I would like to allow real-time updates during a game and I thought about using AWS Gateway's websocket API.
I created the API on AWS Gateway and the following code in React Native to connect to it:
connectToWebSocket = (onConnected) => {
const socket = new WebSocket("wss://xxxx.execute-api.us-east-1.amazonaws.com/production");
socket.addEventListener("open", (e) => {
onConnected();
});
socket.addEventListener("close", (e) => console.log("WebSocket is closed"));
socket.addEventListener("error", (e) => console.error(e));
};
Unfortunately, this gives me the error EventĀ {isTrusted: false} and does not connect.
It seems that all the available examples online are about building a web app that connects to AWS Gateway, but not for a mobile app. I've been reading tutorials for hours now and am completely stuck.
Is there any way for me to use AWS Gateway's websocket API for my project?
I figured it out! The very first thing is that my Websocket API was not deployed.
On the Routes panel, I had to go to Actions>Deploy API
The second thing is that my route Integration types were Lambdas, but I had not switched the Use Lambda Proxy integration flag on. Because of that, no event was sent to my lambda and the code was failing.
Once I had fixed both of those, I could connect without a problem :)

AWS SES could not send the email, got 550 error

I use SES for sending emails to users. Sometimes users reported to me that they did not receive any emails from me. I started to collect bounced emails via sns topic and found a lot of errors with status = 5.5.1 and
diagnosticCode
"smtp; 550 5.1.1 Remote MTA does not support STARTTLS. Message can be delivered only over a TLS connection."
I use the aws-sdk and my code which sends emais:
let params = {
Destination: {
ToAddresses: [emailDestination]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: template({
...templateData
})
},
},
Subject: {
Charset: 'UTF-8',
Data: templateData.subject
}
},
Source: SOURCE_EMAIL,
ConfigurationSetName: CONFIGURATION_SET_NAME
};
await ses.sendEmail(params).promise()
My ConfigurationSet has TLS Required
What did I do wrong and could it be a remote configuration issue of the user?
I think you are on the right track of it being a remote issue. From the sound of the error, Amazon SES is trying to connect to a remote mail relay but failing to create a TLS connection and canceling instead.
Your configuration set is enforcing a policy of sending only when a TLS connection can be established to receiving server (and message is encrypted) all the way to the end-user. Depending on how sensitive your emails are, this may be the desired behavior.
However, if you want to continue to send the mail, even when unencrypted, you can disable the require TLS setting. Amazon will still use TLS when possible, according to their documentation -
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/security.html
By default, Amazon SES uses opportunistic TLS. This means that Amazon SES always attempts to make a secure connection to the receiving mail server. If Amazon SES can't establish a secure connection, it sends the message unencrypted.

WSO2 EI611 Kafka connector error jaas.conf not found

EI611 with kafka connector latest throwing error :
org.apache.kafka.common.KafkaException: Exception while loading
Zookeeper JAAS login context 'Client' . . . . Caused by:
java.lang.SecurityException: java.io.IOException:
C:\WSO2EI~1.1\bin..\repository\conf\identity\jaas.conf (No such file
or directory)
This error was posted by someone else too :
wso2 Inbound endpoint - Kafka consumer
Does anybody find the solution? Do you know how to fix?
If you need to configure Kafka without security, the recommonded version is 0.8.1.1.
From Kafka version 0.9 onwards, they have introduced Kafka security mechanism with SSL and SASL, which will be configured via JAAS. So, when configuring Kafka with WSO2 Products (EI, DAS, CEP) you need to add this config file (jaas.conf) to /repository/conf/identity.
In this case, WSO2 product acts as the Kafka client and the configuration in the jaas.conf will be used to login to the kafka server. Please follow the Kafka security documentation [1] for configuring security for server and client.
Example content for jaas.conf file which is configured for SASL/ Plaintext.
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="kafka"
password="kafka-secret"
user_kafka="kafka-secret"
user_ibm="ibm-secret";
};
KafkaClient {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="kafka"
password="kafka-secret";
};
Please note that kafka 0.9 supports only SASL/Kerberos authentication. Please carefully follow the Kafka security documentation related to your Kafka version and configure it properly.
[1] http://kafka.apache.org/090/documentation.html#security_sasl