0
votes

I am using mosquitto version 1.4.10 with tls-certificate. I am using this plugin https://github.com/mbachry/mosquitto_pyauth to authorize a user.And it works well for mosquitto_pub ( as in, when someone tries to publish , it gets authorized by the module first ).

However, it seems that mosquitto_sub is able to subscribe to anything without authorizing. How do I force security when someone is just trying to access a topic in read only mode?

I went through the mosquitto.conf file and cant seem to find anything related to this.

for example, I am able to subscribe like this:

mosquitto_sub --cafile /etc/mosquitto/ca.crt --cert /etc/mosquitto/client.crt --key /etc/mosquitto/client.key -h ubuntu -p 1883 -t c/# -d

and able to see messages coming from some publisher like this:

mosquitto_pub --cafile /etc/mosquitto/ca.crt --cert /etc/mosquitto/client.crt --key /etc/mosquitto/client.key -h ubuntu -p 1883 -t c/2/b/3/p/3/rt/13/r/123 -m 32 -q 1

What I am trying to do is prevent mosquitto_sub reading all messages at root level without authorization .

the python code that does the authorization looks like this : ( auth data is stored in cassandra db )

import sys
import mosquitto_auth

from cassandra.cluster import Cluster
from cassandra import ConsistencyLevel


## program entry point from mosquitto...
def plugin_init(opts):
    global cluster, session, select_device_query
    conf = dict(opts)
    cluster = Cluster(['192.168.56.102'])
    session = cluster.connect('hub')
    select_device_query = session.prepare('SELECT * from devices where uid=?')
    select_device_query.consistency_level = ConsistencyLevel.QUORUM
    print 'Cassandra cluster initialized'


def acl_check(clientid, username, topic, access):

    device_data = session.execute(select_device_query, [username])

    if device_data.current_rows.__len__() > 0:
        device_data = device_data[0]
        # sample device data looks like this :
        # Row(uid=u'08:00:27:aa:8f:91', brand=3, company=2, device=15617, property=3, room=490, room_number=u'3511', room_type=13, stamp=datetime.datetime(2016, 12, 12, 6, 29, 54, 723000))
        subscribable_topic = 'c/' + str(device_data.company) \
                             + '/b/' + str(device_data.brand) \
                             + '/p/' + str(device_data.property) \
                             + '/rt/' + str(device_data.room_type) \
                             + '/r/' + str(device_data.room) \
                             + '/#'

        matches = mosquitto_auth.topic_matches_sub(subscribable_topic, topic)
        print 'ACL: user=%s topic=%s, matches = %s' % (username, topic, matches)
        return matches

    return False

function acl_check seems to be always called when mosquitto_pub tries to connect, but never called when mosquitto_sub connects. the C code behind this python module is here: https://github.com/mbachry/mosquitto_pyauth/blob/master/auth_plugin_pyauth.c

1
I assume you mean mosquitto_sub not mosquitto_pub in the second paragraph - hardillb
my bad..yes, i meant mosquitto_sub - Shrouk Khan
You might want to include the python code as well so we can see how you've implemented the ACL - hardillb

1 Answers

0
votes

add the following to your mosquitto.conf

...
allow_anonymous false
...

This will stop users without credential from logging on to the broker.

You can also add an acl rule for the anonymous user if there are certain topics you would want unauthenticated clients to be able to see.