Mosquitto, SSL, certificates - how to?

Hi,

Running hassio with docker and mosquitto added as addon.
I have Duckdns/Lets Encrypt certificates, so SSL certificates are on place.

I want to use SSL (port 8883), but I find no good documentation on how to achieve this??
I’ve read a lot of articles here, but found none using the Lets Encrypt certificates.

Can anybody give a good how-to for getting to use SSL?

I’ve tried this;

mqtt:
  broker: !secret mqtt_server_local
  port: 8883
  username: !secret mqtt_username_local
  password: !secret mqtt_password_local
  certificate: /ssl/fullchain.pem
  tls_version: "1.2"
  tls_insecure: true
  discovery: true
  birth_message:
    topic: 'hass/status'
    payload: 'online'
  will_message:
    topic: 'hass/status'
    payload: 'offline'

But I still get the OpenSSL errors in mqtt logs, and I cannot access the broker neither from MQTT Explorer, any client like Zigbee2mqtt or even from running the MQTT Integration all over.

UPDATE:

Well, after many hours of testing and reading - I’ve got most of it resolved. The only missing part is the Mosquitto Integration, which I cannot get to use secure (8883) connection to the broker addon…

1 Like

@TheStigh, I am trying to achieve the same - securely connect to Mosquitto from each client. I am running Duckdns and it works well (can access my HomeAssistant instance through https://myduckdnsdomain.duckdns.org )
Can you share the steps you have completed so that you can successfully enable SSL on the Mosquitto broker and to access it from the clients?

@qntris

Hi, been I while since I did this. But did a check on the current configuration;

  1. Do not use any mqtt: in configuration.yaml

  2. This is my http: configuration (needed for the let’s encrypt certificates):

http:
  ip_ban_enabled: true
  login_attempts_threshold: 5
  server_port: 443
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem
  1. This is my current configuration in the addon Mosquitto Broker:
logins: []
customize:
  active: true
  folder: mosquitto
certfile: fullchain.pem
keyfile: privkey.pem
require_certificate: false
anonymous: false
  1. In /share/mosquitto I have the file mosquitto.conf with only one entry:
# TLS
tls_version tlsv1.2

I hope this helps :slight_smile:

1 Like

@TheStigh

Thanks a lot for the provided details - it worked that way! However, what I want to achieve is to be able to connect to the broker using a certificate in addition to the username and password authentication.

That would be achieved by changing the require_certificate option in the Mosquitto add-on configuration to true. However, I don’t know which certificates to use on the client side? Can you help with that?

After seeing this post revived a few days ago, I tried to tackle it, but failed. I used this link to create a self signed certificate.

mqtt config:

logins: []
customize:
  active: true
  folder: mosquitto
certfile: server.crt
keyfile: server.key
require_certificate: true
cafile: ca.crt

The above self signed certificates is stored in ssl folder just under the config folder. When I restart mqtt addon, the log shows that the certificates are found. When I try to test with a client connect using mqtt explorer, I get this error. Mqtt is not liking the certificates being self signed.

self signed certificate in certificate chain

I figured it out. The missing file is v3.ext, which I was using before when I created my self signed certificates for my HA local domain.

Follow this guide to create the server certificates. Pay attention to the part about common name cn when you fill out the information via openssl process. I used homeassistant as the CN since that is where my MQTT Broker add-on was install to. You can view yours by going to Supervisor → System and look for Hostname under HOST.

When you get to step 5, add the v3.ext file like so before creating the certificate.

sudo openssl x509 -req -in server.csr -CA ca.crt -extfile v3.ext -CAkey ca.key -CAcreateserial -out server.crt -days 720

Paste these line in the v3.ext, changing the DNS and IP to suite your settings.
DNS = What your HA hostname is
IP = HA local ip address

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS = homeassistant
IP = 192.168.1.20

Now Paste these 3 files into your mqtt addon. The files should go under ssl folder

ca.crt
server.crt
server.key

Your Mqtt config file should look like this.

logins: []
customize:
  active: true
  folder: mosquitto
certfile: server.crt
keyfile: server.key
require_certificate: true
cafile: ca.crt

Restart mqtt and you should see in log that the certificates are found.

Now is time to create a client certificate. Follow this guide to create them. Since we will use the same file from the server certificates, start from Step 1 from that link.

At step 2, under common name, input your mqttuser name. The one you use to login to mqtt.
At sep 3, use the same v3.ext file when creating the server certificate. The settings should be the same.

sudo openssl x509 -req -in client.csr -CA ca.crt -extfile v3.ext -CAkey ca.key -CAcreateserial -out client.crt -days 720

To test if you can login successfully, you can use mqtt explorer. Paste these 2 files somewhere in your windows.

client.crt
client.key

In your mqtt explorer certificate tab, navigate to these 3 files.

server certificate (CA) = this is the ca.crt from the server
Client certificate = client.crt
Client key = client.key

Make sure you change the settings to login using port 8883

If successful, you should not receive any red error message from mqtt explorer.

3 Likes

Hi - Excellent guide :slight_smile:

I followed it yesterday (and copied it so I could do it again) to get my instance set up…only difference is that I used 10 years certs…I think I’ll rebuild before they run out!

Now I’m trying to get some Pi 4s going with zigbee2mqtt on docker (running the IOTStack build) - I have this working and I have my first zigbee device detected and passed straight to HA - super excited at how easy that went.

But, ever the tinkerer…I know wonder if it is possible to get the zigbee2mqtt on the PI to use port 8883 back to HA with certificates. It should be totally possible, but I can’t quite grasp where to place the ca.crt. client.key, client.crt on the remote PI. No matter where I try I always get a ‘can’t find the certificate’ type error followed by a whole heaps of the usual ‘I can’t connect’ errors…

The whole thing is then pretty much unusable until you stop it, delete the cert lines out of the yaml and start again.

Has anyone managed to do this? I’ve browed quite a few forum topics now but detail is light on the ground when running in a container…

Cheers!

10 years huh? I thought my 2 years were a bit aggressive.

Have you looked at this sample?

Thanks @duceduc for your guide. It has been a life-saving help in getting MQTT working for my instance.

In case it helps a future reader: my add-on debug log was showing ‘[INFO]: SSL is not enabled’ during startup regardless of network and port config options. I was struggling to determine the file system location for storing the ssl files.

I have had success placing them in /ssl (ie the file system root). Running HA 2022.6.7 on rpi3.

Thanks @duceduc this is brilliant.

Couple of questions for anyone:

Will this support a remote MQTT client (ESP32 connected over a 4G WiFi modem ie connected via a remote internet connection sitting outside hassio’s WiFi LAN) with this config?

Would that just need port forwarding to Hassio of its IP and port 8883?

Or does the CN need to be an actual FQDN rather than just the hostname as @ducedec identified?

Nice guide, thanks.

If there is a need to connect clients from homeassistant (like zigbee2mqtt) and a “remote” client (like a mqtt vacuum), adding this to v3.ext should work. Remote in this case still in your own network but outside home assistant instance. If one wants an actual remote so from WAN, I think the IP should also match as in the example it is internal IP, connecting from WAN would not work. Unless it is something like Wireguard VPN. Might work if one remove the IP from the v3.ext and only use the domains?

DNS.1 = homeassistant
DNS.2 = your.ha.domain