Two-way TLS/SSL with EMQX Cloud, MQTT X, and Let’s Encrypt
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.
- MQTT X 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, MQTT X will be used.
- A registered domain: for this example, AWS Route 53 will be used.
Create client-side self-signed certificate
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
Point a subdomain to the EMQX Cloud deployment cluster
- Copy the EMQX Cloud deployment URL from the EMQX Cloud console.
2. Create a CNAME record in AWS Route 53 hosted zone pointing to the EMQX Cloud deployment.
Get a certificate for the subdomain
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:
# 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://github.com/certbot/certbot/issues/5680)
$( brew --prefix certbot )/libexec/bin/pip install certbot-dns-route53
# 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
2. Give AWS permissions to the plugin:
- Create IAM policy with the following statement, changing
"Id": "certbot-dns-route53 policy",
"Effect" : "Allow",
"Action" : [
"Resource" : [
- Create a new IAM user, attach the new policy to its permissions, and save the
Access key IDand
Secret access key.
- Set credentials for the new IAM user in the CLI as environment variables and acquire a certificate:
certbot certonly --dns-route53 -d mqtt.YOURDOMAIN.COM
Understanding the Certbot certificates
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.
Set up two-way TLS/SSL in EMQX Cloud deployment
- Click on
+ TLS/SSLin EMQX Cloud console.
2. Select “two-way” for “Type”, add the certificates from previous steps to the EMQX Cloud deployment, and click “Confirm”.
- Certificate body:
cert.pemfrom Let's Encrypt. The certificate created by Let's Encrypt for the subdomain.
- Certificate chain: The intermediate (second) certificate in
fullchain.pemfrom 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.pemfrom Let's Encrypt.
- Client CA certificate:
client-ca.crtlocally 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.
Test two-way TLS/SSL with MQTT X
- 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.pemfile and add the root (last) certificate from
- Open MQTT X and create a new connection.
4. 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 port
8883. 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.
- CA File:
root.pemmanually created from the Let's Encrypt certificates.
- Certificate Client File:
client.crtlocally created previously with openssl.
- Client key file:
client.keylocally created previously with openssl.
5. 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 MQTT X “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 MQTT X. 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.
Originally published at https://www.emqx.com.