How to get Letsencrypt working with the Mosquitto MTTQ broker

My server host name is host1.mailhub4u.com and I am self-hosting a Debian 12 machine. I have been running the Mosquitto MQTT broker, the Exim4 mail server and the Apache2 web server for several years without a problem with PositiveSSL certificates that I have been manually generating and installing. I recently installed certbot and converted Exim4 and Apache2 to Letsencrypt certificates. Everything worked great and, quite frankly, was easily installed and made operational. Great!!!

Now, I am attempting to get Mosquitto to work with Letsencrypt, however, I have not yet been successfull. I executed all of the command line commands necessary to install the Letsencrypt certificates using certbot in order to get Apache and Exim working. I then have been endeavoring to use the same certificates for Mosquitto. The Letsencrypt certs are in the /etc/letsencrypt/live/host1.mailhub4u.com/ directory and are named:

cert.pem
chain.pem
fullchain.pem
privkey.pem

However, I am not certain which of these certificates should be assigned to which Mosquitto variables that are defined in /etc/mosquitto/conf.d/myconfig.conf as follows:

cafile
certfile
keyfile

I have tried to infer the proper relationship between the Mosquitto variables and the Letsencrypt certificates (based on my Apache2 and Exim4 configs) and I think that I have tried just about all the possible combinations with the four certificates and the three variables, however, so far, I have been unable to get it to work. The Mosquitto service starts properly without errors but then as soon as anybody connects to the Mosquitto MQTT server then it does not produce the MQTT feed and the following error shows up in the Mosquitto logs:

OpenSSL Error[0]: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca

To me this seems like a simple problem with the Letsencrypt certificates' configuration for Mosquitto that I should be able to figure out, however, so far I have not been successfull.

What are the correct Letsencrypt certificate names to be assigned to the Mosquitto variables, cafile, certfile and keyfile?

Does anybody have any suggestions on how to get Letsencrypt working with Mosquitto?

Please let me know if you do.

I use the Mosquitto broker on one of my weather websites for updating user's weather data in real time without the user having to refresh the page. The weather website can be viewed at:

https://crabapple.dickens.com/

I now need to convert the Mosquitto config back to the PositiveSSL certs so that my MTTQ broker feed works for my users while I figure this out. I say that so that if anybody tries to test my MQTT broker on my server it wiil be working because I have reverted to the PositiveSSL certificates. I can reimplement the Letsencrypt config whenever anyone wants to help test. Just let me know.

Thanks in advance for any recommendations.

Thanks,

Gordon

Just as a guess (and I'd suggest the Mosquitto docs would be a better source of information for you), cafile should be chain.pem, certfile should be cert.pem, and keyfile should be privkey.pem.

2 Likes

Thanks very much for your reply! I have tried the following:

cafile /etc/mosquitto/certs/chain.pem
or;
cafile /etc/mosquitto/certs/fullchain.pem
or;
cafile /etc/ssl/certs/ISRG_Root_X1.pem
and;
certfile /etc/mosquitto/certs/cert.pem
keyfile /etc/mosquitto/certs/privkey.pem

That is I am fairly confident that the certfile and key file are correct as above but I wonder about the cafile.... As far as I know, it may all be wrong....

FYI,

Gordon

Isn't that used for client authentication? I'm not sure but a couple LLMs say so :slight_smile:

In that case you set that based on the TLS Client requirements. What did you use before? Usually for client auth (aka mTLS) you shouldn't use a public CA cert. You would use a private one or possibly self-signed. Do you need to even use that feature? I'm not a MQTT expert but often these are optional but of course depends on your requirements too.

Just fyi, you shouldn't use Let's Encrypt certs for client authentication. In fact, the Client auth EKU is nearly completely removed from LE certs. See: Ending TLS Client Authentication Certificate Support in 2026 - Let's Encrypt

I don't know if MQTT would even check that EKU but probably best to avoid using for client auth in any case.

4 Likes

OK. I finially figured out how to get Letsencrypt certificates to work with Mosquitto but I ended up having to get claude.ai to help. Basically, you have to do the following to get it to work:

The primary problem was that, by default, Letsencrypt issues ECDSA certificates whereas Mosquito uses RSA certificates. Claude told me that Mosquitto and the Paho MQTT client library (used by my weather website software, weewx) have compatibility issues with ECDSA. I have multidomain certificates with three domains and so I must request an RSA certificate explicitly using "--key-type rsa" as follows:

certbot certonly --key-type rsa --no-reuse-key -d domain1.tld -d domain2.tld -d domain3.tld --force-renewal

Claude also recommended these changes to Mosquitto and Weewx:

The cafile directive in my Mosquitto config is only needed for mutual TLS (where clients must also present certificates). For standard one-way TLS remove it entirely.

weewx requires ca_certs to point to a CA bundle. Using the system CA bundle is the most reliable solution and works with any trusted certificate going forward:

For weewx.conf:

ca_certs = /etc/ssl/certs/ca-certificates.crt (instead of any of the Letsencrypt certificates).

Also, by using the OS's certificate I avoid having to ever update the ca_certs value in weewx.conf.

Remove or comment out tls_version in weewx.conf and let the client negotiate automatically.

The Letsencrypt Deploy Hook Script that I use is:

#!/bin/sh
cp "$RENEWED_LINEAGE/privkey.pem" /etc/pki/tls/exim_tls/exim.key
cp "$RENEWED_LINEAGE/fullchain.pem" /etc/pki/tls/exim_tls/exim.cert
cp "$RENEWED_LINEAGE/fullchain.pem" /etc/mosquitto/certs/fullchain.pem
cp "$RENEWED_LINEAGE/privkey.pem" /etc/mosquitto/certs/privkey.pem
cp "$RENEWED_LINEAGE/cert.pem" /etc/mosquitto/certs/cert.pem
cp "$RENEWED_LINEAGE/chain.pem" /etc/mosquitto/certs/chain.pem
chown Debian-exim:Debian-exim /etc/pki/tls/exim_tls/exim.key /etc/pki/tls/exim_tls/exim.cert
chmod 640 /etc/pki/tls/exim_tls/exim.key
chmod 640 /etc/pki/tls/exim_tls/exim.cert
chown -R mosquitto:mosquitto /etc/mosquitto/certs
chmod 640 /etc/mosquitto/certs/fullchain.pem /etc/mosquitto/certs/privkey.pem /etc/mosquitto/certs/cert.pem /etc/mosquitto/certs/chain.pem
systemctl reload exim4 dovecot mosquitto

I use the Apache plugin for Letsencrypt to generate the certificates used by Apache2 and the Deploy Hook Script sets up everything for Exim4 and Mosquitto.

Helpful Diagnostic Commands

Check what certificate Mosquitto is serving

openssl s_client -connect localhost:8883 -CApath /etc/ssl/certs 2>&1 | grep -E "issuer|subject|Verify|PKEY|sigalg"

Check how many certs are in a PEM file

openssl crl2pkcs7 -nocrl -certfile /etc/mosquitto/certs/fullchain.pem | openssl pkcs7 -print_certs -noout

Check cert details

openssl x509 -in /etc/mosquitto/certs/fullchain.pem -noout -issuer -subject -dates

Watch Mosquitto log

sudo tail -f /var/log/mosquitto/mosquitto.log

Check weewx errors

grep weewx /var/log/syslog | grep -i "mqtt|ssl|error"

Restart services

sudo systemctl restart mosquitto weewx

At this point, this should be considered a bug. ECDSA certs have been around for quite some time, and modern software should support them. It's one thing if the ten-year-old firmware in my APC UPS doesn't support them, but any actively-maintained software should.

3 Likes

I agree. I filed a bug report here:

Actually, Let's Encrypt issues the kind of cert the ACME Client requests. There is no LE default. Certbot's default switched from RSA to ECDSA with V2.0.0 in late 2022. It is now on V5.

Glad you got it all sorted. Hopefully your request to Mosquito for ECDSA will get traction

3 Likes

If you want, you can try my Go-based server: GitHub - Cyberax/lenc-mochi: Mochi MQTT server with Let's Encrypt support. Specifically tailored for running on MikroTik routers. · GitHub

It's a Mochi-based server, with added Let's Encrypt support. I just couldn't stomach setting up yet another world-accessible service in C, so I fixed up the Go-based Mochi server a bit.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.