Reputation: 1
I am working with EMQX (version 5.8.0) Mqtt broker for an iot device application. Each device will act as a client and each of them will be publishing or subscribing to topics. But i want to restrict every client to publish and subscribe only on topics starting there own clientId/userName, like, topics would be like,
deviceId1/abc
deviceId2/abc
deviceId3/abc
wherein deviceId1 will be the username of the client
How can I restrict clients to do a pubs only on that particular topic and no one should be able to subscribe to my_device/# and hence receiving all messages.
I tried to add a new rule in the acl.conf file via a script which is triggered by a webhook on a new client connection but it requires restarting the emqx server which is not acceptable for me.
I also tried to handle this via a http server and emqx api but not got issues with the implementation. My server script for this goes like :
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
EMQX_API_URL = "http://localhost:8080/api/v5/acl/rules"
AUTH = ("admin", "admin_password")
@app.route('/acl', methods=['POST'])
def acl():
data = request.json
print(f"Received data: {data}")
client_id = data['clientid']
topic = data['topic']
action = data['action']
# Define ACL rule
acl_rule = {
"username": client_id,
"topic": topic,
"action": action
}
# Check if client_id matches the topic
if topic.startswith(client_id):
try:
response = requests.post(EMQX_API_URL, json=acl_rule, auth=AUTH)
response.raise_for_status()
if response.status_code == 200:
print(f"ACL rule created successfully: {acl_rule}")
return jsonify({"result": "allow"}), 200
else:
print(f"Failed to create ACL rule: {response.status_code}, {response.text}")
return jsonify({"result": "error", "message": "ACL rule creation failed"}), 500
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return jsonify({"result": "error", "message": "Request failed"}), 500
else:
return jsonify({"result": "deny"}), 403
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)`
I am not sure about the api url itself : http://localhost:8080/api/v5/acl/rules. Also, localhost:18083/api-docs does not list any api for acl management. What am I doing wrong? Also, is there better and easier to achieve this?
Upvotes: 0
Views: 150