Skip to content

Mosquitto Mon Amour

krahabb edited this page Nov 16, 2021 · 2 revisions

This is a simple guide showing my own MQTT environment which 'works' reliably since the beginning. I've decided to document it since there's a lot of 'pain' when you're down trying to setup Meross devices on local MQTT. This is especially true for HASSIO addon which, beside mosquitto own behaviour, adds up with it's own 'special' configuration environment, authentication and so (which I don't know at all).

A couple of considerations about this guide and the issues I've encountered:

  • This is not for HASSIO MQTT addon configuration (there's a nice trouble-thread here)
  • This is for a Raspbian (Buster) environment with HA core installed over python/venv (but should work with any HA flavour even HASSIO)
  • This setup is 'unauthenticated': no need to configure device user/password pair -> love it or hate it
  • I don't have any other mqtt appliances around so my environment is very simple. Read about 'mqtt listeners' in order to allow independent configurations for multiple device families.
  • It happened that blindling upgrading packages through 'apt upgrade' broke my mosquitto, I've then put it on 'hold' (in apt terms) since I didn't have the time to investigate issues and so, but now I'm running on the latest 2.0.11 mosquitto version without issues. In my experience mosquitto is still a bit 'unstable' so to say especially on config behaviour so you should expect basic/default policies to maybe change through versions.

Steps

Mosquitto installation

I've added the official mosquitto package repos to my apt so to peek the latest 'bleeding edge' versions since the default raspbian packages for mosquitto are usually a bit 'seasoned' (official guide to perform these steps here)

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-buster.list
sudo apt-get update
sudo apt-get install mosquitto

If your raspbian is not 'buster' change the *.list to the appropriate distro

Certificates

After installing mosquitto, you have to create a CA and a self-signed certificate to run TLS on the broker (original guide here):

openssl genrsa -des3 -out ca.key 2048
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

##Create the certificate signing request. It's important when asked for the FQDN in these next step to use the IP or domain name of the machine your MQTT instance is on.

openssl genrsa -out server.key 2048
openssl req -new -out server.csr -key server.key

##Create the final certificate

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

My personal notes on certificate creation: if you can, use a static IP for your broker and set this as the CN/FQDN when issuing the certificate request. Also, set a long (I've used 3650 days) expiration date else you'd need to update/reissue your certs sooner than later

Mosquitto configuration

I left the original mosquitto.conf as is and gone through adding my custom configuration files in /etc/mosquitto/conf.d. My /etc/mosquitto/mosquitto.conf is nevertheless (should be like the original though):

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.gz

pid_file /run/mosquitto/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

I've then split up my configuration in 3 files (but you could aswell place everything in just 1). This is to easily identify every 'listener' configuration from the directory structure. Keep in mind that, if you split the configuration, mosquitto will load these files in a certain order (alphabetical case sensitive) and it is important to have the 'main' file loaded first since it contains the 'key' configuration which allowed me to overcome authentication subtleties (read on to understand why).

'main' configuration

I use it to provide general settings valid for every listener. Place it in /etc/mosquitto/conf.d/0000.conf

per_listener_settings true

'default' listener

This is the unencrypted, standard, MQTT broker configuration on port 1883. I use this listener to connect HA (no encription since both runs on the same machine and traffic is not exposed then). I've just added the login HA uses to access the broker. Place it in /etc/mosquitto/conf.d/1883.conf

listener 1883
allow_anonymous false
password_file /etc/mosquitto/conf.d/password

'meross' listener

This is the MQTT endpoint used by my Meross devices. I've set it up on port 8883 following the common practice for MQTT/Tls but you can bind it to any port since the devices allow themselves to set a broker port together with the address. The important part here is that Meross devices use Tls so they want a Tls'ed broker. Place it in /etc/mosquitto/conf.d/8883.conf

listener 8883
allow_anonymous true
require_certificate false
use_username_as_clientid true
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key

As a last step I've created a user/password for HA to login to mosquitto and placed it in /etc/mosquitto/conf.d/password. More or less like (sudo might be needed I don't remember):

mosquitto_passwd /etc/mosquitto/conf.d/password hamosquittouser

If I'm not missing anything this could be it. I've gone through these steps a couple months ago so I might not remember every single detail but this is the idea. Continue reading in order to understand where I've encountered issues and how I faced them.

Issues

The main issue with Meross MQTT configuration is the authentication. Provided the certificate setup is correct (my openssl-self-signed worked since the beginning). When they 'log' into the broker they present themselves with user and password so mosquitto tries to authenticate them through its own mechanisms. The basic 'password file' in place doesn't allow for ':' in usernames (and passwords I guess) so you can't authenticate Meross through mosquitto password file. You'd need an authentication plugin (like https://github.com/pvizeli/mosquitto-auth-plug but I don't know anything about it except its existence). Now, in my setup I had to provide a dedicated listener to meross in order to overcome this and avoid any authentication issue (yes, whoever could connect to my broker, at least the one on port 8883). The key to ignore authentication is to tell mosquitto no password_file and no auth_plugin for the listener and allow_anonymous. In this scenario you can't mix authenticated and unauthenticated devices: that's why I went down the easy road to provide another 'standard' listener on port 1883 for HA to let it authenticate independently from the other listener settings

Mosquitto listeners

So this is the answer to (some of) your MQTT pains: plan your mosquitto environment with listeners in mind so it's like having different brokers setup all sharing the same message flow but with dedicated interfacing requirements: You can for instance set it up like:

  • default listener (on port 1883) for devices only supporting non-Tls traffic with or without authentication
  • encrypted listener (on port 8883) for devices requiring/allowing Tls communication with authentication
  • 'meross' listener (on port 2003) for meross devices setting it up like my previous config (without authentication)

Mid-Term considerations

This should be 'finals considerations' but as far as it goes I know it won't. Setting up my own mosquitto environment proved to be easier to manage than the HASSIO addon. Still HASSIO is so pervasive that this couldnt be a solution for everyone but I think this knowledge could be partially 'ported' to HASSIO official addon in order to succesfully play with it. I'm totally unaware tho of how this addon works but I know you can customize the mosquitto conf in some way so that shouldnt be impossible. Also, I understand from the issues threads that mosquitto ACLs could be in place there and that could pose another level of management to investigate but I'm not sure