Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
VerneMQ can be installed on CentOS-based systems using the binary package we provide.
Once you have downloaded the binary package, execute the following command to install VerneMQ:
or:
Once you've installed VerneMQ, start it on your node:
You can verify that VerneMQ is successfully installed by running:
If VerneMQ has been installed successfully vernemq
is returned.
Now that you've installed VerneMQ, check out How to configure VerneMQ.
As well as being available as packages that can be installed directly into the operating systems, VerneMQ is also available as a Docker image. Below is an example of how to set up a couple of VerneMQ
Somtimes you need to configure a forwarding for ports (on a Mac for example):
This starts a new node that listens on 1883 for MQTT connections and on 8080 for MQTT over websocket connections. However, at this moment the broker won't be able to authenticate the connecting clients. To allow anonymous clients use the DOCKER_VERNEMQ_ALLOW_ANONYMOUS=on
environment variable.
Warning: Setting allow_anonymous=on
completely disables authentication in the broker and plugin authentication hooks are never called! See more information about the authentication hooks here.
This allows a newly started container to automatically join a VerneMQ cluster. Assuming you started your first node like the example above you could autojoin the cluster (which currently consists of a single container 'vernemq1') like the following:
(Note, you can find the IP of a docker container using docker inspect <CONTAINER_NAME> | grep \"IPAddress\"
).
To check if the above containers have successfully clustered you can issue the vmq-admin
command:
Set the time in seconds after a QoS=1 or QoS=2
message has been sent that VerneMQ will wait before retrying when no response is received.
This option default to 20
seconds.
This option defines the maximum number of QoS 1 or 2 messages that can be in the process of being transmitted simultaneously.
Defaults to 20
messages, use 0
for no limit. The inflight window serves as a protection for sessions, on the incoming side.
The maximum number of messages to hold in the queue above those messages that are currently in flight. Defaults to 1000
. Set to -1
for no limit. This option protects a client session from overload by dropping messages (of any QoS).
Defaults to 1000
messages, use -1
for no limit. This parameter was named max_queued_messages
in 0.10.*
. Note that 0
will totally block message delivery from any queue!
This option specifies the maximum number of QoS 1 and 2 messages to hold in the offline queue.
Defaults to 1000
messages, use -1
for no limit, use 0
if no messages should be stored.
In contrast to the session based inflight window, max_online_messages and max_offline_messages serves as a protection of queues, on the outgoing side.
VerneMQ supports multiple ways to authenticate and authorize new client connections using a database.
VerneMQ supports authentication and authorization using a number of popular databases and the below sections describe how to configure the different databases.
The database drivers are handled using the vmq_diversity
plugin and it therefore needs to be enabled:
The vmq_diversity
plugin makes it possible to extend VerneMQ using Lua. The documentation can be found here.
When using database based authentication/authorization the enabled-by-default file based authentication and authorization are most likely not needed and should be disabled:
You must set allow_anonymous = off
, otherwise VerneMQ won't use the database plugin for authentication and authorization.
In order to use a database for authentication and authorization the database must be properly configured and the auth-data (username, clientid, password, acls) to be present. The following sections show some sample requests that can be used to insert such data.
While the handling of authentication differs among the different databases, the handling of ACLs is roughly identical and make use of a JSON array containing one or many ACL objects per configured client.
The database integrations will cache the ACLs when the client connects avoiding expensive database lookups for each publish or subscribe message. The cache entries are evicted when the client disconnects.
A minimal publish & subscribe ACL JSON object takes the following form:
General ACL
The pattern is a MQTT topic string that can contain MQTT wildcards, but also the template variables %m
(mountpoint), %u
(username), and %c
(client id) which are automatically substituted with the auth data provided.
Publish ACL
The publish ACL makes it possible to control the maximum QoS and payload size that is allowed, and if the message is allowed to be retained.
Moreover, the publish ACL makes it possible to modify the properties of a published message through specifying one or multiple modifiers
. Please note that the modified message isn't re-validated by the ACL.
Subscribe ACL
The subscribe ACL makes it possible to control the maxium QoS a client is allowed to subscribe to.
Like the publish ACL, the subscribe ACL makes it possible to change the current subscription request by returning a custom set of topic/qos pairs. Please note that the modified subscription isn't re-validated by the ACL.
When deciding on which database to use one has to consider which kind of password hashing and key derivation functions are available and required. Different databases provide different mechanisms, for example PostgreSQL provides the pgcrypto
module which supports verifying hashed and salted passwords, while Redis has no such features. VerneMQ therefore also provides client-side password verification mechanisms such as bcrypt
.
There is a trade-off between verifying passwords on the client-side versus on the server-side. Verifying passwords client-side of course means doing the computations on the VerneMQ broker and this takes away resources from other tasks such as routing messages. With hashing functions such as bcrypt
which are designed specifically to be slow (proportional to the number of rounds) in order to make brute-force attacks infeasible, this can become a problem. For example, if verifying a password with bcrypt
takes 0.5 seconds then on a single threaded core 2 verifications/second are possible and using 4 single threaded cores 8 verifications/second. So, the number of rounds/security paramenters have a direct impact on the max number of verifications/second and hence also the maximum arrival rate of new clients per second.
For each database it is specified which password verification mechanisms are available and if they are client-side or server-side.
To enable PostgreSQL authentication and authorization the following need to be configured in the vernemq.conf
file:
PostgreSQL hashing methods:
method
client-side
server-side
bcrypt
✓
crypt
✓
The following SQL DDL must be applied, the pgcrypto
extension is required if using the server-side crypt
hashing method:
To enter new ACL entries use a query similar to the following:
To enable PostgreSQL authentication and authorization the following need to be configured in the vernemq.conf
file:
Notice that if the CockroachDB installation is secure, then TLS is required. If using an insecure installation without TLS, then vmq_diversity.cockroachdb.ssl
can be set to off
.
CockroachDB hashing methods:
method
client-side
server-side
bcrypt
✓
sha256
✓
The following SQL DDL must be applied:
To enter new ACL entries use a query similar to the following, the example is for the bcrypt
hashing method:
For MySQL authentication and authorization configure the following in vernemq.conf
:
MySQL hashing methods:
method
client-side
server-side
sha256
✓
md5*
✓
sha1*
✓
password
✓
It should be noted that all the above options stores unsalted passwords which are vulnerable to rainbow table attacks, so the threat-model should be considered carefully when using these. Also note the methods marked with *
are no longer considered secure hashes.
The following SQL DDL must be applied:
To enter new ACL entries use a query similar to the following, the example uses PASSWWORD
to for password hashing:
Note, the PASSWORD()
hashing method needs to be changed according to the configuration set in vmq_diversity.mysql.password_hash_method
, it supports the options password
, md5
, sha1
and sha256
. Learn more about the MySQL equivalent for those methods on https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html.
The default password
method has been deprecated since MySQL 5.7.6 and not usable with MySQL 8.0.11+. Also, the MySQL authentication method caching_sha2_password
is not supported. This is the default in MySQL 8.0.4 and later, so you need to add: default_authentication_plugin=mysql_native_password
under [mysqld] in e.g. /etc/mysql/my.cnf.
For MongoDB authentication and authorization configure the following in vernemq.conf
:
MongoDB hashing methods:
method
client-side
server-side
bcrypt
✓
Insert the ACL using the mongo
shell or any software library. The passhash
property contains the bcrypt hash of the clients password.
For Redis authentication and authorization configure the following in vernemq.conf
:
Redis hashing methods:
method
client-side
server-side
bcrypt
✓
Insert the ACL using the redis-cli
shell or any software library. The passhash
property contains the bcrypt hash of the clients password. The key is an encoded JSON array containing the mountpoint, username, and client id. Note that no spaces are allowed between the array items.
Note, currently bcrypt version 2a
(prefix $2a$
) is supported.
Welcome to the VerneMQ documentation! This is a reference guide for most of the available features and options of VerneMQ. The Getting Started guide might be a good entry point.
For a more general overview on VerneMQ and MQTT, you might want to start with the introduction.
For downloading VerneMQ see Downloads.
VerneMQ can be installed on Debian or Ubuntu-based systems using the binary package we provide.
Once you have downloaded the binary package, execute the following command to install VerneMQ:
You can verify that VerneMQ is successfully installed by running:
If VerneMQ has been installed successfully Status: install ok installed
is returned.
Once you've installed VerneMQ, start it on your node:
The whereis vernemq
command will give you a couple of directories:
Path
Description
/usr/sbin/vernemq:
the vernemq and vmq-admin commands
/usr/lib/vernemq
the vernemq package
/etc/vernemq
the vernemq.conf file
/usr/share/vernemq
the internal vernemq schema files
/var/lib/vernemq
the vernemq data dirs for LevelDB (Metadata Store and Message Store)
Now that you've installed VerneMQ, check out How to configure VerneMQ.
A quick and simple guide to get started with VerneMQ
VerneMQ is a high-performance, distributed MQTT message broker. It scales horizontally and vertically on commodity hardware to support a high number of concurrent publishers and consumers while maintaining low latency and fault tolerance. To use it, all you need to do is install the VerneMQ package.
Choose your OS and follow the instructions:
It is also possible to run VerneMQ using our Docker image:
If you built VerneMQ from sources, you can add the /bin
directory of your VerneMQ release to PATH
. For example, if you compiled VerneMQ in the /home/vernemq
directory, then add the binary directory (/home/vernemq/_build/default/rel/vernemq/bin
) to your PATH, so that VerneMQ commands can be used in the same manner as with a packaged installation.
To start a VerneMQ broker, use the vernemq start command in your Shell:
A successful start will return no output. If there is a problem starting the broker, an error message is printed to STDERR
.
To run VerneMQ with an attached interactive Erlang console:
A VerneMQ broker is typically started in console mode for debugging or troubleshooting purposes. Note that if you start VerneMQ in this manner, it is running as a foreground process that will exit when the console is closed.
You can close the console by issuing this command at the Erlang prompt:
Once your broker has started, you can initially check that it is running with the vernemq ping command:
The command will respond with pong
if the broker is running or Node <NodeName> not responding to pings
in case it’s not.
As you may have noticed, VerneMQ will warn you at startup when your system’s open files limit (ulimit -n
) is too low. You’re advised to increase the OS default open files limit when running VerneMQ. Read more about why and how in the Open Files Limit documentation.
Set the maximum size for client ids, MQTT v3.1 specifies a limit of 23 characters.
This option default to 23
.
This option allows persistent clients (those with clean_session
set to false
) to be removed if they do not reconnect within a certain time frame.
This is a non-standard option. As far as the MQTT specification is concerned, persistent clients are persisted forever.
The expiration period should be an integer followed by one of h
, d
, w
, m
, y
for hour, day, week, month, and year; or never
:
This option defaults to never
.
Limit the maximum publish payload size in bytes that VerneMQ allows. Messages that exceed this size won't be accepted.
Defaults to 0
, which means that all valid messages are accepted. MQTT specification imposes a maximum payload size of 268435455 bytes.
VerneMQ supports multiple ways to configure one or many MQTT listeners.
Listeners specify on which IP address and port VerneMQ should accept new incoming connections. Depending on the chosen transport (TCP, SSL, WebSocket) different configuration parameters have to be provided. VerneMQ allows to write the listener configurations in a hierarchical manner, enabling very flexible setups. VerneMQ applies reasonable defaults on the top level, which can be of course overridden if needed.
These are the only default parameters that are applied for all transports, and the only one that are of interest for plain TCP and WebSocket listeners.
These global defaults can be overridden for a specific transport protocol listener.tcp.CONFIG = VAL
, or even for a specific listener listener.tcp.LISTENER.CONFIG = VAL
. The placeholder LISTENER
is freely chosen and is only used as a reference for further configuring this particular listener.
Normally, an MQTT broker hosts one single topic tree. This means that all topics are accessible to all publishers and subscribers (limited by the ACLs you configured, of course). Mountpoints are a way to host multiple topic trees in a single broker. They are completely separated and clients with different topic trees cannot publish messages to each other. This could be useful if you provide MQTT services to multiple separated use cases/verticals or clients, with a single broker. Note that mountpoints are configured via different listeners. As a consequence, the MQTT clients will have to connect to a specific port to connect to a specific topic space (mountpoint).
The mountpoints can be configured on the protocol level or configurred or overridden on the specific listener level.
Since VerneMQ 1.5.0 it is possible to configure which MQTT protocol versions as listener will accept.
VerneMQ supports MQTT 3.1, 3.1.1, and 5.0 (since VerneMQ 1.6.0). To allow these protocol versions, set:
Here 3,4,5
are the protocol level versions corresponding to MQTT 3.1, 3.1.1 and 5.0 respectively. The default value is 3,4
thus allowing MQTT 3.1 and 3.1.1, while MQTT 5.0 is disabled.
Listen on TCP port 1883 and for WebSocket Connections on port 8888:
An additional listener can be added by using a different name. In the example above the name equals to default
and can be used for further configuring this particular listener. The following example demonstrates how an additional listener is defined as well as how the maximum number of connections can be limited for this listener:
VerneMQ listeners can be configured to accept connections from a proxy server that supports the PROXY protocol. This enables VerneMQ to retrieve peer information such as source IP/Port but also PROXY Version 2 protocol TLS client certificate details if the proxy was used to terminate TLS.
To enable the PROXY protocol for tcp listeners use listener.tcp.proxy_protocol = on
or for a specific listener use listener.tcp.LISTENER.proxy_protocol = on
.
If client certificates are used you can set listener.tcp.proxy_protocol_use_cn_as_username = on
which will overwrite the MQTT username set by the client with the common name from the client certificate before authentication and authorization is performed.
Accepting SSL connections on port 8883:
If you want to use client certificates to authenticate your clients you have to set the following option:
If you use client certificates and want to use the certificates CN value as a username you can set:
Both options require_certificate
and use_identity_as_username
default to off
.
The same configuration options can be used for securing WebSocket connections, just use wss
as the protocol identifier e.g. listener.wss.require_certificate
.
With SSL, you still need to configure authentication and authorization! That is, set allow_anonymous
to off
, and configure vmq_acl and vmq_passwd or your authentication plugin.
The default listener listener.vmq.clustering
is used for distributing MQTT messages among the cluster nodes.
Where should VerneMQ emit the default console log messages (which are typically at info
severity):
VerneMQ defaults to log the console messages to a file, which can specified by:
This option defaults to /var/log/vernemq/console.log
for Ubuntu, Debian, RHEL and Docker installs.
The default console logging level info
could be setting one of the following:
VerneMQ log error messages by default. One can change the default behaviour by setting:
VerneMQ defaults to log the error messages to a file, which can specified by:
This option defaults to /var/log/vernemq/error.log
for Ubuntu, Debian, RHEL and Docker installs.
VerneMQ log crash messages by default. One can change the default behaviour by setting:
VerneMQ defaults to log the crash messages to a file, which can specified by:
This option defaults to /var/log/vernemq/crash.log
for Ubuntu, Debian, RHEL and Docker installs.
The maximum sizes in bytes of inidividual messages in the crash log defaults to 64KB
but can be specified by:
VerneMQ rotate crash logs. By default, the crash log file is rotated at midnight or when the size exceeds 10MGB
. This behaviour can be changed by setting:
The default number of rotated log files is 5 and can be set with the option:
VerneMQ supports logging to SysLog, enable it by setting:
Logging to SysLog is disabled by default.
VerneMQ uses Google's LevelDB as a fast storage backend for messages and subscriber information. Each VerneMQ node runs its own embedded LevelDB store.
There's not much you need to know about LevelDB and VerneMQ. One really important thing to note is that LevelDB manages its own memory. This means that VerneMQ will not allocate and free memory for LevelDB. Instead you'll have to configure a configuration value in vernemq.conf that tells LevelDB how much memory it can use up.
Configuring LevelDB memory:
LevelDB means business with its allocated memory. It will eventually end up with the configured max, making it look like there's a memory leak, or even triggering OOM kills. Keep that in mind when configuring the percentage of RAM you give to LevelDB.
Many aspects of VerneMQ can be extended using plugins. The standard VerneMQ package comes with several official plugins. You can show the enabled & running plugins via:
The command above displays all the enabled plugins together with the hooks they implement:
This enables the ACL plugin. Because the vmq_acl
plugin is already started the above command won't succeed. In case the plugin sits in an external directory you must also to provide the --path=PathToPlugin
.
To make a plugin start when VerneMQ starts they need to be configured in the main vernemq.conf
file.
The general syntax to enable a plugin is to add a line like plugins.pluginname = on
, using the vmq_passwd
plugin as an example:
And if the plugin is external the path can be specified like this:
Plugin specific settings can be configured via myplugin.somesetting = value
, like:
See the vernemq.conf
file for details.
VerneMQ supports the WebSocket protocol out of the box. To be able to open a WebSocket connection to VerneMQ, you have to configure a WebSocket listener or Secure WebSocket listener in the vernemq.conf
file first:
Keep in mind that you'll use MQTT-over-WebSocket, so you will need a Javascript library that implements the MQTT client behaviour. We have used the as well as
You won't be able to open WebSocket connections on a base URL, always add the /mqtt
path.
Working with shared subscriptions
A shared subscription is a mechanism for distributing messages to a set of subscribers to shared subscription topic, such that each message is received by only one subscriber. This contrasts with normal subscriptions where each subscriber will receive a copy of the published message.
A shared subscription is on the form $share/sharename/topic
and subscribers to this topic will receive messages published to the topic topic
. The messages will be distributed according to the defined distribution policy.
When subscribing to a shared subscription using command line tools remember to quote the topic as some command line shells, like bash
, will otherwise expand the $share
part of the topic as an environment variable.
Currently three message distribution policies for shared subscriptions are supported: prefer_local
, random
and local_only
. Under the random
policy messages will be published to a random member of the shared subscription, if any exist. Under the prefer_local
policy messages will be delivered to a random node-local member of the shared subscription, if none exist, the message will be delivered to a random member of the shared subscription on a remote cluster node. Under the local_only
policy message will be delivered to a random node-local member of the shared subscription.
When a messages is being delivered to subscribers of a shared subscription, the message will be delivered to an online subscriber if possible, otherwise the message will be delivered to an offline subscriber. Notice that the shared subscription policy is applied before considering online or offline status of clients.
Note that Shared Subscriptions still fully operate under the MQTT specification (be it MQTT 5.0 or backported to older protocol versions). Be aware of this, especially regarding QoS and clean_session configurations.
Subscriptions Note: When subscribing to a shared topic, make sure to escape the $
So, for dash or bash shells
Publishing Note: When publishing to a shared topic, do not include the prefix $share/group/
as part of the publish topic name