Understanding and Using the Mosquitto Dynamic Security Plugin

The dynamic security plugin can be used instead of the password file and the ACL list.

The plugin is available in mosquitto v2 but it is not enabled by default.

If you decide to use it then the manual recommends you use it for all listeners and don’t have some using the old password file and other listeners using the security plugin. Use:

per_listener_settings false

To configure the broker to use it then you need to set the path to the plugin, and also the path to the security file.

The security file is a json file.

Linux:

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

plugin /usr/lib/x86_64-linux-gnu/mosquitto_dynamic_security.so
plugin_opt_config_file /home/steve/mos/v5/test.json


Windows:

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


To locate the plugin on  Linux use

whereis mosquitto_dynamic_security.so

Using the Plugin

You first need to edit the config file as shown above, and also to create a dynamic-security.json file.

The file can have any name and a starter basic file is created using the mosquitto_ctrl utility that comes with mosquitto v2.
Use:

mosquitto_ctrl dynsec init path/to/dynamic-security.json admin-user

example:
mosquitto_ctrl dynsec init path/to/dynamic-security.json steve


Where steve is the user that I will use for configuring the security settings.

You must do this on the broker itself or you will need to copy the file to the broker.

The proceeding command is the only mosquitto_ctrl command that doesn’t require that you specify a broker and port.

The mosquitto_ctrl utility is basically a modified mosquitto_pub client and publishes messages to the $CONTROL topics on the broker. When you generate the default file the user steve (my example) will be given the required permissions in the file. You could manually edit the security file to modify the security settings but this is too complex. Instead the mosquitto_ctrl utility is then used to dynamically modify the security settings on a running broker and can be run from any machine that has the utility installed. It is probably best that you use SSL when running this utility on a production broker but when testing I wouldn’t use SSL. Key Concepts The plugin lets you configure security using three objects- client, group and role objects. The client is actually the use rname you use to access the broker assuming that you are not allowing anonymous access. Client Object This has the following properties: • user name • password • client Id (optional) • groups • roles • text name – a friendly name • text description • enabled – a client can be disabled A client can belong to a group/groups and assigned to a role/roles it can also be enabled and disabled. If the client_id is not specified then the username/password can be used by multiple connections which is the case for mosquitto when using standard password files. Groups Object This has the following properties: • Group name -Used when modifying group • Roles • Friendly name (optional) • Description (optional) Roles Object The Roles object contains the following properties • Role name • Access Control List (ACL) • Friendly name (optional) • Description (optional) The roles object is used to give clients access to topics. Clients,Groups and Roles Clients can be assigned directly to roles and given or denied access to topics, but doing so is not as flexible as using groups. For example if 10 clients are assigned to role1 and you decide that you need to assign different access to 5 clients and so need to assign them to role2 then you would to make 5 changes. However if you had assign 5 clients to group1 and 5 to group2 and assigned both groups to role 1 then you would only need to make 1 change to the group. That is provided the clients had been assigned in the correct group to start with. So try and use client–>Group –>Role and not client –> Role. How it works To understand how security is applied we will start using the default security file generated using mosquitto_ctrl. A snapshot of the file is shown below: The plugin uses events that trigger an ACL check. So for example when a client subscribes an ACL lookup would be triggered. You can see from the file that I have marked it into three blocks. Default Access The default access permissions in the default configuration file are defined in the defaultACLAcess entry (bottom block) are very restrictive and only grant access to the admin user. All other users and anonymous users (if enabled) are not allowed to publish or subscribe to any topics, not even the$SYS topic

You can see from the defaultACLAcess entry that we have four broker events that can be used to configure ACL permissions.

We have the unsubscribe and subscribe events which are triggered when a client subscribes or unsubscribes.

We also have the publishClientSend event which is triggered when the client published a message to the broker, and the publishClientReceive event when the broker needs to send a message to the client.

As stated in the manual there is an overlap between the subscribe and publishClientReceive events and usually using the subscribe event is sufficent.

However the publishClientReceive event gives you more control as you can subscribe to a wild card topic but still restrict access to certain topics in the hierarchy.

E.g

topic test/# subscribe allow

would allow access to all topics in the test hierarchy except test/secret

If a client supplies a username and password then the logon credentials will be checked against the client entry if any.

If the client doesn’t have an assigned role or group then the defaultACLAcess permissions will apply.

If allow anonymous is disabled then the connection must supply a valid username and password, defined in the configuration file as a client entry.

It is possible to simulate the old passwords file just by simply creating client entries with no roles or groups and setting all entries in defaultACLAcess to true.

"defaultACLAccess": {
"publishClientSend": true,
"subscribe": true,
"unsubscribe": true
}


The entry for the admin user is only necessary if you want to manage the settings using mosquitto_ctrl.

Priorities

A priority can be applied to groups and roles. The default priority is -1.

If a client has multiple roles assigned or is a member of multiple groups then you need to understand the order in which ACL permissions are applied.

The first check is made on the role assigned to the client.

If a client(user) has two roles for example role1 and role2 and role role1 and a priority of -1 (default ) and role2 has a priority of 5 then the permission of role2 will take affect.

If a client is assigned to a role or group with ACL permissions set then these ACL permissions will override those in the defaultACLAcess entry.

The documentation gives a more detailed but complex overview of priorities.

I would suggest you keep them as simple as possible.

Anonymous Group

If you have allowed anonymous access then all anonymous users will be placed in the anonymous group.

The name of this group needs to be created and set using:

mosquitto_ctrl <options> dynsec createGroup <groupname>
mosquitto_ctrl <options> dynsec setAnonymousGroup <groupname>

example
mosquitto_ctrl -h 192.168.1.91 -u steve -P password dynsec createGroup anonymous
anonymous mosquitto_ctrl -h 192.168.1.91 -u steve -P password dynsec setAnonymousGroup anonymous

You can now assign the group to a role and ACL permissions to that role.

ACL Worked Example

Configuration – The default defaultACLAcess is set as follows:

"defaultACLAccess": {
"publishClientSend": false,
"subscribe": false,
"unsubscribe": true
}


Client john is assigned to role1 and role 2. Role 1 has all allow permissions to topic test with priority -1 and role 2 is configured with deny subscribe to topic test with priority of 5.

Q1 Will john be able to subscribe to topic test?

Q2 Will john be able to publish to topic test?

Q3 What will be the effect of changing the permissions for role1 to deny publish.

Q4 If You change permissions to role1 will you need to restart mosquitto.

Answers at the end of the tutorial

Making Changes

You can edit the security file manually and this is likely to be the case with the initial security file.

However after initial deployment changes are made dynamically using the new mosquitto_ctrl tool which we look at in the next tutorial.

Q1 _can I use the %u and % c syntax like in the old ACL file?

A- It doesn’t appear so

Q2 – Should I move to the new plugin?

A2- Unless your ACL permissions change frequently then I think you would be better with the old files.

Q1 -role2 has priority and there is a deny permission to topic test.. So  John cannot subscribe to test

Q2 role2 has no entry for publish for which means it will look in role1 which has an entry and so John can publish.

Q3-John cannot publish

Q4 – No it is dynamic.

Related Resources and Tutorials

1. Dorian says:

hey !

I am a little bit confused here. Are these commands actually applied also dynamically on Mosquitto service? Or it needs to be restarted each time I set up/add new rules?!

The config file is also written in case the service/system is restarted/rebooted?!

I asked this because I’d like to develop an interface where I should add/generate/manage clients &topics & ACL … and all of these stuff, without actually stopping the service. It will be possible/applicable to do that?

thanks !

ps: nice article! 🙂

1. steve says:

Hi
There is no need for a restart as it is dynamic
rgds
steve

2. Mike Sandstrom says:

Hi Steve,

To take this further, if I want to modify the json file dynamically based off of MQTT messages from clients, what approach could I take? Could I use a python client on the broker that uses the ‘os’ module to interact with the mosquitto_ctrl tool?

1. steve says:

Mike
Yes that is what I would do. It is on my to do list along with lots of other things but I might do it in node-red as it is easier to build a web interface for it.
rgds
steve

1. Mike says:

got it, thanks for the reply Steve, I hope all is well.

3. Werner says:

Minor nitpicking: there are a few “Recieve” in the text. These should be “Receive”. (I did check the code, just in case 🙂

1. steve says:

Hi
Tks for pointing that out. I have edited the page and hopefully found them all.
Rgds
Steve

4. Lukas says:

Hi everyone,
just a quick side note. Don’t forget to restart the broker after setting everything up.
Otherwise the plugin will not give any response (no error either).

And one quick question. Shouldn’t I be able to a new client in the dynamic-security.json after “createClient”?
In which file would it be stored then?

Best and thanks for this Blog!

5. Mike says:

On windows I can find mosquitto_dynamic_security.dll, but on raspberry pi and a virtual private server running debian I can’t seem to find mosquitto_dynamic_security.so ?

I tried
>whereis mosquitto_dynamic_security.so
but it just returns
mosquitto_dynamic_security:

I tried looking and searching with slightly modified names but no luck, any ideas please?

Thanks,
Mike

1. steve says:

I didn’t find it either it is on my todo list to find out why. Presently I am using the windows one to do the testing as it runs remote anyway.
Rgds
Steve

1. Mike says:

Thanks for letting me know it’s same on your system, I downloaded mosquitto source and compiled the plugin (untested so far).
These are the steps I took..

1. Needed cJSON for linking, so from my home directory did:

mkdir cjson
cd cjson
git clone https://github.com/DaveGamble/cJSON.git ./
sudo make install

2. get source for mosquitto (but build won’t currently work for me because of websockets library error, but get source anyway for the plugin source code), so from my home directory did:

mkdir mosquitto2
cd mosquitto2
git clone https://github.com/eclipse/mosquitto.git ./

3. build and install the dynamic_security plugin

cd /home/pi/mosquitto2/plugins/dynamic-security
sudo make install
(The output from that gives: “/usr/local/lib/mosquitto_dynamic_security.so”)

I haven’t yet tested mosquitto_dynamic_security.so against a running mosquitto broker, I just wanted to know how to make the library file if I had to..

All the best,
Mike

1. steve says:

Tks for the info I will try it myself when I get a chance.
Rgds
Steve

6. Sam says:

Hi, I think for the question 2 under ACL worked example, the answer should be YES. The reason why I say so is because –
a) I have tried it practically, and
b) This has to work. Then only the point of using multiple roles with a single client would work. If we try to publish to the test topic, an ACL check will occur in the role role2 first (since it has the highest priority). Since, no matching ACL will be found, it will search in the role with lesser priority, i.e., role1. And since role1 has allow for all ACLs to the topic test, the client john will be able to publish.
Similarly I think the answer to the third question should also change to – client will not be able to publish.

1. steve says:

Sorry for the delay tks for the feedback I will try and check the results shortly and let you know.

1. steve says:

Yes I agree with you and have changed the answers.
Rgds
Steve