ELXSoftware

ELX-MQTT Broker

Documentation

Everything from the first launch to bridging two installations together. The same text is available offline inside the broker itself.

Installation

The broker is one executable. On Linux the Debian package additionally registers a systemd unit, creates the working directory and starts the service; on Windows the file runs from wherever you put it.

Debian / Ubuntu, amd64
wget https://elxsoftware.com/download/elxmqttbroker-linux-amd64
sudo install -m 755 elxmqttbroker-linux-amd64 /usr/local/bin/elxmqttbroker
sudo elxmqttbroker --install-service
sudo systemctl enable --now elxmqttbroker

For 32-bit and 64-bit ARM boards the procedure is identical — take arm64 or armhf instead. uname -m tells you which one the board is: aarch64 means arm64, armv7l means armhf.

Windows
Run the installer, or unpack the portable build and start elxmqttbroker.exe.
The dashboard opens at http://127.0.0.1:8567
Default credentials: admin / admin
Change the password before exposing anythingThe first account is admin / admin so that the first launch works without configuration. Change it in the dashboard before the machine becomes reachable from anywhere but your desk.

The first launch

  1. Open http://<address>:8567 and sign in.
  2. Change the administrator password in the profile menu.
  3. Create a user for your devices in Users and give it the topics it needs — the permission list is empty at first, and an empty list means no access.
  4. Connect one client and watch it appear in Clients: that confirms the address, the port and the credentials in one step.
  5. Publish a test message from Publish and check that the subscriber receives it.
If a client cannot connectThe event feed on the dashboard states the reason — wrong credentials, a refused topic, a protocol version mismatch or a TLS error. It is faster than reading the client's own logs.

Users and permissions

Every account carries a list of rules. A rule is a topic filter, an access type — subscribe, publish or both — and a verdict: allow or deny. Nothing is permitted that is not stated: an account with no rules can connect and do nothing.

RuleMeaning
sensors/# · subscribe · allowMay read the whole sensors branch
sensors/kitchen/+ · publish · allowMay write to any topic one level under kitchen
devices/$u/# · both · allowMay do anything inside its own branch, and nothing outside it
# · both · denyExplicitly refuses everything not allowed above

The $u placeholder expands to the account name at connection time. One rule therefore serves a thousand devices without a thousand rules: each device sees only its own subtree.

Order mattersRules are evaluated top to bottom and the first match wins. A broad deny placed above a narrow allow hides it entirely — that is the usual reason a permission “does not work”.

Where credentials come from

The broker can keep its own account list, or ask something else. The source is switched live, without a restart, so you can test a new backend while the old one is still serving.

  • Built-in. Accounts stored in the broker's own database. Right for a few dozen devices.
  • MariaDB / MySQL. A table you already have, with the query written in the settings. Right when a device inventory already exists elsewhere.
  • SQLite. A file with the same shape, for a system that keeps its data locally.
  • CSV. A plain file, re-read on change. Convenient for a fixed list produced by another tool.
  • JWT. The device presents a signed token instead of a password; the broker verifies the signature and reads the permissions from the claims.
  • HTTP. The broker asks your service whether this client may connect, and your service answers. Everything you already implement — device blocking, tariffs, quotas — applies without duplication.

TLS

Point the broker at a certificate and a key and the encrypted listener starts on port 8883; the dashboard can use the same pair. For a closed network the broker can generate a self-signed pair itself, which is enough to keep passwords off the wire.

Checking the certificate from the command line
openssl s_client -connect broker.example.com:8883 -servername broker.example.com </dev/null | head -20
Self-signed certificates and clientsA client that validates certificates will refuse a self-signed one until it is told to trust it. Either add the certificate to the client's trust store or use a real certificate — turning validation off entirely removes the point of using TLS.

Bridges

A bridge is a permanent connection to another broker with a list of topics to carry. Direction is per topic: out pushes local messages outward, in pulls remote messages in, both does both.

  • A prefix can be added on either side, so that messages from a remote site arrive under site-b/… and never collide with local ones.
  • Loop protection stops a message that came in through a bridge from being sent straight back out.
  • A dropped connection is retried with a growing delay; the queue keeps going in the meantime.
  • TLS and credentials are configured per bridge, so two sites can use different certificates.
Bridge or shared network?A bridge joins two brokers over the public internet with an explicit list of what crosses. If instead you want the machines themselves to be on one network, that is a different tool — see ELX-VNetwork.

Delayed publish

Publishing to $delayed/<seconds>/<topic> hands the broker a message to deliver later. The message is stored, survives a restart, and appears in the dashboard where it can be cancelled before it fires.

Turn the light off in five minutes
mosquitto_pub -h broker -t '$delayed/300/home/light/kitchen' -m 'off'

The syntax matches EMQX, so scripts written for that broker work unchanged.

Rate limits

Two mechanisms, aimed at different problems. A per-connection token bucket stops one client from flooding the broker. Per-topic rules deal with a device that is merely too enthusiastic: instead of disconnecting it, they thin the stream to a rate and keep the most recent value.

RuleEffect
sensors/+/raw · 1 per secondAt most one message a second per topic; the newest wins
debug/# · dropDiscarded at the broker, subscribers never see it
Connection · 200 per secondA client exceeding it is throttled, then disconnected

REST API

The dashboard is a client of the same API you can use. Create a token in the settings, choose whether it may write, and call it from your own system.

Creating a device account from a script
curl -X POST https://broker.example.com/api/users \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{"name":"sensor-42","password":"...","acl":[{"filter":"devices/sensor-42/#","access":"both","allow":true}]}'
Read-only tokensA monitoring system needs statistics, not the ability to delete users. Issue it a read-only token and the question does not arise.

What survives a restart

  • Retained messages — the last value of every topic that asked to be retained.
  • Persistent sessions — subscriptions of clients that connected with clean_session off.
  • Offline queues — QoS 1 and 2 messages for those sessions while the client is away.
  • Delayed messages that have not fired yet.
  • Users, permissions, bridges, rules and settings.

All of it lives in one SQLite file. Backing the broker up means copying that file; moving it to another machine means copying it there.

When something is wrong

SymptomWhere to look
Client connects, then disconnects immediatelyCredentials, or a permission list that denies everything. The event feed names the reason.
Messages are published but nobody receives themThe publisher's permissions allow writing but the subscriber's do not allow reading that filter.
Retained value does not come back after a restartPersistence is disabled, or the working directory is not writable by the service user.
A device reconnects in a loopTwo clients are using the same client identifier — each connection kicks the other off.
TLS client reports a certificate errorA self-signed certificate that the client does not trust, or a hostname that does not match the certificate.
The dashboard is unreachable from another machineThe dashboard is bound to the loopback address; change the bind address in the settings.

Frequently asked questions

Where is the log?
On Linux, journalctl -u elxmqttbroker -f. On Windows, the console window, or the log file next to the executable when it runs as a service.
How do I move the broker to another machine?
Stop the service, copy the SQLite file and the certificates, start the broker on the new machine. Clients only need the new address.
Can two brokers share one database?
No. Each broker owns its file. To join two installations, use a bridge — that is what bridges are for.
Does the dashboard have to be exposed to the internet?
No, and preferably not. Bind it to the internal address and reach it over a private network or an SSH tunnel.

Nearby programs