Sorry for the late answer! Of course, I can do that. ![]()
So for the setup I am using a Raspberry Pi 4, an Arduino Nano 33 IoT and DuckDNS as a DNS-Server. DuckDNS is free to use and works just fine for private and small projects as mine.
For the next lines, I am providing the rough approach on how I've done it. At the end of this post I will provide some http-links that I've used as sources and to gain new knowledge. You should have a look at them as well, if this solution does not work for you.
So let's start.
Port Forwarding:
You have to do some port forwarding on your router. The process on how to do that depends on the router, you are using.
I am using a FritzBox with following ports. The ports depend on your mosquitto and nginx configurations. The nginx server, I am using for DuckDNS and to create a Let's Encrypt certificate runs on the default port 80 and 443. The other ports are for the websocket and mqtt protocols (and their secure versions).

On the Raspberry side:
I am using a raspberry pi 4 with the default raspbian 32bit OS.
Prerequirements:
- install mosquitto mqtt
- install nginx
- open the required ports with
ufw allow <port>on your raspberry
There are plenty of tutorials around the web on how to install and configure nginx and mosquitto on a raspberry pi. I didn't have any problems with that, so you should be fine as well.
- You have to install certbot to generate the Let's encrypt certificates.
- Register an account at https://www.duckdns.org/
- Configure nginx according to your DuckDNS domain. (For more information see the links in the section below).
- Create a new certificate with following command:
sudo certbot certonly --standalone --preferred-challenged http -d <your-subdomain>.duckdns.org -d *.<your-subdomain>.duckdns.org - Copy the following files to your mosquitto directory (optionally you can also provide the path to your Let's Encrypt certificate in your mosquitto.conf file. However, you may have to configure some rights of your linux system in order for it to work).
sudo cp /etc/letsencrypt/live/<your-subdomain>.duckdns.org/cert.pem /etc/mosquitto/certs/
sudo cp /etc/letsencrypt/live/<your-subdomain>.duckdns.org/chain.pem /etc/mosquitto/certs/
sudo cp /etc/letsencrypt/live/<your-subdomain>.duckdns.org/privkey.pem /etc/mosquitto/certs/
- Configure your mosquitto.conf file to your needs using the copied certificate files.
The configuration bwlow allows clients to connect via TLS and without TLS.
listener 1883
listener 8883
# TLS/SSL
certfile /etc/mosquitto/certs/cert.pem
cafile /etc/mosquitto/certs/chain.pem
keyfile /etc/mosquitto/certs/privkey.pem
listener 9001
protocol websockets
listener 8083
protocol websockets
# TLS/SSL
certfile /etc/mosquitto/certs/cert.pem
cafile /etc/mosquitto/certs/chain.pem
keyfile /etc/mosquitto/certs/privkey.pem
- You must configure your nginx-server to use the certificates and make it accessable via https. This is required to install the certificate on the Arduino later on. Also, you should provide a basic index.html file in order to have a "website" that can be certificated.
sudo nano /etc/nginx/conf.d/<your-domain>.duckdns.org.conf
server {
listen 80 default_server;
server_name <your-domain>.duckdns.org;
return 301 https://$server_name$request_uri;
root /var/www/<your-domain>.duckdns.org;
index index.php index.htm index.html;
}
server {
listen 443 ssl default_server;
server_name <your-domain>.duckdns.org;
##
# SSL
##
ssl on;
ssl_certificate /etc/letsencrypt/live/<your-domain>.duckdns.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<your-domain>.duckdns.org/privkey.pem; # managed by Certbot
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_ciphers HIGH:!aNULL:!MD5:!RC4;
##
# HSTS
##
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
##
# global
##
root /var/www/<your-domain>.duckdns.org;
index index.php index.htm index.html;
location / {
try_files $uri $uri/ =404;
}
}
- Don't forget to restart your mosquitto server and nginx server.
DONE! Now, you should have access to your mosquitto server via TLS using a trusted Let's Encrypt certificate. You can test this with any MQTT-Client. For example, I am using MQTT X (https://mqttx.app/) for testing.
Edit:
You can renew the Let's Encrypt certificate by using following command:
sudo certbot --authenticator standalone --installer nginx -d <your-domain>.duckdns.org -d *.<your-domain>.duckdns.org --pre-hook "service nginx stop" --post-hook "service nginx start"
Arduino:
- First you have to use thw WiFiSSLClient instead of the WiFiClient in your code.
WiFiSSLClient wifiClient;
PubSubClient client(wifiClient);
- Next you have to update your credentials according to your new configurations. Your server name will be your new DuckDNS domain and you might want to change the port according to the port you chose for TLS/SSL connections.
- I have update the NINA firmware of my Arduino to version 1.4.5, which requires to use the WiFiNINA library v 1.8.10. However, I am not sure if this is even required but it works.
Updating the firmware is pretty easy. Just flash the FirmwareUpdater example on your Arduino, choose your Arudino port and the version, you want to update to and click on "Update Firmware".
- Install the Let's Encrypt certificate from your nginx website according to following instructions by using your DuckDNS domain: https://support.arduino.cc/hc/en-us/articles/360016119219-How-to-add-certificates-to-Wifi-Nina-Wifi-101-Modules-
DONE! Because Let's Encrypt is already a trusted CA to the Arduino Nano 33 IoT, you don't have to do any further steps to trust the certificate.
Resources:
- How to Install and Secure the Mosquitto MQTT Messaging Broker on Debian 9 | DigitalOcean
- Mosquitto MQTT Broker SSL Configuration Using Own Certificates
- MQTTS : How to use MQTT with TLS? - examples and helpers β Openest
- Wildcard Zertifikat mit DuckDNS erstellen - Edvpfau (GERMAN language)
- Nginx und Let's Encrypt auf Raspberry Pi - Michis Blog (GERMAN language)
Side notes:
In this post, I am explaining for what I am using the mosquitto server and how to use it to control pwm-fans if anyone is interested. This might also help to write some code for your Arduino project.
I hope this post can help some people even though it does not provide every details of the whole process. However, I didn't want to pollute this post with writing too much about nginx and mosquitto itself.

