Closed jpmens closed 4 months ago
I have changed my mind about the dynamic security plugin for Quicksetup: far too complex, not necessarily for us, but if we'd have to support the resulting configuration.
We might be able to simplify with some Ansible/Jinja templating which picks up specific user files and inserts them into the ACL where they belong.
This looks okay, using only Jinja templating:
----
{% for f in friends %}
# main: user={{ f.username }}
{% set fragment = "t/" + f.username + ".acl" %}
{% include fragment ignore missing %}
{% endfor %}
----
t/jjolie.acl
# --begin special for jjolie
topic read owntracks/jpmens/5s
topic read $SYS/#
# --end special for jjolie
----
# main: user=jane
# main: user=ck
# main: user=ck00
# main: user=bbb
# main: user=ccc
# main: user=jip
# main: user=jjolie
# --begin special for jjolie
topic read owntracks/jpmens/5s
topic read $SYS/#
# --end special for jjolie# main: user=iris
# main: user=iris
# main: user=iris
# main: user=andie
# main: user=huawei
# main: user=simu
# main: user=simu
----
user jip
topic readwrite owntracks/jip/#
topic read owntracks/+/+
topic read owntracks/+/+/event
topic read owntracks/+/+/info
# --begin special for jjolie
topic read owntracks/jpmens/5s
topic read $SYS/#
# --end special for jjolie
user iris
topic readwrite owntracks/iris/#
topic read owntracks/+/+
topic read owntracks/+/+/event
topic read owntracks/+/+/info
{% for f in friends %}
{{ f.username | mqtt_acl() }}
{% endfor %}
This filter tests if a fragement file for the specified username exists; if so it is read in, otherwise a default ACL for the particular user is emitted.
from ansible.errors import AnsibleFilterError
from string import Template
import os
def mqtt_acl(username):
acl = """
user $U
topic readwrite owntracks/$U/#
topic read owntracks/+/+
topic read owntracks/+/+/event
topic read owntracks/+/+/info
"""
path = os.path.join("t", "%s.acl" % username)
if os.path.exists(path):
with open(path, "r") as f:
acl = f.read()
return acl
return Template(acl).safe_substitute(U=username)
class FilterModule(object):
def filters(self):
return {
'mqtt_acl': mqtt_acl,
}
When Quicksetup configures a system, we create a
mosquitto.conf
which can, if necessary, be augmented by user-specific files dropped intoconf.d/
; these will be picked up during a Mosquitto restart.Assuming a user needs specific ACLs, however, we have no provision for specifying these. Bootstrapping creates a
mosquitto.acl
which, if necessary, is overwritten at each run.It's probably worth our while, long-term, to look at the dynamic security plugin which is auto-installed with the Debian Mosquitto package.