Home Assistant, MQTT and SSL

Home Assistant, MQTT and SSL

Setting up MQTT broker with SSL, the easy/lazy way.

In my current setup I'm running Home assistant via Docker, all the services/add-ons running share /usr/share/hassio/ subfolders as a mount into the docker container. For ssl this is /usr/share/hassio/ssl, I'm already running NginxProxyManager which handles the certs for HTTP, via LetsEncrypt, for me. So rather than setting it up manually I'm simply going to reuse the cert NginxProxyManager created.

creating the cert

This should be fairly straight forward. Via the webinterface of NginxProxyManager, this should look something like http://192.168.178.x:81/nginx/proxy. Add a proxy host, input the domain name, point it to anywhere, shouldn't really matter. Do keep it enabled otherwise the cert will not be updated.

finding the cert

All cert live in /usr/share/hassio/ssl which is also the path which is mounted to the containers. This means you can actually use certs from other containers!

root@fractal:/home/patrick# ls -alh /usr/share/hassio/ssl/nginxproxymanager/live
total 80K
drwx------ 19 root root 4,0K nov 14 18:24 .
drwxr-xr-x  9 root root 4,0K feb 15 11:55 ..
drwxr-xr-x  2 root root 4,0K feb  3 12:57 npm-1
drwxr-xr-x  2 root root 4,0K feb  3 12:57 npm-2
drwxr-xr-x  2 root root 4,0K feb  3 13:52 npm-3
drwxr-xr-x  2 root root 4,0K feb  3 13:52 npm-4
...

As you can see these are not easily recognised by name, diving into the directory;

root@fractal:/home/patrick# ls -alh /usr/share/hassio/ssl/nginxproxymanager/live/npm-1/
total 12K
drwxr-xr-x  2 root root 4,0K feb  3 12:57 .
drwx------ 19 root root 4,0K nov 14 18:24 ..
lrwxrwxrwx  1 root root   29 feb  3 12:57 cert.pem -> ../../archive/npm-1/cert5.pem
lrwxrwxrwx  1 root root   30 feb  3 12:57 chain.pem -> ../../archive/npm-1/chain5.pem
lrwxrwxrwx  1 root root   34 feb  3 12:57 fullchain.pem -> ../../archive/npm-1/fullchain5.pem
lrwxrwxrwx  1 root root   32 feb  3 12:57 privkey.pem -> ../../archive/npm-1/privkey5.pem

To “easily” check the domain (CN/common name) simply use openssl.

root@fractal:/home/patrick# openssl x509 -noout -subject -in /usr/share/hassio/ssl/nginxproxymanager/live/npm-1/cert.pem 
subject=CN = my.domainname.com

Since we've just created a new one we can simply go by date and get the latest. Please do validate it is the correct one.

Config

Within Home assistant -> supervisor -> Mosquitto Broker -> configuration

Look for and replace or add;

certfile: fullchain.pem
keyfile: privkey.pem

Please note, we omit the /usr/share/hassio, since ssl is mount to /ssl in the container.

Mosquitto is wrapped in a run.sh scripts which checks if the files exist and PREPENDS /ssl/

# Enable SSL if exists configs
if [ -e "/ssl/$CAFILE" ] && [ -e "/ssl/$CERTFILE" ] && [ -e "/ssl/$KEYFILE" ]; then
    echo "$SSL_CONFIG" >> /etc/mosquitto.conf
else
    bashio::log.warning "SSL not enabled - No valid certs found!"
fi

for more info see /usr/share/hassio/addons/core/mosquitto/data/run.sh

So the config becomes:

certfile: nginxproxymanager/live/npm-19/fullchain.pem
keyfile: nginxproxymanager/live/npm-19/privkey.pem

Save, restart the container, and check the log if it comes up AND if the 8883 port is included

Alternatives

Connect to 443 directly

I actually tried this, using MQTT Explorer to connect directly to NginxProxyManager on 443 but this doesn't work.

NginxProxy as a proxy for mqtt

Sadly this isn't as easy as you might think, but you would have to be able to add an additional port to NginxProxyManager. So some clarification, you would need to add the 8883, the MQTT SSL port, to NginxProxyManager docker container. That might not seem that big of an issue, take (for example) Portainer, edit the container, add the port, BUT, with each update (and possibly restart) Home Assistant will remove it again.

WS/WSS

Could we use WS or WSS via NginxProxy alone? Yes of course, will I? NO, I'm going to connect to it from a microcontroller on which I don't intent to implement websocket.