EMQX Cloud is the first fully hosted MQTT 5.0 cloud messaging service in the world. With the support of EMQX Cloud, you can create an MQTT cluster on the cloud and use the features of EMQX Enterprise Edition. This allows you to spend more time on business connections and less time for EMQX operation, maintenance, and management.
In this article, we will set up a two-way TLS/SSL authentication for an EMQX Cloud deployment with a third-party certification.
- Let's Encrypt, a free third-party Certificate Authority, will be used to certify a custom domain purchased from AWS Route 53, which will point to the EMQX Cloud deployment.
- OpenSSL will be used for client-side TLS/SSL.
- MQTTX will be used to validate the encrypted connection.
- An EMQX Cloud Professional deployment up and running: for this example, a deployment to AWS will be used.
- An MQTT client installed: for this example, MQTTX will be used.
- A registered domain: for this example, AWS Route 53 will be used.
Alternatively to the step by step below, instructions can be followed from the EMQX Cloud TLS/SSL documentation.
# Create CA certificate
openssl req -new -newkey rsa:2048 \
-days 365 -nodes -x509 \
-subj "/C=US/O=Test Org/CN=Test CA" \
-keyout client-ca.key -out client-ca.crt
# Create private key
openssl genrsa -out client.key 2048
# Create certificate request file
openssl req -new -key client.key -out client.csr -subj "/CN=Client"
# Create client certifite by feeding the certificate request file to the newly created CA
openssl x509 -req -days 365 -sha256 -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client.crt
# View and verify the client certificate
openssl x509 -noout -text -in client.crt
openssl verify -CAfile client-ca.crt client.crt
-
Copy the EMQX Cloud deployment URL from the EMQX Cloud console.
-
Create a CNAME record in AWS Route 53 hosted zone pointing to the EMQX Cloud deployment.
Alternatively to the step by step below, instructions are available from Let's Encrypt/Certbot for certbot and Route 53 plugin. Be sure to select "Other" for the "Software" dropdown, and the "Wildcard" tab.
-
Install package manager, Certbot, and DNS plugin using the CLI:
-
macOS:
# Install Homebrew if needed /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Install certbot with brew brew install certbot # Install DNS plugin (discussion on why Homebrew doesn't work: https:/certbot/certbot/issues/5680) $( brew --prefix certbot )/libexec/bin/pip install certbot-dns-route53
-
Ubuntu:
# Install snap if needed sudo snap install core; sudo snap refresh core # Install certbot with snap and configure it sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/bin/certbot sudo snap set certbot trust-plugin-with-root=ok # Install DNS plugin sudo snap install certbot-dns-route53
-
-
Give AWS permissions to the plugin:
-
Create IAM policy with the following statement, changing
YOURHOSTEDZONEID
:{ "Version": "2012-10-17", "Id": "certbot-dns-route53 policy", "Statement": [ { "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:GetChange" ], "Resource": [ "*" ] }, { "Effect" : "Allow", "Action" : [ "route53:ChangeResourceRecordSets" ], "Resource" : [ "arn:aws:route53:::hostedzone/YOURHOSTEDZONEID" ] } ] }
-
Create a new IAM user, attach the new policy to its permissions, and save the
Access key ID
andSecret access key
. -
Set credentials for the new IAM user in the CLI as environment variables and acquire a certificate:
export AWS_ACCESS_KEY_ID=AKIA---------EXAMPLE export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI-----------------EXAMPLEKEY certbot certonly --dns-route53 -d mqtt.YOURDOMAIN.COM
-
fullchain.pem
: The full chain of certificates involving the certification of the domain. Usually includes three certificates that can be broken down in the following manner:- Certificate body (first): the certificate for the registered domain.
- Intermediate certificate (second): the certificate for Let's Encrypt.
- Root certificate (third): the certificate from a trusted certificate authority, which belongs to a select few set of CA's shipped by default in most OS and web browsers.
cert.pem
: The first certificate from the full chain.chain.pem
: All the certificates from the full chain, except the first.privkey.pem
: Used to encrypt/decrypt data.
More information from Let's Encrypt on their certificate chain can be found here.
-
Click on
+ TLS/SSL
in EMQX Cloud console. -
Select "two-way" for "Type", add the certificates from previous steps to the EMQX Cloud deployment, and click "Confirm".
-
Certificate body:
cert.pem
from Let's Encrypt. The certificate created by Let's Encrypt for the subdomain. -
Certificate chain: The intermediate (second) certificate in
fullchain.pem
from Let's Encrypt. The chain should include all certificates between the certified (sub)domain and the root certificate, which in this case should be just one. -
Certificate private key:
privkey.pem
from Let's Encrypt. -
Client CA certificate:
client-ca.crt
locally created previously with openssl. Since the client connecting to the deployment also needs to be verified, the deployment needs to know the trusted CA to check client certificates with.
-
-
Ensure the existence of a username and password to connect to the deployment. Help creating users can be found here.
-
In the Let's Encrypt certificate directory, create a new
root.pem
file and add the root (last) certificate fromfullchain.pem
. -
Open MQTTX and create a new connection.
-
Fill out the new connection prompt with the proper information and click "Connect".
- Host and Port: since TLS is being used, choose
mqtts://
as well as port8883
. The port number can be confirmed in the EMQX Cloud console. Do not forget to add the certified subdomain in the address field. - Username and Password: fill out with an existing EMQX Cloud deployment user (see step 1).
- Enable both SSL options.
- Certificate: Choose self signed.
- Certificates:
- CA File:
root.pem
manually created from the Let's Encrypt certificates. - Certificate Client File:
client.crt
locally created previously with openssl. - Client key file:
client.key
locally created previously with openssl.
- Host and Port: since TLS is being used, choose
-
Once the connection is successful, a green "SSL" sign should appear and the two-way TLS/SSL is fully configured and ready to be used. It can be further tested by subscribing to a topic then sending a message to the same topic.
If you get a "Error: unable to get issuer certificate" message, download the ISRG Root X1 Self-signed certificate and use it in the MQTTX "CA file" field. The error occurs because Let's Encrypt's default root certificate is itself certified with an older CA that recently expired, causing some devices to no longer trust it. More information here.
Now we have finished setting up a two-way TLS authentication for an EMQX Cloud with a custom domain from Route 53 certified by Let’s Encrypt, tested with MQTTX. Two-way TLS/SSL can provide an important layer of security for communication over the internet, helping to protect sensitive information and prevent attacks.
Continue exploring what EMQX Cloud has to offer:
- Use Python to connect to EMQX Cloud.
- Persist data and connect to other services with Data Integrations.
- Access EMQX functions via REST API.
For more about EMQX Cloud, please check our documentation, GitHub, Slack channel, and forum! For questions, comments, or suggestions, please contact us at [email protected].