Starting with MQTT protocol and ejabberd MQTT broker
Update January 2022: This tutorial is slightly out of date. In case of problems, please consult the corresponding section in the ejabberd documentation: MQTT Support.
MQTT stands for Message Queuing Telemetry Transport. It is a simple and lightweight publish/subscribe messaging protocol: MQTT broker sends & relays messages to MQTT clients. It was designed for constrained devices and low-bandwidth, high-latency or unreliable networks. All while attempting to ensure reliability and some degree of assurance of delivery. This makes the protocol ideal for the Internet of Things (IoT). Another good fit are mobile apps where bandwidth and battery power are at a premium.
» Don’t want to manage ejabberd MQTT broker yourself?
ProcessOne experts will make your business instantly connected. Contact us »
ejabberd and MQTT
ejabberd MQTT broker is included in every installation of latest ejabberd versions and is available on port 1883 out-of-the-box. In my first ejabberd tutorial I installed ejabberd on my private server. I didn’t do any additional configuration towards an MQTT broker, so lets see if it’s really there.
To do this test, we need an MQTT client. We can use one of existing the GUI clients like MQTT FX or one of the best CLI clients, Mosquitto. It supports Linux, Windows and macOS. You can easily install it on the macOS using Homebrew with: brew install mosquitto
Subscribe the MQTT client
ejabberd acts as an MQTT broker, so first we need a client to subscribe to receive relayed messages. We do this with the following command on the machine where we installed Mosquitto:
mosquitto_sub -h mqtt.fluux.io -t "test/channel/1" -d
Publish with MQTT client
Once there’s a first subscriber, our ejabberd MQTT broker will relay any message sent from the publisher:
mosquitto_pub -h mqtt.fluux.io -t "test/channel/1" -m "This is a test message"
You will see “This is a test message” appear under the mosquitto_sub
process. However, mqtt.fluux.io
is a public MQTT broker, not my private server, meaning anyone can publish, subscribe and intercept messages. It’s not really meant for production.
ejabberd MQTT broker initial configuration doesn’t allow unauthorized connections, which is good. To connect, we need to use a username and password that’s already registered on our ejabberd server.
Subscribe and publish to MQTT broker with authenticated user
Lets first go to the ejabberd admin console, which is at example.com:5443/admin
if we assume the configuration from my tutorial series. Lets create a new user, broker@example.com
. Then, we need to add this user to the ACL in our ejabberd configuration file:
acl:
...
publisher:
user:
- "broker@example.com"
subscriber:
user:
- "broker@example.com"
Finally, we need to let mod_mqtt
know who can interact with our ejabberd MQTT broker:
mod_mqtt:
access_publish:
"#":
- allow: publisher
- deny
access_subscribe:
"#":
- allow: subscriber
- deny
Here we specify to let the publishers and subscribers, defined earlier in ejabberd ACL, have access to any channel. We block access to all channels for any unauthenticated connections. To test this, start the subscriber again with broker@example.com
and its password:
mosquitto_sub -h example.com -t "test/channel/1" -u broker@example.com -P ******* -d
In another window, lets publish a test message:
mosquitto_pub -h example.com -t "test/channel/1" -m "This is a test message" -u broker@example.com -P *******
The subscriber process should display the published message. However, we still have all these MQTT messages coming and going in cleartext, unencrypted. To make it even more secure, lets set up TLS encryption for our MQTT broker.
Configure MQTT broker TLS encryption in ejabberd
There are two ways to do this. You can either create a new listener on another port, and keep the cleartext 1883 open. Or, as I prefer, simply add tls: true
to the existing mod_mqtt
listener:
listen:
...
-
port: 1883
module: mod_mqtt
backlog: 1000
tls: true
This configuration will use your existing global certificate files to encrypt the mod_mqtt
connections with TLS. To be able to connect our subscribers and publishers to the TLS encrypted MQTT broker, we need to let them know which certificate to use.
First, download the certificate files your ejabberd MQTT broker is using. These are the files defined at the top of your ejabberd configuration file in certfiles
section. Then, download the latest cacert.pem. Finally, supply these certificates to the subscriber and publisher:
mosquitto_sub -h example.com -t "test/channel/1" -u broker@example.com -P ******* -d -p 1883 --cafile /path/to/cacert.pem --cert /path/to/ejabberd/fullchain.pem --key /path/to/ejabberd/privkey.pem
mosquitto_pub -h example.com -t "test/channel/1" -m "This is a test message" -u broker@example.com -P ******* -p 1883 --cafile /path/to/cacert.pem --cert /path/to/ejabberd/fullchain.pem --key /path/to/ejabberd/privkey.pem
You should see the test message appear under the subscriber process.
What can we do with ejabberd MQTT broker?
To conclude, thanks to ejabberd we now have a powerful XMPP server running together with a scalable MQTT broker. Connections on both protocols are TLS encrypted and limited to authenticated users. We have the capability to chat one-to-one, operate one-to-many multi-user chatrooms and interconnect publish-subscribe many-to-many client networks.
It’s an especially interesting setup to create interactions between digital and physical world. Next time, we will try to send MQTT messages based on XMPP events. But why? Well, for example, we could control MQTT IoT devices via commands sent to a chat with an XMPP bot assistant. And the bot could talk back to us about the events at our home. The possibilities are endless!
In this ejabberd tutorial series:
- How to move the office to ejabberd XMPP server
- How to set up ejabberd video & voice calling (STUN/TURN)
- How to configure ejabberd to get 100% in XMPP compliance test
- Check ejabberd XMPP server useful configuration steps
- Starting with MQTT protocol and ejabberd MQTT broker
- Getting started with WebSocket API in ejabberd
- Install and configure MariaDB with ejabberd
- Publish-Subscribe pattern and PubSub in ejabberd