Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mosquitto Dynamic Security Plugin - dynamic changes. Unknown commands error #2772

Closed
franriibeiro opened this issue Mar 21, 2023 · 4 comments

Comments

@franriibeiro
Copy link

Hello to all,

I have a backend server programmed in PHP with the Symfony framework and I am using the mqttClient/PHP package to connect and communicate with a mosquitto broker which I'm running locally. The mosquitto broker is using the Dynamic Security Plugin, defined in the mosquitto.config as the https://mosquitto.org/documentation/dynamic-security/ says to do.

My problem is as follows:

I want the PHP server to be a client of the broker, and this client will act as the admin of the broker. I need to dynamically update the dynamic_security.json file so that I can add/remove/update clients/roles/groups. For this to happen, I am publishing on the $CONTROL/dynamic-security/v1 topic, as the documentation indicates. However, every time I try to publish on this topic, because the client is also subscribed to the topic $CONTROL/dynamic-security/#, I always get the following error:

Received message on topic "$CONTROL/dynamic-security/v1/response": {"responses":[{"command":"Unknown command","error":"Invalid/missing commands"}]}

The command (payload) I am sending to the broker is a json message with the following structure:

`
$client->subscribe('$CONTROL/dynamic-security/#', function (string $topic, string $message) use ($output) {
$output->writeln(sprintf('Received message on topic "%s": %s', $topic, $message));
});

    $client->publish('$CONTROL/dynamic-security/v1', json_encode([
        "commands" => [
            "command" => "createClient",
            "clientid" => "clientid",
            "username" => "testing",
            "password" => "password",
            "roles" => ["admin"],
            "topics" => [
                "topic1" => [
                    "qos"=> 0,
                    "retain"=> false,
                    "pub"=> true,
                    "sub"=> true
                ]
            ]
        ]
    ]));`

What am I doing wrong?

On the running mosquitto broker, when I try to publish this message, the following message is logged:

`
1679395256: New connection from ::1:62345 on port 1884.

1679395256: New client connected from ::1:62345 as client_id (p2, c1, k10, u'admin-user').
1679395256: No will message specified.
1679395256: Sending CONNACK to client_id (0, 0)
1679395256: Received SUBSCRIBE from client_id
1679395256: $CONTROL/dynamic-security/# (QoS 0)
1679395256: client_id 0 $CONTROL/dynamic-security/#
1679395256: Sending SUBACK to client_id
1679395256: Received PUBLISH from client_id (d0, q0, r0, m0, '$CONTROL/dynamic-security/v1', ... (31 bytes))
1679395256: Sending PUBLISH to client_id (d0, q0, r0, m0, '$CONTROL/dynamic-security/v1/response', ... (80 bytes))
1679395266: Received PINGREQ from client_id
1679395266: Sending PINGRESP to client_id
`

Also, I know that my php client is correctly authenticating himself as the admin-user because if i don't authenticate it, all the messages are denied on the broker. So, the problem should not be that.


Summarizing:

I need to dynamically add and remove clients and I need to do that on my code, so I can't use the mosquitto_ctrl tool. To which topic should I send the message with the new clients? What commands does that topic accept? The mqttCLient/PHP is using the MQTT v3.1.1, is this the problem? It shouldn't be, right?

Best regards,
Francisco

@franriibeiro
Copy link
Author

Also, my dynamic_security.json file is currently like this.

{
	"defaultACLAccess":	{
		"publishClientSend":	false,
		"publishClientReceive":	true,
		"subscribe":	true,
		"unsubscribe":	true
	},
	"clients":	[{
			"username":	"admin-user",
			"textname":	"Dynsec admin user",
			"roles":	[{
					"rolename":	"admin"
				}],
			"password":	"xTM8O7Pu2pVJeefrZE8sW6nSbYLtZViP2Vd7gkbOnzKOeUDGyls6A5dm53kCGrT5USvUPeCTwZh0zcjV6XyWhw==",
			"salt":	"n7P/hqRPNLS+OId+",
			"iterations":	101
		}, {
			"username":	"test",
			"roles":	[{
				"rolename":	"admin"
			}],
			"password":	"UcXm3fZw2gFaWMQ60VcjWdnNTn2JyQPFqONY0SSY6tACzaIj1mE0XKJP912kJdSoh1ly7PfXERNnlijE8ZmK+w==",
			"salt":	"Hryd/AjX2A/jXoRM",
			"iterations":	101
		}],
	"groups":	[{
			"groupname":	"devices",
			"roles":	[],
			"clients":	[]
		}, {
			"groupname":	"mobiles_app",
			"roles":	[],
			"clients":	[]
		}, {
			"groupname":	"server",
			"roles":	[],
			"clients":	[]
		}],
	"roles":	[{
			"rolename":	"admin",
			"acls":	[{
					"acltype":	"publishClientSend",
					"topic":	"$CONTROL/dynamic-security/#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"publishClientReceive",
					"topic":	"$SYS/#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"publishClientReceive",
					"topic":	"#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"subscribePattern",
					"topic":	"$CONTROL/dynamic-security/#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"subscribePattern",
					"topic":	"$SYS/#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"subscribePattern",
					"topic":	"#",
					"priority":	0,
					"allow":	true
				}, {
					"acltype":	"unsubscribePattern",
					"topic":	"#",
					"priority":	0,
					"allow":	true
				}]
		}, {
			"rolename":	"appRole",
			"acls":	[]
		}, {
			"rolename":	"deviceRole",
			"acls":	[]
		}]
}

and my mosquitto.conf is like this:

allow_anonymous true
listener 1884

plugin C:\Program Files\mosquitto\mosquitto_dynamic_security.dll
plugin_opt_config_file C:\Program Files\mosquitto\dynamic-security.json

@ralight
Copy link
Contributor

ralight commented Apr 1, 2023

I'm not familiar with the json_encode syntax, but it looks as though you may have some mixup about what should be an array and what should be an object. I'd try printing the result of the call to json_encode to have a look.

You should be getting something like this:

{
    "commands":[
        {
            "command": "createClient",
            ...
        }
    ]
}

@franriibeiro
Copy link
Author

Thank you. it was because of the json encoding indeed

@arshidkv12
Copy link

You can use the easy dynamic plugin. It is developed with Rust.
https://github.com/arshidkv12/mosquitto-plugin

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants