fablabbcn / smartcitizen-api

The Smart Citizen Engine
https://developer.smartcitizen.me
GNU Affero General Public License v3.0
10 stars 4 forks source link

Add device authentication at a mqtt broker level #133

Closed pral2a closed 5 years ago

pral2a commented 5 years ago

Currently, the MQTT broker accepts any device and is the application the one deciding if a message posted by a device is consumed or not. That opens important known vulnerabilities so its time to fix them soon.

The suggested implementation is based on the MQTT broker postgre plug-in also check the Github

The broker will connect to our main database and check on the devices table using device_token as a key.

/emq_auth_pgsql.conf can be configured as:

example docs:

auth.pgsql.auth_query = select password from mqtt_user where username = '%u' limit 1

our implementation:

auth.pgsql.auth_query = select device_token from devices where device_token = '%c' limit 1

%c should be client_id on the mqtt payload. See:

## Variables: %u = username, %c = clientid, %a = ipaddress

That should simply ensure the device can post to our broker, but nothing else will be validated. For example a user can get the other devices topics and replace their identity. For that reason we can try to add an access control list (ACL) approach, however, I am not fully sure this will work unless we do some changes on the client side, but let's try:

example docs:

auth.pgsql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'

our implementation:

auth.pgsql.acl_query = select allow, clientid, access, topic from mqtt_acl where clientid = '%c'

It them seems new mqtt_acl table will need to contain id, allow, ipaddr, username, clientid, access, topic. Properties ipaddr, username will not be used and will remain null. In fact, the only property we are interested in is topic where we will need to write the topics we want each clientid to be allowed to subscribe and/or publish. For example device_token AKA clientid 5a3ff5 will the topic property as /device/sck/5a3ff5/+ allowing him to pub and sub under this path. If wildcard + aren't supported, we will need to add all the subtopics for it.

⚠️ After writing all this I suggest we also try the HTTP plugin maybe it makes things easier for our workflow and we can always cache URLs to speed up performance.

We will need also to see how we set the rails app as a superuser so it can publish and subscribe to any topic. See default-acl-file on the main broker configuration.

pral2a commented 5 years ago

Closed and moved to https://github.com/fablabbcn/smartcitizen-api/issues/134