Any tips how to secure, client-cert authentication, with MQTT inside HA?

I’m having serious challenges getting MQTT to be secure. I’m certain it’s configuration issues, or my misunderstanding of HA, but here’s where I am at.

  • For router-related reasons, I can’t (yet) expose HA to the internet, so LetsEncrypt isn’t yet an option.
  • I want a vanilla MQTT setup with TLS, i.e., self-signed CA, server key/cert, and then to be able to use client key/cert pairs to publish from assorted devices.
  • When I put a full chain (concatenated server cert, CA cert) in, with the server key, and CA cert, attempts to connect with openssl s_client -connect homeassistant.local:8883 still fail with verify error:num=18:self-signed certificate errors – don’t know how to overcome that. Yes, the CA is self-signed, but it’s also explicitly set as the cafile.
  • When I attempt to re-configure, and drop in my client certificate and key, I get an error “Invalid private key, ensure a PEM coded file is supplied without password” – except, the client key is supplied without a password.
  • Except sometimes I manage to get past that (no idea how!) and if I do, I get “Failed to connect” messages without much guidance.

I’ve looked at a whole range of recipes, what I could really use is some simple guide as to how to get MQTT working with a custom CA, server cert, and implementing client certificate authentication.

I have done this before (successfully) with Mosquitto directly, but here, there’s no access to the plain Mosquitto config, I’m having to work through the YAMLs and I really don’t know how that gets pushed into any underlying Mosquitto setup.

If I can get this working I am happy to make it into some documentation, because right now that’s a little lightly covered.

An update. I’ve managed to get the broker working, but slightly oddly, and only from outside HA. Internally, I cannot get the integration configured to work.

I’m not completely sure what was wrong – it may be some unusual authentication behaviours that only made it look like it was out of whack – and in particular the fact that even when requiring client certificates, a username and password are also required – this is not usual for MQTT in my limited experience. The add-on config is more or less as follows:

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

I was hoping the use_identity_as_username would work, but it doesn’t. There does not seem to be any way for HA to allow the certificate to provide the identity, as is normal. This means, as far as I can tell, there is no way to dispense with the password. You always seem to need a username and password, even if you also use a client certificate. This feels to go against the whole point of a client certificate.

However, whatever I do, I cannot connect from the integration. I can’t get the YAML for that as it never actually configures, but essentially I use:

  • Broker: core-mosquitto
  • Port: 8883
  • User: mqtt
  • Password:
  • Advanced > user a client certificate: true
  • Advanced > client certificate: client.crt
  • Advanced > client key: client.key
  • Advanced > broker certificate validation: custom
  • Advanced > CA: ca.crt

When I try to configure, I always get Failed to connect

However, from a command line, I can do:

mosquitto_pub -d -h homeassistant.local -p 8883 -t '/test' -m 'helloWorld' -u mqtt -P '[redacted]' --cafile roles/ssl/files/ca.crt --cert roles/ssl/files/client.crt --key roles/ssl/files/client.key

And this not only connects, it authenticates and publishes. So the settings seem correct for MQTT.

After the attempt to configure, the log from the addin contains the following lines:

2023-10-08 15:04:01: New connection from 172.30.32.1:34429 on port 8883.
2023-10-08 15:04:01: OpenSSL Error[0]: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
2023-10-08 15:04:01: Client <unknown> disconnected: Protocol error.

However, I uploading the exact same files that I am using with mosquitto_pub, so they do work okay.

It genuinely feels like there’s something off with the usage of client certs with MQTT.