i have four trucks connected to a mqtt broker, and I have four Apps/devices. the trucks publishes messages and the Apps subscribe to these message
is there any way to restrict the access of the devices to the message published by the trucks? in another words, lets assume truck1 publishes the following messages (truck1_msg1, truck1_msg2, truck1_msg) I want App1 able to subscribe and listen to the messages from truck1 only and never be able to subscribe and see any other messages published by other trucks. is it possible? would you please let me how can I do it?
note: all the trucks and the Apps are connected to the same broker, and lets assume it is Mosquitto
Most MQTT brokers support topic level ACLs for a given user so assuming each truck publishes messages to a distinct topic (or topic prefix as ACLs tend to support wild cards) and each truck and app has it's own user you should be able to arrange any segregation of access you need.
Each broker have different mechanisms for managing these ACLs, for example here are the details for mosquitto.
The documentation for mosquitto's ACL format can be found in it's man page here: https://mosquitto.org/man/mosquitto-conf-5.html
You add an ACL file to the mosquitto.conf with the acl_file option:
acl_file /path/to/acl/file
The ACL file format looks like this:
user <username>
topic [read|write|readwrite] <topic>
You can have multiple topic lines per user.
Details of how to enable user authentication is also in the man page.
Related
How do I configure emqx v3.2.1 that I used?
EMQX allows you to configure Access Control Lists to authorise access to topics.
See https://github.com/emqx/emqx/wiki/ACL-Design and https://docs.emqx.io/broker/v3/en/config.html#anonymous-authentication-and-acl-files
e.g. an acl.config file with:
{allow, {user, "testuser"}, subscribe, ["a/b/c", "d/e/f/#"]}.
{allow, {user, "admin"}, pubsub, ["a/b/c", "d/e/f/#"]}.
{deny, all}.
will allow the client testuser to subscribe to topics a/b/c and d/e/f/# only, while admin is allowed to publish and subscribe these topics.
I am trying to subscribe to multiple topic levels in the configuration file and the aim is whenever I launch the MQTT, the broker has those topics, after which when I enter a wild card it string compare and checks if the topic is on the broker and if yes it extracts the data and if not it jumps to the next branch level
I have tried to write a level topic tree but dont know how to subscribe in the config file, as I am most sure if mosquitto.subscribe will work there or not
Below shows the snippet of the topic tree,
tree is the root node,
sub_branch = tree/sub_branch;
sub_branch_1 = tree/sub_branch_1;
branch_1 = tree/branch/branch_1;
branch_2 = tree/branch/branch_2;
After launch, the topics are on the broker and I use wildcard
tree/#;
this should give me data for all the branches
and if topic = tree/ranch; its an error(wrong topic) and ask for the next one
Any help is much much appreciated!
You do NOT configure topics on the broker, the broker has no knowledge of what topics a client might publish messages to or what topics a client might subscribe to (apart from in any Access Control Lists).
As far as the broker is concerned topics don't exist until a client publishes a message, at which point it does the following things in order:
Checks the ACL for that user/client if one exists to see if there is a pattern matching the incoming topic and accepts or discards the message if there is a match
Assuming it accepts the message it then searches the list of topic patterns for all subscribed clients.
If there is a match for a client it checks that client's/user's ACL to see if there is a match and if allowed sends that message to the client.
I would like to have a "default" client that gets all MQTT messages on topics that no one subscribed to. Is that possible?
I read about $SYS topics but they don't seem to provide a solution.
No, it is not possible to know what topics every other client is subscribed to easily/in a browser independent way. You may be able to build a list of what topics clients are subscribed to from the info in the $SYS/# topic tree on some broker implementations, but that won't help you find the inverse, which is what you are asking for.
The only option would be to subscribe with the wildcard topic of #. This would get all (assuming no ACLs in place) messages published to all topics.
If you could build the list I mentioned in the fist paragraph then you could use this as a filter.
How can I restrict publishing to only selected users on a Mosquitto MQTT broker?
I want some users to be able to subscribe, some other users to be able to publish and I need these two groups of users separated.
I know there is an authorization control that allows access with username:password. But it is not clear to me how to assign roles to users.
If there are no such role assignments, is setting different ports for publishers and subscribers possible?
The man page for the mosquitto config file covers all this.
The acl_file option specifies the file that holds the ACL list. The file contains groups of entries that control access to either a topic or pattern to match against a topic. e.g.
user user1
topic read foo/bar
user user2
topic readwrite foo/bar
This allows user1 to read from topic foo/bar and allows user2 to both read and write to the topic.
The password_file option can be used to specify the file to find username/password mappings. This file is edited with the mosquitto_passwd command, here is it's man page.
Both these options can be replaced by a plugin that provides an API to authenticate and authorize users. At the moment there is only one publicly available plugin that supports multiple different database backends to store user/acl data. You can find it here
Is it possible to that two clients are subscribed to same topic in MQTT broker. And based on authorization, some of the massages are sent to one client and not other (subscribed on same topic).
No
Any number of clients can be subscribed to a given topic, but you can not limit which of those clients can receive messages on that topic on a per message basis. It is all the topic or none.
There is no direct solution for this approach. But however I have a workaround for this solution.
Say you have two client with ClientId: 1 and 2
Say your topic structure is : stackoverflow/data/{Client-ID}/sensor/ingress
While defining the authorization parameter you can assert with the permission as +/+/{Client-ID}/+/+
This will make sure that, the topic structure will remain the same, but at the same time, the client will be able to publish and subscribe data only from their own topics.(topics which have their client-Id).