Configuring and Testing Mosquitto MQTT Topic Restrictions

mosquitto-broker-topic-restrictionsNot only can you restrict access to the Mosquitto MQTT broker using a username and password you can also restrict access to topics.

Unless you are running an open broker you will want to restrict access to topics so that only authorized users/clients can publish or subscribe to them.



Topic restrictions are configured on the Broker, and there is nothing to configure on the client.

Topic restriction is done in an access control list ( ACL ) file.

To enable topic restrictions you need to edit the mosquitto.conf file to use it.

Note: You should create a copy of the default file as a backup before you edit it.

You will find the setting in the Default authentication and topic access control section:

You need to add the following line (windows install example)

acl_file c:\mosquitto\aclfile.example

A default file ( aclfile.example ) is provided with the installation.

The contents of this file are shown below:

mosquitto-default-acl-file

The default ACL file is very restrictive, and if implemented as is, would deny access to almost every topic to every user and client.

The general rule is that, by default, you are denied access unless explicitly allowed.

The file has effectively three sections:

  • General section
  • User specific section
  • Client or user ID section

General Section

Entries here start with the keyword topic and apply to all clients except if the client provides a user name.

If the client provides a username then entries in this section are ignored for that user.

The entry in the default file is

topic read $SYS/#

This gives read (subscribe) access to any client that doesn’t supply a username to the topic $SYS/#.

Any client trying to subscribe or publish to any other topics e.g. house/sensor1 would be denied.

User Section

This section uses the keyword user.

Each user can have topic entries that define access rights. The default file contains the following entry

user roger
topic foo/bar

This entry only apples if the client supplies a username otherwise it is ignored.

The entry means that a user named roger can publish and subscribe on the topic foo/bar.

No other user can publish or subscribe on any other topics.

Note: topic foo/bar is the same as topic readwrite foo/bar

Client or User ID Section

Every client will provide a client ID.

Entries in this section will only apply to the client with that Client ID.

The entry in the default file is

pattern write $SYS/broker/connection/%c/state

This means that a client with client name or ID of P1 can publish to the topic:

$SYS/broker/connection/P1/state

and a client with client ID of P2 can publish to the topic

$SYS/broker/connection/P2/state

Client P! cannot publish to :

$SYS/broker/connection/P2/state

However entries in the General section and User section will also need to be taken into consideration and could allow more access.

The user id is used in a similar fashion.

pattern readwrite phone/inbox/%u/#

Would give user roger publish and subscribe access to:

phone/inbox/roger/#

Detecting Access Control Restrictions

Unfortunately it is not easy to detect ACL restrictions as they aren’t notified to the client.

This means that if a client subscribes to a topic and is denied by the ACL then the client doesn’t know it has been denied as it receives a positive acknowledgement.

In addition if a client publishes to a topic and is denied, again the client doesn’t know it has been denied as it receives a positive acknowledgement. (This you will see in the examples below)

The only way you can really detect a problem is by subscribing and publishing to a topic and detecting or not detecting the published message.

Access Control Examples -General Settings

In the detailed examples below we look at topic restrictions using the general settings.

Later we look at User and client settings and how they are used to control topic access.

In the examples below we will use a simple python script to subscribe and publish and examine the results on the python client and on the broker console.

In the examples below we will do the following:

  1. Subscribe and Publish to a topic with no ACL configured.
  2. Subscribe and Publish to a topic using the default ACL file.
  3. Edit the default ACL file to allow subscriptions and then Subscribe and Publish to a topic.
  4. Edit the default ACL file to allow subscriptions and publishing and then Subscribe and Publish to a topic.

In each case we look at the various return and error codes shown by the client script and on the Mosquitto broker console.

For the examples I have enabled logging of all error messages on the broker.

Example 1-Subscribe and Publish to a topic with no ACL configured.

With no ACL being used then we are free to subscribe and publish to any topic.

The screen shots below show that the messages we publish are received.

acl_restrictions_no_acl

Example 2- Subscribe and Publish to a topic with the default ACL configured.

With the default ACL being used then we are restricted to reading the #SYS topic.

In the example we subscribe to house/# and publish to house/sensor1

The screen shots below show that the messages we publish are not received which is as expected.

However notice that the subscribe return code and publish return code indicate success.

However the Mosquitto server console logs a published denied message.

acl_restrictions_default_acl

Example 3- Subscribe and Publish to a topic with an Edited ACL .

This time we edit the default ACL to allow subscribing to topic house/#

The setting is

topic read house/#

Again,In the example we subscribe to house/# and publish to house/sensor1

The screen shots below show that the messages we publish are not received which is as expected.

However notice that the subscribe return and publish return codes indicate success.

However the Mosquitto server console logs a published denied message.

acl_restrictions_edited_read_acl

Example 4- Subscribe and Publish to a topic with an Edited ACL.

This time we edit the default ACL to allow anyone to subscribe and publish to topic house/# .

the setting is

topic readwrite house/#

Again,In the example we subscribe to house/# and publish to house/sensor1

The screen shots below show that the messages we publish are received, which is as expected.

This time the Mosquitto server console logs the message being sent back to the client.

acl_restrictions_edited_readwrite_acl

User Restrictions

User restrictions are triggered when the client provides a username.

If a username is provided by the client then the ACL list is checked for that user.

Username restrictions will override General restrictions.

This means that if the General settings allow access to that topic, if the client provides a username, and that username doesn’t have an entry in the ACL explicitly giving access to that topic, then they are denied.

Client Settings

Client settings usually use the client ID as part of a pattern match.

You normally see entries like:

pattern readwrite house/%C/#

This setting will allow a client with client id python1 to publish and subscribe to topic house/python1/#.

Client python1 will not be able to publish and subscribe to topic house/lights/#.

Client Settings and General Settings are additive. This means that if the client settings don’t allow, but the General settings do then, it is allowed.

Client Settings will override User Settings. This means that if clients settings allow a client to publish/subscribe to a topic then they are allowed regardless of the user settings.

The Following table tries to summarize the General,User and Client Settings

General Settings

User Settings

Client sends Username

Client

Settings

Result

Blank Blank No Blank Denied
Configured Blank or configured No Blank Depends on General settings
Blank or configured Blank Yes Blank Denied
Blank or configured Configured Yes Blank Depends on User settings. General settings don’t apply
Blank or configured Blank or configured No Configured Combination of General and Client settings
Blank or configured Blank or configured Yes Configured Client Settings will override user settings and user settings make General settings irrelevant

Examples Settings

Here are some example settings to illustrate the above

Example 1 -User Settings

#General settings

readwrite topic #

#User settings

user Roger
topic readwrite house/#

#Client settings

#Blank

Result

Only user roger can publish and subscribe to topic house/#.

If the client doesn’t send a username then the client can publish and subscribe to all topics -entry readwrite topic # in General settings.


Example 2 -User and Client Settings

#General settings

#Blank

#User settings

user Roger
topic readwrite house/P1/#

#Client settings

pattern readwrite house/%C/#

Result

If the client name is Python 1 then that client can publish and subscribe to topic house/Python1/# regardless of the username sent.

However only user roger can publish and subscribe to topic house/P1/#..

Important Notes:

Topic names and usernames are case sensitive. User roger isn’t the same as user Roger.

Topic house/Python1/# isn’t the same as house/python1/#.

Common Questions and Answers

Q- How do I know if my published message has been denied by the broker or just lost?

A- You cannot tell from the client.

Q-Does the user in the ACL user section need to be added to the passwords file?

A- No, not for the ACL to work, but it does if you are also using username and password authentication.

Summary

You can restrict access to a broker by configuring Access control.

Access control can be applied to users,client ids and topics.

From a client perspective is isn’t easy to know if access control is being applied as restrictions aren’t notified to the client.

Mosquitto Configuration Tutorials

Related Tutorials and Resources

Facebooktwittergoogle_plusredditpinterestlinkedinmail

19 comments

  1. Hi Steve,

    Great article, very informative. Is it possible to deny access by IP Addresses? Or to only allow access to specific IP Address?

    Thanks.

    1. Glad you found the article useful. You cannot restrict access by IP address using the mosquitto.conf file. In a way it is not surprising as client IP addresses can change.
      If you needed to do that then you could use IPtables on Linux.

  2. Hello Steve,

    Thank you for the article. It is very imformative. I was wondering is there any way to use external service as acl data provider. I mean in this example broker loads file. But you have to reload it every time acl change a happens. Would it be possible to use database to check acl?

    1. Not as far as I know but the broker is being upgraded to support mqtt vs 5 and things might change then.
      Last time I checked it was supposed to be released in august but I haven’t heard anything. Here is a link to the blog https://mosquitto.org/blog/
      rgds
      steve

  3. Hi
    My users are more than 1 million
    And I am needing user only subscribe in self userid
    So I have to add all user self topic in acl
    If acl contain 1 million user in file so mosquitto cannot load it
    Do you have idea for prevent sinscribe user in other topic for many users?

  4. Hi, Steve. For the example 4, I’ve commented all other setting in ACL file and add in “topic readwrite house/#” but when I publish, the broker still denied the publish. Do you have any idea about this?

    1. BTW, i’m using the windows command prompt console to do the testing and my ACL file only have the setting I mentioned above, if this could be the cause.

  5. @Steve. A very good explanation.
    You have mentioned that :
    “The general rule is that, by default, you are denied access unless explicitly allowed.”

    Is there as way in which we could deny a user from publishing to a particular topics only while he/she has access to other topics. What I want is explicit deny instead of explicit allow.

    1. Of my head I would try to allow all using the # wildcard and then deny on a user name basis. I haven’t tried it yet but I will and let you know. Just to be sure I get what you want . you want all users to have access but deny individual users access to certain topics? Is that correct

  6. Also you said that :
    ” Entries here start with the keyword topic and apply to all clients except if the client provides a user name.
    If the client provides a username then entries in this section are ignored for that user. ”

    the above sentences are not clear. what do you mean from “username” ? username in the CONNECT message or in the GENERAL section of the “acl_file” ?
    can you provide an example?

    thank you very much for your help
    Best regard…

    1. Jack
      username in the connect message. If you look back to the password tutorial you can supply a username and password from the client but if the broker is set for anonymous access, and has no passwords file set the the broker ignores it.
      However that username can be used for access control.
      Does that make sense?

  7. dear steve
    what do you mean from “outline” and “ouline” in this expression?
    {outline]topic read house/# [/ouline]

Leave a Reply

Your email address will not be published. Required fields are marked *