Skip to main content
Version: Mosquitto 2.8

Security

Security measures must be set on the client or publisher side.

![NATcommunication] (./_images//NATcommunication.png)

For example, a MQTT client is located after a router, using the NAT (Network Address Translation) to transmit from a private network address to a public address.

![bidirectionalPublishing] (./_images//bidirectionalPublishing.png)

Client sessions are protected with username/password through authentication.

After authentication, access to resources can be controlled with username as well.

But it's very important to know that the broker only delivers packets, therefore the broker does not encrypt the packet including username and password - the client must set security measurements.

Use the per_listener_settings to control whether passwords are required globally or on a per-listener basis.

Ports:

  • The default secured MQTT broker port is 8883.

  • The standard unsecure port is 1883.

Read more about Authentication: [Here] (NEW_mosquitto-configuration.md). And [here] (NEW_subscribing.md). And [here] (./mqtt).

Authorization

TCP is embedding TLS (Transport Layer Security). Allowing MQTT packets to be transmitted via encrypted pipes.

![tcpTLS] (./_images//tcpTLS.gif)

TLS protects all parts of an MQTT packet, not only the payload.

Encrypting just the payload is also able. But again, encrypting a payload is done at the application level, not the broker.

Following encrypted payloads can be sent without broker configuration needed.

The broker just delivers packets.

![brokerHandlingSubscriptions] (./_images//brokerHandlingSubscriptions.gif)

Subscribing clients on the other end must be able to decrypt the payload.

The TCP security and any kind of packet encryption are recommended to be dealt with by the Load Balancer, before handing off the incoming packet to the broker.

Implementing TLS and maintaining the structure, requires in-depth knowledge support.

Server Side TLS

Using Transport Layer Security (TLS) provides a secured communication channel a client and a server can use to connect.

TLS is a cryptographic protocol, that uses a handshake mechanism to create a secure connection between client and server.

![tlsHandshake] (./_images//tlsHandshake.jpg)

An encrypted communication between client and server is established, after the handshake is completed. Servers use X509 certificates.

A client uses the certificate to verify the identity of the server.

![broker] (./_images//broker.gif)

TCP/IP is not safe on its own.

TCP packets lead through many infrastructure components (routers, firewalls, etc.) before reaching the target.

Every participant of the transfer is able to read the packet and its content. Just like reading a unsecured text file. It is even possible to manipulate the text.

Make sure to establish a secured setup.

TLS is all about providing a secure communication channel. TLS ensures that the content of your communication can not be read or altered by third parties. Assuming secure cipher suites are used and there are no undiscovered attacks on the TLS version used.

MQTT relies on TCP (Transmission Control Protocol). You must set encryption yourself, as TCP connections do not use an encrypted communication by default.

Depending on the level of security you should consider to use TLS to secure your setup. Maybe other security measurements meet your requirements as well.

Port 8883

Port 8883 is the standard port for secured MQTT connections. It is exclusively reserved for MQTT using TLS.

Bandwidth isn't impacted so much by using TLS, but it does require more CPU power, particularly when a new connection is established. As the usage of TLS brings along workload more CPU power is required. Still the Mosquitto broker, as it is the most efficient on the market, is the most likely choice to run in a highly secured environment setup with low bandwidth.

Whenever overhead in CPU and low bandwidth is not a problem for your setup, you should always choose to use high security measurements.

Using TLS with MQTT is highly recommended. But be aware of the possibility of overhead.

There are different versions of TLS available. Always make sure to use the actual version.

In order to avoid so called "Man-in-the-middle attacks" validate x509 certificates before using them. Please make sure your client is doing this by default to avoid mistakes and further attacks.

Other security mechanisms such as payload encryption, payload signature verifications, and authorization mechanisms can be added to your package of security.

Certificate based TLS Support

  • cafile file path

cafile is used to define the path to a file containing the PEM encoded CA certificates that are trusted when checking incoming client certificates.

  • certfile file path

Path to the PEM encoded server certificate. This option and keyfile must be present to enable certificate based TLS encryption.

The certificate pointed to by this option will be reloaded when Mosquitto receives a SIGHUP signal. This can be used to load new certificates prior to the existing ones expiring.

  • ciphers_tls1.3 cipher:list

The list of allowed ciphersuites for this listener, for TLS v1.3, each separated with a colon.

  • crlfile file path

If you have require_certificate set to true, you can create a certificate revocation list file to revoke access to particular client certificates. If you have done this, use crlfile to point to the PEM encoded revocation file.

  • dhparamfile file path

To allow the use of ephemeral DH key exchange, which provides forward security, the listener must load DH parameters. This can be specified with the dhparamfile option. The dhparamfile can be generated with the command e.g.

  • keyfile file path

Path to the PEM encoded server key. This option and certfile must be present to enable certificate based TLS encryption.

The private key pointed to by this option will be reloaded when Mosquitto receives a SIGHUP signal. This can be used to load new keys prior to the existing ones expiring.

  • require_certificate [ true | false ]

By default an TLS enabled listener will operate in a similar fashion to a https enabled web server, in that the server has a certificate signed by a CA and the client will verify that it is a trusted certificate. The overall aim is encryption of the network traffic. By setting require_certificate to true, a client connecting to this listener must provide a valid certificate in order for the network connection to proceed. This allows access to the broker to be controlled outside of the mechanisms provided by MQTT.

  • tls_engine_kpass_sha1 engine_kpass_sha1

SHA1 of the private key password when using an TLS engine. Some TLS engines such as the TPM engine may require the use of a password in order to be accessed. This option allows a hex encoded SHA1 hash of the password to the engine directly, instead of the user being prompted for the password.

  • tls_keyform [ pem | engine ]

Specifies the type of private key in use when making TLS connections. This can be "pem" or "engine". This parameter is useful when a TPM module is being used and the private key has been created with it. Defaults to "pem", which means normal private key files are used.

  • tls_version version

Configure the minimum version of the TLS protocol to be used for this listener. Possible values are tlsv1.3, tlsv1.2 and tlsv1.1. If left unset, the default of allowing TLS v1.3 and v1.2.

In Mosquitto version 1.6.x and earlier, this option set the only TLS protocol version that was allowed, rather than the minimum.

  • use_identity_as_username [ true | false ]

If require_certificate is true, you may set use_identity_as_username to true to use the CN value from the client certificate as a username. If this is true, the password_file option will not be used for this listener.

This takes priority over use_subject_as_username if both are set to true.

See also use_subject_as_username.

  • use_subject_as_username [ true | false ]

If require_certificate is true, you may set use_subject_as_username to true to use the complete subject value from the client certificate as a username. If this is true, the password_file option will not be used for this listener.

The subject will be generated in a form similar to CN=test client,OU=Production,O=Server,L=Nottingham,ST=Nottinghamshire,C=GB.

See also use_identity_as_username.

  • TCP Connection Support

TCP is embedding TLS (Transport Layer Security). Allowing MQTT packets to be transmitted via encrypted pipes. Cryptology ensures privacy and integrity. Also authenticity with the use of certificates. Implementing TLS and maintaining the structure, requires in-depth knowledge support.

mosquitto_pub supports TLS encrypted connections. It is strongly recommended that you use an encrypted connection for anything more than the most basic setup. Unauthenticated encrypted support is provided by using the certificate based TLS based options certfile and keyfile. Transport Layer Security pre-shared key ciphersuites (TLS-PSK) is a set of cryptographic protocols that provide secure communication based on pre-shared keys (PSKs). These pre-shared keys are symmetric keys shared in advance among the communicating parties.Usually, Transport Layer Security (TLS) uses public key certificates or Kerberos for authentication. TLS-PSK uses symmetric keys, shared in advance among the communicating parties, to establish a TLS connection.

  • set_tcp_nodelay [ true | false ]

If set to true, the TCP_NODELAY option will be set on client sockets to disable Nagle's algorithm. This has the effect of reducing latency of some messages at potentially increasing the number of TCP packets being sent. Defaults to false.

This option applies globally.

Reloaded on reload signal.

Ways to generate PEM files

Generate a private key and certificate signing request. Send the CSR to a commercial Certificate Authority with some money, and the CA sends you a certificate.

Use Lets Encrypt to generate your private key and automatically obtain the certificate.

[Let's Encrypt] (https://letsencrypt.org/de/).

Generate a private key and your own self signed server certificate (clients need the server certificate of each server for checking).

Generate a private key and own self signed certificate to act as a Certificate Authority, then generate a server private key and CSR and sign the server CSR with your CA private key to generate the server certificate (clients need the CA certificate, and this can be used for multiple servers).

Authentication

On an unsecured broker, clients can subscribe to any topic they want. The use of ACLs (Access Control Lists) allows subscriptions to be restricted for different clients, so information can be controlled. The same is true for publishing messages, where only certain clients should be allowed to publish to certain topics, depending on the application.

Note that username/password is authentication, and that use of ACLs and other mechanisms is authorisation.

In some cases, no level of authentication might be without risk. But it's always the end user that has to make up his mind about what level of security has to be chosen and how to implement it.

Access control (ACL) based on client ID, IP address, user name.

Mosquitto supports the permission management of client through client publish/subscribe ACLs.

On an unsecured broker, clients can subscribe to any topic they want. The use of ACLs (Access Control Lists) allows subscriptions to be restricted for different clients, so information can be controlled. The same is true for publishing messages, where only certain clients should be allowed to publish to certain topics, depending on the application.

ClientId or IP address authentication support.

The clientId can be used for authentication. Also you can add the username. The username does not have to be a unique username to use it in a case like this.

The clientId of each client must be unique.

The clientId can be set by the client. But it does not always have to.

Whenever a client session is already existing as a client pleases to connect, the old session is discarded and taken over.

Read more about Clean Start: [Here] (NEW_mosquitto-configuration.md). And [here] (NEW_publishing.md). And [here] (NEW_supported-mqtt-versions.md). And [here] (./mqtt).

Based on a clientId there is always the possibility to rejoin a subscription the client has been disconnected.

The Clean Session flag (MQTT v.3.1.1) or the Session Expiry Interval (MQTT v.5) can tell the broker to preserve information including the subscription information and queued messages.

Non-persistent clients do not have to generate a clientId as there is no use, except for authentication.

Sending a blank clientId to the broker, will have the broker to generate an unique clientId during the session.

  • allow_zero_length_clientid [ true | false ]

MQTT 3.1.1 and MQTT 5 allow clients to connect with a zero length client id and have the broker generate a client id for them. Use this option to allow/disallow this behaviour.

Defaults to true. See also the auto_id_prefix option.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal.

In MQTT v5 the broker is able to inform the client about the generated clientId.

Username / Password

Username

The client username maps to the username provided in the CONNECT packet when a device connects.

![CONNECT] (./_images//CONNECT.png)

The username is unique across the plugin, so attempting to create a client with a duplicate username will result in an error.

The username acts as the primary key if you want to change anything about the client.

When run as root, change to this user and its primary group on startup. If set to "mosquitto" or left unset, and if the "mosquitto" user does not exist, then mosquitto will change to the "nobody" user instead.

If this is set to another value and mosquitto is unable to change to this user and group, it will exit with an error.

The user specified must have read/write access to the persistence database if it is to be written. If run as a non-root user, this setting has no effect. Defaults to mosquitto.

This setting has no effect on Windows and so you should run mosquitto as the user you wish it to run as.

Not reloaded on reload signal.

Password

Password files are a simple mechanism of storing usernames and passwords in a single file.

They are good if you have a relatively small number of fairly static users.

To create a password file, use the mosquitto_passwd utility. You will be asked for the password. Note that -c means an existing file will be overwritten: mosquitto_passwd -c <password file> <username>

Read more about Username: [Here] (NEW_publishing.md). And [here] (NEW_security.md). And [here] (NEW_mosquitto-configuration.md).

  • password_file file path

Set the path to a password file. If defined, the contents of the file are used to control client access to the broker. The file can be created using the mosquitto_passwd utility. If mosquitto is compiled without TLS support (it is recommended that TLS support is included), then the password file should be a text file with each line in the format "username:password", where the colon and password are optional but recommended. If allow_anonymous is set to false, only users defined in this file will be able to connect. Setting allow_anonymous to true when password_file is defined is valid and could be used with acl_file to have e.g. read only guest/anonymous accounts and defined users that can publish.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal. The currently loaded username and password data will be freed and reloaded. Clients that are already connected will not be affected.

To add more users to an existing password file, or to change the password for an existing user, leave out the -c argument:

  • mosquitto_passwd <password file> <username>

To remove a user from a password file:

  • mosquitto_passwd -D <password file> <username>

You can also add/update a username and password in a single line, but be aware that this means the password is visible on the command line and in any command history: mosquitto_passwd <password file> <username> <password>

To start using your password file you must add the password_file option to your configuration file:

  • password_file <path to the configuration file>

The password file must be able to be read by whatever user Mosquitto is running as.

On Linux/POSIX systems this will typically be the mosquitto user, and /etc/mosquitto/password_file is a good place for the file itself.

If you are using the per_listener_settings true option to have separate security settings per listener, you must place the password file option after the listener it is for: listener 1883

  • password_file /etc/mosquitto/password_file

  • per_listener_settings [ true | false ]

If true, then authentication and access control settings will be controlled on a per-listener basis. The following options are affected:

  • password_file

  • acl_file

  • psk_file

  • allow_anonymous

  • allow_zero_length_clientid

  • auto_id_prefix.plugin

  • plugin_opt_*

Note that if set to true, then a durable client (i.e. with clean session set to false) that has disconnected will use the ACL settings defined for the listener that it was most recently connected to.

The default behaviour is for this to be set to false, which maintains the settings behaviour from previous versions of mosquitto.

Reloaded on reload signal.

If you make changes to the password file you must trigger the broker to reload the file by sending a SIGHUP message:

  • kill -HUP <process id of mosquitto>

Read more about [Password] (NEW_publishing.md).

Connection Support

  • allow_zero_length_clientid [ true | false ]

MQTT 3.1.1 and MQTT 5 allow clients to connect with a zero length client id and have the broker generate a client id for them. Use this option to allow/disallow this behaviour.

Defaults to true.

See also the auto_id_prefix option.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal.

  • auth_plugin_deny_special_chars [ true | false ]

If true then before an ACL check is made, the username/client id of the client needing the check is searched for the presence of either a '+' or '#' character. If either of these characters is found in either the username or client id, then the ACL check is denied before it is sent to the plugin.

This check prevents the case where a malicious user could circumvent an ACL check by using one of these characters as their username or client id. This is the same issue as was reported with mosquitto itself as CVE-2017-7650.

If you are entirely sure that the plugin you are using is not vulnerable to this attack (i.e. if you never use usernames or client ids in topics) then you can disable this extra check and hence have all ACL checks delivered to your plugin by setting this option to false.

Defaults to true. Applies to the current authentication plugin being configured.

Not currently reloaded on reload signal.

  • clientid_prefixes prefix

This option is deprecated and will be removed in a future version.

If defined, only clients that have a clientid with a prefix that matches clientid_prefixes will be allowed to connect to the broker. For example, setting "secure-" here would mean a client "secure-client" could connect but another with clientid "mqtt" couldn't. By default, all client ids are valid.

This option applies globally.

Reloaded on reload signal. Note that currently connected clients will be unaffected by any changes.

  • connection_messages [ true | false ]

If set to true, the log will include entries when clients connect and disconnect. If set to false, these entries will not appear.

This option applies globally.

Reloaded on reload signal.

  • max_inflight_bytes count

Outgoing QoS 1 and 2 messages will be allowed in flight until this byte limit is reached. This allows control of outgoing message rate based on message size rather than message count. If the limit is set to 100, messages of over 100 bytes are still allowed, but only a single message can be in flight at once. Defaults to 0. (No limit).

See also the max_inflight_messages option.

This option applies globally.

Reloaded on reload signal.

  • max_inflight_messages count

The maximum number of outgoing QoS 1 or 2 messages that can be in the process of being transmitted simultaneously. This includes messages currently going through handshakes and messages that are being retried. Defaults to 20. Set to 0 for no maximum. If set to 1, this will guarantee in-order delivery of messages.

This option applies globally.

Reloaded on reload signal.

  • max_keepalive value

For MQTT v5 clients, it is possible to have the server send a "server keepalive" value that will override the keepalive value set by the client. This is intended to be used as a mechanism to say that the server will disconnect the client earlier than it anticipated, and that the client should use the new keepalive value. The max_keepalive option allows you to specify that clients may only connect with keepalive less than or equal to this value, otherwise they will be sent a server keepalive telling them to use max_keepalive. This only applies to MQTT v5 clients. The maximum value allowable, and default value, is 65535.

Set to 0 to allow clients to set keepalive = 0, which means no keepalive checks are made and the client will never be disconnected by the broker if no messages are received. You should be very sure this is the behaviour that you want.

For MQTT v3.1.1 and v3.1 clients, there is no mechanism to tell the client what keepalive value they should use. If an MQTT v3.1.1 or v3.1 client specifies a keepalive time greater than max_keepalive they will be sent a CONNACK message with the "identifier rejected" reason code, and disconnected.

This option applies globally.

Reloaded on reload signal.

  • password_file file path

Set the path to a password file. If defined, the contents of the file are used to control client access to the broker. The file can be created using the mosquitto_passwd utility. If mosquitto is compiled without TLS support (it is recommended that TLS support is included), then the password file should be a text file with each line in the format "username:password", where the colon and password are optional but recommended. If allow_anonymous is set to false, only users defined in this file will be able to connect. Setting allow_anonymous to true when password_file is defined is valid and could be used with acl_file to have e.g. read only guest/anonymous accounts and defined users that can publish.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal. The currently loaded username and password data will be freed and reloaded. Clients that are already connected will not be affected.

Reloaded on reload signal. The currently loaded username and password data will be freed and reloaded. Clients that are already connected will not be affected.

See also: [Here] (NEW_management-center.md).

  • per_listener_settings [ true | false ]

If true, then authentication and access control settings will be controlled on a per-listener basis. The following options are affected: password_file, acl_file, psk_file, allow_anonymous, allow_zero_length_clientid, auto_id_prefix. plugin, plugin_opt_*

Note that if set to true, then a durable client (i.e. with clean session set to false) that has disconnected will use the ACL settings defined for the listener that it was most recently connected to.

The default behaviour is for this to be set to false, which maintains the settings behaviour from previous versions of mosquitto.

Reloaded on reload signal.

  • persistence [ true | false ]

If true, connection, subscription and message data will be written to the disk in mosquitto.db at the location dictated by persistence_location. When mosquitto is restarted, it will reload the information stored in mosquitto.db. The data will be written to disk when mosquitto closes and also at periodic intervals as defined by autosave_interval. Writing of the persistence database may also be forced by sending mosquitto the SIGUSR1 signal. If false, the data will be stored in memory only. Defaults to false.

The persistence file may change its format in a new version. The broker can currently read all old formats, but will only save in the latest format. It should always be safe to upgrade, but cautious users may wish to take a copy of the persistence file before installing a new version so that they can roll back to an earlier version if necessary.

This option applies globally.

Reloaded on reload signal.

  • psk_file file path

Set the path to a pre-shared-key file. This option requires a listener to be have PSK support enabled. If defined, the contents of the file are used to control client access to the broker. Each line should be in the format "identity:key", where the key is a hexadecimal string with no leading "0x". A client connecting to a listener that has PSK support enabled must provide a matching identity and PSK to allow the encrypted connection to proceed.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal. The currently loaded identity and key data will be freed and reloaded. Clients that are already connected will not be affected.

  • user username

When run as root, change to this user and its primary group on startup. If set to "mosquitto" or left unset, and if the "mosquitto" user does not exist, then mosquitto will change to the "nobody" user instead. If this is set to another value and mosquitto is unable to change to this user and group, it will exit with an error. The user specified must have read/write access to the persistence database if it is to be written. If run as a non-root user, this setting has no effect. Defaults to mosquitto.

This setting has no effect on Windows and so you should run mosquitto as the user you wish it to run as.

Not reloaded on reload signal.

Available Plugins

Dynamic Security

note

Premium feature

The Dynamic Security plugin is a plugin for Eclipse Mosquitto which provides role based authentication and access control features that can updated whilst the broker is running, using a special topic based API.

It is supported since Eclipse Mosquitto 2.0, and should be available in all installations, but will not be activated by default.

The Cedalo [Management Center] (NEW_management-center.md) provides a web user interface for managing the dynamic security feature.

Read more about the Management Center: [Management Center] (NEW_management-center.md).

Clients

Whenever you want a device or user to be able to connect and authenticate to the broker, you create a client.

Each client has the following attributes:

  • password

The client password maps to the password provided in the CONNECT packet when a device connects. The password may be unset when a client is created, this will mean that devices will be unable to connect as the corresponding client.

The password can be updated at any point, but only by a client with the correct access. Devices typically cannot update their own passwords.

Read more about Password: [Here] (NEW_publishing.md). And [here] (NEW_mosquitto-configuration.md)

  • clientId

The client id maps to the client id provided in the CONNECT packet when a device connects. This is an optional attribute.

If the client id is empty or not provided, then any device can connect with the username for this client regardless of its client id. This means that multiple devices could connect with the same credentials at the same time, but sharing credentials between devices is not recommended.

If the client id is set, then a device can only connect as this client if the triple of username, password, and client id all match those in the client.

Read more about [Client ID] (NEW_mosquitto-configuration.md)

  • groups

A client can be a member of any number of groups.

Read more about [Groups] (NEW_mosquitto-configuration.md)

  • roles

A client can be assigned to any number of roles. A role gives the client access to different topics.

Read more about [Roles] (NEW_mosquitto-configuration.md)

  • text name

This is an optional text field to give a human friendly name to this client.

  • text description

This is an optional text field to give a human friendly description to this client.

  • disabled

A client can be set to be enabled/disabled at any point.

Disabling a client means that any devices currently connected using the credentials for that client will be disconnected and unable to reconnect.

Groups

Multiple clients can be placed in a group. Groups can have roles assigned to them, so using r is appropriate where you have a number of clients that need to have the same access.

Groups have the following attributes:

  • group name

The group name is the primary name for the group. It is used when modifying the group in any way, such as adding a client or a role.

  • roles

A group can be assigned to any number of roles. A role gives the group access to different topics.

  • text name

This is an optional text field to give a human friendly name to this group.

  • text description

This is an optional text field to give a human friendly description to this group.

Roles

Roles contain multiple access control lists (ACLs), and can be assigned to clients and/or groups.

Access Control Lists

ACLs is the feature which allows access to topics to be controlled.

Checks are made on different events as they happen: publishClientSend, publishClientReceive, subscribe, and unsubscribe.

The publishClientSend event occurs when a device sends a PUBLISH message to the broker, i.e. "is the device allowed to publish to this topic".

The publishClientReceive event occurs when a device is due to receive a PUBLISH message from the broker, i.e. it has a valid subscription and a matching message has been published to the broker.

The subscribe event occurs in response to a device sending a SUBSCRIBE message, and the unsubscribe event occurs in response to a device sending an UNSUBSCRIBE packet.

The default behaviour of the different events can be set to allow or deny access. The default behaviour applies if no matching ACL is found.

The default behaviour for the different events when the plugin has first been configured is:

  • publishClientSend: deny

  • publishClientReceive: allow

  • subscribe: deny

  • unsubscribe: allow

There is some overlap between publishClientReceive and subscribe.

In most cases, using a subscribe ACL is sufficient to provide the control you need, however by combining the two types it is possible to e.g. allow subscriptions to a wildcard topic like topic/#, but deny access for device to receive messages on a specific topic within that hierarchy like 'topic/secret'.

The different events have ACL types associated with them, and it is these ACLs that you will add to your roles.

Each ACL has a topic, a priority, and can be set to allow or deny.

The publishClientSend and publishClientReceive ACL types map directly to the events of the same name.

The topic can contain wildcards, so allowing to send access to topic/# will allow devices to publish to all topics in the topic/# hierarchy, including topic.

The subscribe and unsubscribe events have two ACL types each: subscribeLiteral, subscribePattern, unsubscribeLiteral, and unsubscribePattern.

The *Literal ACL types make a literal comparison between the topic filter provided for the ACL and the topic filter provided in the SUBSCRIBE or UNSUBSCRIBE message.

This means that setting a subscribeLiteral ACL with topic filter # to deny would prevent matching devices from subscribing the # topic filter only, but still allow them to subscribe to topic/#, for example.

The *Pattern ACL types allow or deny access based on a wildcard comparison of the ACL topic filter and the topic provided in the SUBSCRIBE or UNSUBSCRIBE message.

This means that setting a subscribePattern ACL with topic filter # to deny would prevent matching devices from subscribing to any topic at all.

Add ACLs

The following ACL types are available:

  • publishClientSend: Restrict the topics this client is allowed to use when publishing to the broker.

  • publishClientReceive: Restrict the topics this client is allowed to use when receiving published messages from the broker.

  • subscribeLiteral: Restrict the exact topic filters that this client is allowed to subscribe to. Setting to # would mean the client cannot subscribe to the # topic, but could subscribe to test/topic, for example.

  • subscribePattern: Restrict a range of topic filters that this client is allowed to subscribe to.

  • unsubscribeLiteral: Restrict the exact topic filters that this client is allowed to unsubscribe from. Setting to # would mean the client cannot unsubscribe from the # topic, but could unsubscribe from test/topic, for example.

  • unsubscribePattern: Restrict a range of topic filters that this client is allowed to unsubscribe from.

Select the ACL type in the dropdown, define the topic and priority of the ACL and decide between "allow" and "deny".

Configuring default access

The initial configuration sets the default ACL type behaviors to:

  • publishClientSend: deny

  • publishClientReceive: allow

  • subscribe: deny

  • unsubscribe: allow

You can edit the default settings by clicking on the "edit default ACL Access" icon below the roles overview table.

acl_file file path

Set the path to an access control list file. If defined, the contents of the file are used to control client access to topics on the broker.

If this parameter is defined then only the topics listed will have access. Topic access is added with lines of the format: topic [read|write|readwrite|deny] \<topic\>.

The access type is controlled using "read", "write", "readwrite" or "deny". This parameter is optional (unless \<topic> includes a space character) - if not given then the access is read/write.

\<topic> can contain the + or # wildcards as in subscriptions.

The "deny" option can used to explicitly deny access to a topic that would otherwise be granted by a broader read/write/readwrite statement. Any "deny" topics are handled before topics that grant read/write access.

The first set of topics are applied to anonymous clients, assuming allow_anonymous is true. User specific topic ACLs are added after a user line as follows: user <username>.

The username referred to here is the same as in password_file. It is not the clientid.

It is also possible to define ACLs based on pattern substitution within the topic. The form is the same as for the topic keyword, but using pattern as the keyword. pattern [read|write|readwrite|deny] \<topic\>

The patterns available for substition are:

%c to match the client id of the client

%u to match the username of the client

The substitution pattern must be the only text for that level of hierarchy. Pattern ACLs apply to all users even if the "user" keyword has previously been given.

Example: pattern write sensor/%u/data

Allow access for bridge connection messages: pattern write $SYS/broker/connection/%c/state

If the first character of a line of the ACL file is a # it is treated as a comment.

If per_listener_settings is true, this option applies to the current listener being configured only. If per_listener_settings is false, this option applies to all listeners.

Reloaded on reload signal. The currently loaded ACLs will be freed and reloaded. Existing subscriptions will be affected after the reload.

Roles have the following attributes:

  • role name

The role name is the primary name for the role. It is used when modifying the role in any way, such as adding an ACL.

  • text name

This is an optional text field to give a human friendly name to this role.

  • text description

This is an optional text field to give a human friendly description to this role.

Priorities

If you are working with more than one role per client or group, or more than one group per client, then it is crucial to understand how roles and ACLs are applied.

The order in which checks are made is determined in part by the priority of groups, roles and ACLs.

Each client group has a priority, each client role and group role has a priority, and each ACL within a role has a priority. If not set explicitly, priorities will default to -1.

For each of the group, role, and ACL objects, checks are made in priority order from the highest numerical value to the lowest numerical value.

If two objects of the same type have the same priority, then they will be checked in lexographical order according to the username/groupname/rolename, but it is advised to use unique priorities per object type.

When an event occurs that needs an ACL check, the ACLs for that ACL type are checked in order until there is a matching ACL for the topic in question.

Within each role that is checked, the ACLs are checked in priority order.

The roles assigned to a client are checked first, in priority order.

Each client group is checked in priority order, with all the roles in a group being checked in priority order before the next group is checked.

As an example, let us assume we have the following client, groups, and roles:

  • Client: sensor Groups: temperature (priority 2), humidity (priority 1)
  • Roles: hallway
  • Group: temperature Roles: input (priority 5), output (priority 1)
  • Group: humidity Roles: humidity
  • Role: hallway
  • Role: input
  • Role: output
  • Role: humidity

Anonymous access

All the documentation so far assumes that you do not allow anonymous unauthenticated access - meaning devices or users that connect without a username.

You may wish to allow anonymous access, but still make use of the dynamic security plugin, and this is supported through the automatic anonymous group.

If allowed, anything connecting without a username will be assigned to a group that you define.

By assigning roles to that group, you can control what anonymous devices can access.

Initial configuration

To use the Dynamic Security plugin, it must be configured in the broker and an initial plugin configuration must be generated. To configure the broker, add the following to your configuration file.

Linux/BSD: plugin path/to/mosquitto_dynamic_security.so plugin_opt_config_file path/to/dynamic-security.json

On Linux you would expect the plugin library to be installed to /usr/lib/x86_64-linux-gnu/mosquitto_dynamic_security.so or a similar path, but this will vary depending on the particular distribution and hardware in use.

It is recommended to use per_listener_settings false with this plugin, so all listeners use the same authentication and access control.

The dynamic-security.json file is where the plugin configuration will be stored. To generate an initial file, use the mosquitto_ctrl utility:mosquitto_ctrl dynsec init path/to/dynamic-security.json admin-user

Choose your own admin-user username. You will be asked for a password for the client. This user will be assigned the admin role, which has the following access:

  • publishClientSend: $CONTROL/dynamic-security/# - this allows the client to control the Dynamic security plugin.

  • publishClientReceive: $CONTROL/dynamic-security/# - this allows the client to receive information from the plugin. This is not necessary in the default configuration, but is included in case the default behavior for publishClientReceive is set to deny.

  • subscribePattern: $CONTROL/dynamic-security/# - this allows the client to receive information from the plugin.

  • publishClientReceive: $SYS/# - this allows the client to see the broker metrics.

  • subscribePattern: $SYS/# - this allows the client to see the broker metrics.

  • publishClientReceive: # - this allows the client to examine the messages being published by other clients.

  • subscribePattern: # - this allows the client to examine the messages being published by other clients.

  • unsubscribePattern: # - this allows the client to undo previous subscriptions. This is not necessary in the default configuration, but is included in case the default behavior for unsubscribe is set to deny.

The admin user does not have access to publish to normal application topics in the # hierarchy by default. You are strongly encouraged to keep the admin user purely for administering the plugin, and create other clients for your application.

Windows: plugin path\to\mosquitto_dynamic_security.dll plugin_opt_config_file path\to\dynamic-security.json

Usage

All control of the plugin after initial installation is through the MQTT topic API at $CONTROL/dynamic-security/v1. This allows integrations to be built, but isn't the best choice for people to use directly. The mosquitto_ctrl command provided with Mosquitto implements support for the dynamic security plugin API, as described below. Other options include the [Management Center for Mosquitto] (/management-center) which is an open source web based tool for controlling the plugin and other features. The Management Center is not part of the Mosquitto project.

Using mosquitto_ctrl with a running broker

The initial configuration is the only time that mosquitto_ctrl does not connect to a broker to carry out the configuration. All other commands require a connection to a broker, and hence a username, password, and whatever else is required for that particular connection. It is strongly recommended that your broker connection uses encryption so that your configuration, including new passwords, is not transmitted in plain text.

The connection options must be given before the dynsec part of the command line:

mosquitto_ctrl <connection options> dynsec <command> ...

For example:

mosquitto_ctrl -u admin -h localhost dynsec <command> ...

It is possible to provide the admin password on the command line using -P password, but this is not recommended. If you do not provide a password, mosquitto_ctrl will ask you to enter the password when it is needed.

Using an options file

For convenience, mosquitto_ctrl can load an options file which contains a list of options it should use. This means you can set the encryption options, host, admin username and any other options once and not have to add them to the command line every time.

mosquitto_ctrl will try to load a configuration file from a default location. For Windows this is at %USER_PROFILE%\mosquitto_ctrl.conf. For other systems, it will try $XDG_CONFIG_HOME/mosquitto_ctrl.conf or $HOME/.config/mosquitto_ctrl.conf.

You may override this behavior by manually specifying an options file with -o <path to options file>.

The options file should contain a list of options, one per line, exactly as they would be provided on the command line. For example:

--cafile /path/to/my/CA.crt

--certfile /path/to/my/client.crt

--keyfile /path/to/my/client.key

-u admin

-h mosquitto.example.com

See [this page] (https://github.com/eclipse/mosquitto/blob/fixes/www/pages/documentation/dynamic-security.md#mosquitto_ctrl-options) for the full list of options available for mosquitto_ctrl.

Configuring default access

The initial configuration sets the default ACL type behaviors to:

  • publishClientSend: deny
  • publishClientReceive: allow
  • subscribe: deny
  • unsubscribe: allow

If you wish to change these, use mosquitto_ctrl.

mosquitto_ctrl <options> dynsec setDefaultACLAccess publishClientSend deny
mosquitto_ctrl <options> dynsec setDefaultACLAccess publishClientReceive deny
mosquitto_ctrl <options> dynsec setDefaultACLAccess subscribe deny
mosquitto_ctrl <options> dynsec setDefaultACLAccess unsubscribe deny

You can examine the current default access with the getDefaultACLAccess command:

mosquitto_ctrl <options> dynsec getDefaultACLAccess unsubscribe

Creating and modifying clients

To create a new client:

mosquitto_ctrl <options> dynsec createClient <username>

This creates a client which does not have a client id associated with it. You will be asked for the password for the new client before you are asked for the admin user password. Pay attention to the messages on the command line.

mosquitto_ctrl <options> dynsec createClient <username> -i <client id>

This creates a client which has a client id associated with it.

To delete a client (clients connected with these credentials will be disconnected from the broker):

mosquitto_ctrl <options> dynsec deleteClient <username>

To disable a client (clients connected with these credentials will be disconnected from the broker):

mosquitto_ctrl <options> dynsec disableClient <username>

To enable a client (clients will be able to use these credentials to log in again):

mosquitto_ctrl <options> dynsec enableClient <username>

To set a client password:

mosquitto_ctrl <options> dynsec setClientPassword <username>
mosquitto_ctrl <options> dynsec setClientPassword <username> <password>

To add/remove a role to/from a client:

mosquitto_ctrl <options> dynsec addClientRole <username> <rolename> <priority>
mosquitto_ctrl <options> dynsec removeClientRole <username> <rolename>

To get information on a client:

mosquitto_ctrl <options> dynsec getClient <username>

To list all clients:

mosquitto_ctrl <options> dynsec listClients

The modifyClient command also exists in the topic API, but is not currently available in mosquitto_ctrl.

Creating and modifying groups

To create a new group:

mosquitto_ctrl <options> dynsec createGroup <groupname>

To delete a group:

mosquitto_ctrl <options> dynsec deleteGroup <groupname>

To add/remove a client to/from a group:

mosquitto_ctrl <options> dynsec addGroupClient <groupname> <username> <priority>
mosquitto_ctrl <options> dynsec removeGroupClient <groupname> <username>

In this case the priority refers to the priority of the group within the client's list of groups.

To add/remove a role to/from a group:

mosquitto_ctrl <options> dynsec addGroupRole <groupname> <rolename> <priority>
mosquitto_ctrl <options> dynsec removeGroupRole <groupname> <rolename>

To set/get the group that anonymous devices are assigned to:

mosquitto_ctrl <options> dynsec setAnonymousGroup <groupname>
mosquitto_ctrl <options> dynsec getAnonymousGroup

To get information on a group:

mosquitto_ctrl <options> dynsec getGroup <groupname>

To list all groups:

mosquitto_ctrl <options> dynsec listGroups

The modifyGroup command also exists in the topic API, but is not currently available in mosquitto_ctrl.

Creating and modifying roles

To create a new role:

mosquitto_ctrl <options> dynsec createRole <rolename>

To delete a role:

mosquitto_ctrl <options> dynsec deleteRole <rolename>

To add an ACL to a role:

mosquitto_ctrl <options> dynsec addRoleACL <rolename> <acltype> <topic filter> allow|deny <priority>

Where acltype is one of publishClientSend, publishClientReceive, subscribeLiteral, subscribePattern, unsubscribeLiteral, and unsubscribePattern.

For example:

mosquitto_ctrl <options> dynsec addRoleACL <rolename> clientPublishSend client/topic allow 5

To remove an ACL from a role using the topic filter as the key:

mosquitto_ctrl <options> dynsec removeRoleACL <rolename> <acltype> <topic filter>

For example:

mosquitto_ctrl <options> dynsec removeRoleACL <rolename> clientPublishSend client/topic

To get information on a role:

mosquitto_ctrl <options> dynsec getRole <rolename>

To list all roles:

mosquitto_ctrl <options> dynsec listRoles

The modifyRole command also exists in the topic API, but is not currently available in mosquitto_ctrl.

Limitations

To set limitations can increase security as well. As you don't want your broker to crash when there is any kind cyberattack. Like a DDoS Attack.

info

Digression: DDos Attack

A distributed denial of service (DDoS) attack is a malicious attempt to disrupt the normal traffic of a targeted server, service, or network by overloading the target or surrounding infrastructure with a flood of traffic.

Message rate limit

You can set a rate limit of how many messages can be sent within a specific time interval.

  • max_packet_size value

For MQTT v5 clients, it is possible to have the server send a "maximum packet size" value that will instruct the client it will not accept MQTT packets with size greater than value bytes. This applies to the full MQTT packet, not just the payload. Setting this option to a positive value will set the maximum packet size to that number of bytes. If a client sends a packet which is larger than this value, it will be disconnected. This applies to all clients regardless of the protocol version they are using, but v3.1.1 and earlier clients will of course not have received the maximum packet size information. Defaults to no limit.

This option applies to all clients, not just those using MQTT v5, but it is not possible to notify clients using MQTT v3.1.1 or MQTT v3.1 of the limit.

Setting below 20 bytes is forbidden because it is likely to interfere with normal client operation even with small payloads.

This option applies globally.

Reloaded on reload signal.

  • max_queued_bytes count

The number of outgoing QoS 1 and 2 messages above those currently in-flight will be queued (per client) by the broker. Once this limit has been reached, subsequent messages will be silently dropped. This is an important option if you are sending messages at a high rate and/or have clients who are slow to respond or may be offline for extended periods of time. Defaults to 0. (No maximum).

See also the max_queued_messages option. If both max_queued_messages and max_queued_bytes are specified, packets will be queued until the first limit is reached.

This option applies globally.

Reloaded on reload signal.

  • max_queued_messages count

The maximum number of QoS 1 or 2 messages to hold in the queue (per client) above those messages that are currently in flight. Defaults to 1000. Set to 0 for no maximum (not recommended). See also the queue_qos0_messages and max_queued_bytes options.

This option applies globally.

Reloaded on reload signal.

  • memory_limit limit

This option sets the maximum number of heap memory bytes that the broker will allocate, and hence sets a hard limit on memory use by the broker. Memory requests that exceed this value will be denied. The effect will vary depending on what has been denied. If an incoming message is being processed, then the message will be dropped and the publishing client will be disconnected. If an outgoing message is being sent, then the individual message will be dropped and the receiving client will be disconnected. Defaults to no limit.

This option is only available if memory tracking support is compiled in.

Reloaded on reload signal. Setting to a lower value and reloading will not result in memory being freed.

  • message_size_limit limit

This option sets the maximum publish payload size that the broker will allow. Received messages that exceed this size will not be accepted by the broker. This means that the message will not be forwarded on to subscribing clients, but the QoS flow will be completed for QoS 1 or QoS 2 messages. MQTT v5 clients using QoS 1 or QoS 2 will receive a PUBACK or PUBREC with the "implementation specific error" reason code.

The default value is 0, which means that all valid MQTT messages are accepted. MQTT imposes a maximum payload size of 268435455 bytes.

This option applies globally.

Reloaded on reload signal.

  • Maximum client identifier length of 65535 characters.

  • Maximum allowed topic length of 65535 characters.

  • Unlimited concurrent connections.

  • No bandwidth throttling.

  • Automatic disconnection of clients that fail to send a CONNECT message within 10 seconds after the TCP connection is established.

Third party plugins

[OAuth2.0] (https://github.com/gewv-tu-dresden/mosquitto-go-auth-oauth2).