Search code examples
lets-encryptmosquittoclient-certificates

mosquitto broker with ssl LetsEncrypt certificate and self signed client certificate


I read already about this but I am not sure I got it correctly.

The situation is I have LetsEncrypt certificates for ssl for my duckdns server.

I wanted to reuse it for a mosquitto server as well, I configured it as

listener 8884

allow_anonymous false
password_file /mosquitto/config/passwords
certfile /mosquitto/ssl/live/xxxxxx.duckdns.org/fullchain.pem
keyfile /mosquitto/ssl/live/xxxxxx.duckdns.org/privkey.pem
tls_version tlsv1.2

where the certfile and keyfile are the ones generated by LetsEncrypt. This works as expected.

Now to expose it to the web though, I'd rather use client certificates. For what I understood, I should use then a "private" CA, otherwise any certificate signed by LetsEncrypt would do as a valid client.

So I added to the configuration the following lines

require_certificate true
use_identity_as_username true
cafile /mosquitto/certs/ca.crt

Where ca.crt is a certificate I generated with

openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt

and with it generated a client certificate using

openssl genrsa -out keyfile.key 4096
openssl req -new -key keyfile.key -out keyfile.csr
openssl x509 -req -days 36500 -in keyfile.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out keyfile.crt

I checked that the client certificate is correctly signed using openssl verify. Now by calling

 mosquitto_pub --cafile /mosquitto/certs/ca.crt --key keyfile.key --cert keyfile.crt -h xxxxxx.duckdns.org -p 8884 -t broker/hello -m "online"

I get a TLS error and in mosquitto logs I see

OpenSSL Error[0]: error:1404A418:SSL routines:ST_ACCEPT:tlsv1 alert unknown ca

I suppose I'm mixing up things with the server certificate and the client certificate having different CAs, though I'm not getting where I'm doing it wrong and how to reach the goal.

Any help or hint on what's wrong in my operations, is appreciated.


Solution

  • The problem is the CA cert you've passed to the mosquitto_pub command.

    mosquitto_pub uses the ca cert passed to it to verify the certificate the broker presents to authenticate it's self, so it should point to somewhere that has the Let's Encrypt root CA. The CA cert should not be linked to the cert/key the client uses to authenticate.

    So you should probably be pointing it at the system CA cert bundle e.g.

    mosquitto_pub --capath /etc/ssl/certs --key keyfile.key --cert keyfile.crt -h xxxxxx.duckdns.org -p 8884 -t broker/hello -m "online"