Restrict MQTT Broker


#1

Hello @brocaar!

I am working on your LoRa project and I was wondering if you could give me any help. I think this could be done even in a new version of it. Let me explain my point.

As you know, the current version uses a specific topic in order to users read and write data, which is stored in database. For instance, if user wants to get data from an application’s nodes, it has to subscribe on application/+/node/+/rx topic. If so, user can read all messages nodes send to broker.

This user was added by accessing LoRa App-server web-based system. Same for a hipotetical application. If we define allow_annonimous to true in /etc/mosquitto/conf.d/local.conf file, any user could read this topic. It’s known that if we define this configuration to false, only users allowed in ACL file could access this topic.

Now let’s suppose my system needs to create many users on demand. It’s not a god thing to keep editing ACL file when a new user is created or even removed. As I can see, lora-app-server has no filter for user or Client-ID, as ACL file needs.

System could have a feature to restrict access of all data to every user. I mean, if user “A” was created to have control of application “X”, this user should not have permission to access data from application “Y”.
I think there are two different options to restrict users to broker:

  1. Modify the server to make a relationship between each application and its users.
  2. Isolate current broker from outside users, create a new one which would be responsible for parsing application/+/node/+/rx topics and make a query in database to get the application and user related to that topic and finally publish that topic to connected and allowed users.

There is anything coming in next releases or perhaps you have any hint to accomplish this goal?
Thanks in advance.

Best regards"


Is Multi-Tenant supported by the architecture
#2

Hi, @RogerioCassares. There is indeed a way of controlling authentication and authorization other than with plain passwords and ACLs files for the mosquitto MQTT broker, and that is using a mosquitto auth plugin. The Loraserver’s project recommended configuration is described here:

https://docs.loraserver.io/install/mqtt-auth/

This configuration makes use of mosquitto-auth-plugin:

Some time ago I wrote a new plugin in Go (jpmens’ is written in C), specially intended for use with Loraserver project (though it grew to add more backends later), which implements some missing features and deals with a couple of issues present in the typical one. I’d be glad to help you configure it if you are willing to test it, and you can find it here:

Cheers!


#3

Hello @iegomez !

i really appreciate your indication and today i have read and implemented the things you have linked at loraserver.io !

This is the target! Exactly this plugin would work to we have almost everything done!

But since I follow exactly as described at jpmens’, there were some issues, for example when restarted the machine mosquitto had started and exit. I have to restart mosquitto.service to get the broker on. Somethings also like adding new user to the application and subscribing it on mosquitto, the auth was great and wrks but any data is received.

You had said that you developed a special way to connect with the LoRa Project. I am using loraserver_0.20 and lora-app-server_0.11. They are compatible with the project? I have to compile inside the machine or there is a way to generate a .deb? I just need to use JWT, postgres and Files just?

I am looking forward your contribution could help us to implement at our system!

Have a nice day!
Rogério


#4

Hi, @Rogerio.

To clarify, I didn’t develop a way to connect the first plugin with the loraserver project (well, initially I did by forking it and adding some features, but then I ditched that). What I developed is another plugin, which you can check at the second github link on my past comment, and it was created to be used with loraserver, lora-app-server and lora-gateway-bridge, though now it accepts a bunch of unrelated backends too.

there were some issues, for example when restarted the machine mosquitto had started and exit. I have to restart mosquitto.service to get the broker on.

That is a known issue with jpmens’ plugin, which @brocaar opened a long time ago: https://github.com/jpmens/mosquitto-auth-plug/issues/269. Basically, mosquitto starts before postgres, the plugin can’t connect and thus mosquitto exits. My plugin resolves this by waiting for a connection on startup (wether it is postgres, mysql or even redis, it doesn’t matter), and then just resuming with initialization once the connection is established.

I am using loraserver_0.20 and lora-app-server_0.11. They are compatible with the project?

Yep, the plugin is meant for mosquitto, so it doesn’t matter which versions of loraserver you are running.

I have to compile inside the machine or there is a way to generate a .deb?

The plugin must be compiled, but there’s a Makefile available that makes it pretty easy, so the process is quite simple: just clone the repository inside your Go path, cd into the directory and run the following commands.

This will get all Go packages dependencies that the plugin needs:

make requirements

This will build the plugin using Go’s buildmode. Also, it’ll build a utility binary, pg, which allows to create password hashes for the passwords file:

make

That’s it! Then you just need to give the path of the generated shared object (go-auth.so) to mosquitto.

I just need to use JWT, postgres and Files just?

Those are exactly the backends that I use for loraserver. Furthermore, jpmens’ plugin only allows JWT option through http, but for loraserver, it makes sense to use the token to get the user claims and directly query the same DB that loraserver uses instead of having to send a request to an API (though it allows it too), which is implemented in my plugin.

Configuration is pretty much the same as the recommended one. All configuration options are duly documented on the repo’s Readme, but -sensible information apart- here’s my configuration to give you an example (it includes redis as a backend too, but just omit it):

allow_anonymous false
auth_opt_log_level debug
auth_plugin /home/iegomez/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so
auth_opt_backends files, postgres, jwt, redis

auth_opt_plugin_path /home/iegomez/go/src/github.com/iegomez/mosquitto-go-auth/plugin/plugin.so

auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

auth_opt_cache true
auth_opt_cache_reset true

auth_opt_pg_host localhost
auth_opt_pg_port 5432
auth_opt_pg_dbname appserver
auth_opt_pg_user my_db_user
auth_opt_pg_password my_db_password
auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

auth_opt_jwt_remote false
auth_opt_jwt_db postgres
auth_opt_jwt_secret my_jwt_secret
auth_opt_jwt_port 8080
auth_opt_jwt_host localhost
auth_opt_jwt_getuser_uri /api/mqtt_auth
auth_opt_jwt_superuser_uri /api/mqtt_superuser
auth_opt_jwt_aclcheck_uri /api/mqtt_acl
auth_opt_jwt_with_tls true
auth_opt_jwt_verify_peer false
auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1
auth_opt_jwt_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_jwt_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

auth_opt_redis_db 1

I’d recommend that you take a look at the readme on github to check what the plugin offers and how it works, then just clone and try to use it. If you meet any problems, have any doubts or suggestions, just reply in this topic so I can help you.


#5

Amazing!

Please ask me one more question.

Regarding the pw command, I read the pw-gen directory and understood the pw.go code, but I could not generate the correct passwords. I hope it’s not asking too much, but when I ran the ./pw -p “my_password” command, I could not get these to be the correct HASH passwords. Please, how could I generate this password.

Thank you so much!

Regards,

Rogerio


#6

What do you mean exactly with that? For example, this is what I get using my_password as pass:

iegomez@debian:~/go/src/github.com/iegomez/mosquitto-go-auth$ ./pw my_password
PBKDF2$sha512$100000$7skxMEH5lqY/8ov/1vz2JA==$TRwQrwHNsUkkiqfixteQX1RXuml/OEm+R31LamM/lvxx7sFG3NqTNR5k09BNO1mRd7vJmKQZ8mqZwScG/fmf7g==

Notice that it’s different from using “my_password”:

iegomez@debian:~/go/src/github.com/iegomez/mosquitto-go-auth$ ./pw "my_password"
PBKDF2$sha512$100000$/ep8nfgbCi1BRvCwpNkpSg==$SkEhvRnfI8yfAwmvpLMgXBvgcp10f67ZFcgapt23sC9rj9HxbSVfQrzWoirGJpIj14IuTDzgiZejmpajfmh+qA==

Also, hash iterations and algorithm (sha256 or sha512) may be set with flags -i and -a.


#7

Hello @iegomez,

I have been testing the implementations here but will no success yet.

At first I’ve read and study the Readme.md file.

So I have tryed out with your example changing the db name as the user . But there was no result.

So i read and read again carefully and then I have wrote just my needs:

#/etc/mosquitto/conf.d/mosquitto-auth-plug.conf:

#General options
allow_anonymous false
auth_plugin /home/smartcampus/go/src/github.com/iegomez/mosquitto-go-auth/auth-plug.so
auth_opt_backends files, postgres, jwt

#CACHE --> NOT USE!

#LOG LEVEL
auth_opt_log_level debug

#PREFIXES --> NOT USE!

#FILES
auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

#POSTGRESQL
auth_opt_pg_host localhost
auth_opt_pg_port 5432
auth_opt_pg_dbname db_name
auth_opt_pg_user user_name
auth_opt_pg_password password
auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id =$


#JWT
auth_opt_jwt_remote false
auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1

So here is my code to mosquitto.conf read.

I am hardly fighting against the passwords file

Supose that loraserver mqtt user has a password like loraserver, then I go to ~/go/src/github.com/iegomez/mosquitto-go-auth and run pw to generate my password for loraserver:

./pw loraserver

This generates the hashed password with sha512 as defaults with 1000 interactions, also as defaults.
I have tried to set -p as flag: ./pw -p loraserver

The hashed value then I copy and paste to /etc/mosquitto/mosquitto-auth-plug/passwords. Like bellow:

loraserver:PBKDF2$sha512$100000$HQElPt/L+2vkEaCmUo2iNA==$yyf7lncradC3r74Wd/iQTMtJPXoeMl6x9htpxEW1/7Amsj5W389GP8FMZ7nMZHzn1ncL+6Fit1Y3d5I+tCTjwA==

Then I restart mosquitto.service and the lora server rejects the auth WITH CONNECTION REFUSED

I have tried many times but no answer that works. JWT may be something wrong also in conffigurations…

Please can you check?

Would should am I doing wrong, please?

Thangs for the patient :confused: .


#8

Regarding the pw utility, I’m sorry, I made a mistake in my other replies. The error is that the -p flag is missing, so it is using the default empty string to generate the hash instead of the given password. It should be like this:

./pw -p your_password

As for JWT, you are indeed missing some options:

Option default Mandatory Meaning
jwt_db postgres N The DB backend to be used
jwt_secret Y JWT secret to check tokens
jwt_userquery Y SQL for users
jwt_superquery Y SQL for superusers
jwt_aclquery Y SQL for ACLs

#9

Hi @iegomez,

Still not great news yet :/:pensive:

I look to the auth_opt_jwt_

I kown that there is lines like comments, I was doing some tests.

However, reading the documentation I have realised the in my api version there wasnt "/api/ mqtt_auth/", "/api/mqtt_superuser" or "/api/mqtt_acl". That configuration have to enable the JWT plugin to work well.

These are my conf at Jwt file:

And in my https://localhost:8080/api there is nothing that seems like “/api/mqtt” as the configurations tells

Otherwise, many times when I restart jus with the line to load the plugin,

auth_plugin /home/roger/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so

mosquitto.service exit the services

May be the version of lora-app-server, that mine is not comming with "/api/mqtt" options?


#10

No, it’s not a problem with your version, lora-app-server doesn’t have those API methods. The idea is that any API that is able to check JWT tokens should work, and that could be implemented at the lora-app-server end (I did it that way to test it), but it could be any other public API as well, located anywhere and written in whatever language meets your needs. As long as the API is able to consume and respond in the configured ways, it’s ok.

That said, those options are needed only when using remote mode. If you wish to use local mode (by setting auth_opt_jwt_remote false) to check JWT directly against a postgres instance (in this case, lora-app-server’s DB), you only need to set the options that I mentioned in my previous reply and the postgres options needed to connect to the DB. So in your conf, uncomment the jwt queries and secret options.

Apart from that, I’d recommend starting mosquitto manually after stopping the service to check what is going on so we can debug any configuration errors.


#11

Hi @iegomez

Sorry being annoying, but i really want to run your plugin in the project:

Here is my /etc/mosquitto/conf.d/mosquitto-auth-plug.conf file:

    allow_anonymous false
    auth_opt_log_level debug 
    auth_plugin /home/roger/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so
    auth_opt_backends files, postgres, jwt

    #Files
    auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
    auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

    #POSTGRESQL
    auth_opt_pg_host localhost
    auth_opt_pg_port 5432
    auth_opt_pg_dbname loraserver_as
    auth_opt_pg_user loraserver_as
    auth_opt_pg_password loraserver_as
    auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
    auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
    auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

    #JWT
    auth_opt_jwt_remote false
    auth_opt_jwt_db postgres
#we really need secret here, as you coment above? 
    auth_opt_jwt_secret my_jwt_secret 
    auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1
    auth_opt_jwt_superquery select count(*) from "user" where username = $1 and is_admin = true
    auth_opt_jwt_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

So I restart mosquitto,service: sudo systemctl restart mosquitto.service

In file /var/log/mosquitto/mosquitto.log seems to be all right!

But when I do: sudo systemctl status mosquitto.service

Here is the log:

roger@roger-Inspiron-5447:~$ sudo systemctl status mosquitto.service 
● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
   Loaded: loaded (/etc/init.d/mosquitto; bad; vendor preset: enabled)
   Active: active (**exited**) since Sex 2018-02-02 17:57:11 -02; 1s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 5337 ExecStop=/etc/init.d/mosquitto stop (code=exited, status=0/SUCCE
  Process: 5349 ExecStart=/etc/init.d/mosquitto start (code=exited, status=0/SUC

Fev 02 17:57:11 roger-Inspiron-5447 systemd[1]: Starting LSB: mosquitto MQTT v3.
Fev 02 17:57:11 roger-Inspiron-5447 mosquitto[5349]:  * Starting network daemon:
Fev 02 17:57:11 roger-Inspiron-5447 mosquitto[5349]:    ...done.
Fev 02 17:57:11 roger-Inspiron-5447 systemd[1]: Started LSB: mosquitto MQTT v3.1

When I just comment the auth_pugin line at mosquitto-auth-plug.conf, not choosing the plugin, it appears running instead of exit

At the project I have done the make requirements and make commands to prepare the go env and install the application. But still not working.

I start to suspect it seems missing something to runs the project. But I hava done all the steps detailed. :confused: And read again and again, and Read all your replyes carefully.


#12

Hi, @RogerioCassares. It’s no problema at all, I’m glad to help getting it to work. If anything, I’m sorry that it’s giving you so much trouble, maybe I need to write some better documentation.

Yep, as with lora-app-server, the plugin needs to know the jwt secret in order to check the user claims.

Any problem on starting the plugin will be properly logged, specially on debug level, where it logs a lot of things. Of course you can check mosquitto service logs to see those (try ´sudo journalctl -u mosquitto -f -n 50´ to check more logging info), but I strongly recommend starting mosquitto manually to see the direct output (when debuggin, of course). Hopefully, it’s just a path typo, some missing options or something like that preventing the plugin from running. Try this to see what error is thrown:

sudo service mosquitto stop
sudo mosquitto -c /etc/mosquitto/mosquitto.conf

#13

Hello @iegomez

Many thanks for the commands that helps to see what is going on at mosquitto.conf.
Now we have more detailed issues.

I have noticed that there was some inconsistency by running the plugin in mosquito.

At first, my mosquitto-auth-plug.conf was:

allow_anonymous false
auth_opt_log_level debug 
auth_plugin /home/roger/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so
#auth_opt_backends files, postgres, jwt, redis
auth_opt_backends files, postgres, jwt

#Files
auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

#POSTGRESQL
auth_opt_pg_host localhost
auth_opt_pg_port 5432
auth_opt_pg_dbname loraserver_as
auth_opt_pg_user loraserver_as
auth_opt_pg_password loraserver_as
auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

#JWT
auth_opt_jwt_remote false
auth_opt_jwt_db postgres
auth_opt_jwt_secret IEGVsUTr1iN1rPRGhu7rCJaQy4TXz6ABc+rh6kdskKQ= 
auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1
auth_opt_jwt_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_jwt_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

So when I ran sudo mosquitto -c /etc/mosquitto/mosquitto.conf

INFO[0000] Got 4 users from passwords file.
            
INFO[0000] created aclrecord {gateway/+/stats 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/rx 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/tx 1} for user loragw
 
INFO[0000] created aclrecord {gateway/+/stats 1} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/tx 2} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/rx 1} for user loraserver
 
INFO[0000] created aclrecord {application/+/node/+/rx 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/join 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/ack 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/error 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/tx 1} for user loraappserver
 
INFO[0000] Got 11 lines from acl file.
                 
INFO[0000] Backend registered: Files
                   
INFO[0000] Backend registered: Postgres
                
INFO[0000] Backend registered: JWT
                     
ERRO[0000] No cache, got 

The apparent result seems to be ok, but with no cache configurated, because i did not configurated.

In log with mosquitto.log it was running and ok. But when I tried to connect to broker with mosquitto_sub in the localhost and even by other subhost of my network. The service of mosquitto was broken :confused:

So I have tried to write at mosquitto-auth-plug.conf above the cache set true .

auth_opt_cache true

Note that I can not do the reset cache because when I have used before, it erase all the activations on nodes in the LoRa Server.

So the log on sudo mosquitto -c /etc/mosquitto/mosquitto.conf was the following:

INFO[0000] Got 4 users from passwords file.
            
INFO[0000] created aclrecord {gateway/+/stats 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/rx 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/tx 1} for user loragw
 
INFO[0000] created aclrecord {gateway/+/stats 1} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/tx 2} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/rx 1} for user loraserver
 
INFO[0000] created aclrecord {application/+/node/+/rx 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/join 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/ack 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/error 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/tx 1} for user loraappserver
 
INFO[0000] Got 11 lines from acl file.
                 
INFO[0000] Backend registered: Files
                   
INFO[0000] Backend registered: Postgres
                
INFO[0000] Backend registered: JWT
                     
INFO[0000] Cache activated                              
INFO[0000] started cache redis client                   
Falha de segmentação (imagem do núcleo gravada)

Note that was some issue in the las line thas happens when I ran the mosquitto commands.

So I rebooted my machine and the error is detaild by as an Internal error on ubuntu thaht I can show you more info in the images bellow:

From that moment i cant start mosquitto with running status. Mosquitto always start with active(exit).

How can we solve this or get the debug that runs with auth_opt_log_level debug ?

The fatal error is **

“Mosquitto crashed with SIGSEGV in strlen()”

**

How can we proceed ?

Regards,

Rogério


#14

Hi, @RogerioCassares.

First, regarding Redis, you can change the default db so that it doesn’t get mixed with loraserver’s use. For example, this would set the plugin’s cache to Redis db 3:

auth_opt_cache_db 3

As for the segfault, I’m not quite sure what’s going on, I’ve never faced that error, but your report says that some packages need updating, namely gcc5-base and libstdc++6. Could you try updating them to see if that works?

I tried your conf file and there was a space after “debug”, so it wasn’t getting set correctly and the log level defaulted to “info”. I’ll correct that and push it to the repo, but in the meantime delete the offending space to get debug level logging.

EDIT: I just pushed the change to deal with whitespaces in some options.


#15

Hi @iegomez,

Thanks to notice the space after debug. I really did not realise.

So In order to make the update of packages, I ran sudo apt-get update and sudo apt-get upgrade

I also completely uninstall the mosquitto and have installed it again.

When I rebooted to apply the changes I got two system errors:

4

One applying to sudo and the other with mosquitto.

Then, in/etc/mosquitto/conf.d/mosquitto-auth-plug.conf did not work.

I ran again sudo mosquitto -c /etc/mosquitto/mosquitto.conf and get the same SIGSEGV error.

So I renamemosquitto-auth-plug.conf to mosquitto-auth-plug.conf.bak and restart mosquitto. From then, it was running ok on default.

Then I re-renamed mosquitto-auth-plug.conf.bak tomosquitto-auth-plug.conf

Restarting mosquitto and verifying status strangely it appears to running, i.e., it do not start but have to do some workaround maybe? It maybe maskink some other things ?

I wrote in .con file the opts cache db instance, so i have added redis at backends. But every time I start mosquitto I have my activations reseted yet.

Please take a look how the .conf file is:

allow_anonymous false
auth_opt_log_level debug
auth_plugin /home/roger/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so
auth_opt_backends files, postgres, jwt, redis 

    #Cache
    auth_opt_cache true
    **auth_opt_cache_reset true**
**    auth_opt_cache_db 3**

**    #Redis**
**    auth_opt_redis_db 3** 

    #Files
    auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
    auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

    #POSTGRESQL
    auth_opt_pg_host localhost
    auth_opt_pg_port 5432
    auth_opt_pg_dbname loraserver_as
    auth_opt_pg_user loraserver_as
    auth_opt_pg_password loraserver_as
    auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
    auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
    auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

    #JWT
    auth_opt_jwt_remote false
    auth_opt_jwt_db postgres
    auth_opt_jwt_secret IEGVsUTr1iN1rPRGhu7rCJaQy4TXz6ABc+rh6kdskKQ=
    auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1
    auth_opt_jwt_superquery select count(*) from "user" where username = $1 and is_admin = true
    auth_opt_jwt_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

Then, thesudo mosquitto -c /etc/mosquitto/mosquitto.conf

EDIT: Please let me know where debug generate from auth_opt_log_level debug is logged:


#16

You don’t need to add Redis to backends if you are only using it for cache, so remove it from the backends.

Also, it’s not necessary to wipe the cache on restart, so you could just set auth_opt_cache_reset false and it’ll work fine (individual cache entries are deleted when not used for some time anyway, which defaults to 30 seconds but may be changed in the conf).

Regarding the logs, you should see something like this (notice that now there are [DEBU] entries along with the [INFO] ones:

INFO[0000] Backend registered: Postgres
                
INFO[0000] Backend registered: JWT
                     
INFO[0000] No cache set.                                
DEBU[0004] checking user admin with backend Files
      
DEBU[0004] checking user admin with backend Postgres
   
DEBU[0004] user admin authenticated with backend Postgres

Also, they get saved as regular mosquitto logs, and you should see all logging when running mosquitto manually (i.e., with sudo mosquitto -c /etc/mosquitto/mosquitto.conf).

Try deleting redis from backends and the auth_opt_redis_db option and running it again to see what we get now.


#17

Hi @iegomez,

It seems we are reaching the goal :thinking:

So this is my .conf file:

allow_anonymous false
auth_opt_log_level debug
auth_plugin /home/roger/go/src/github.com/iegomez/mosquitto-go-auth/go-auth.so
auth_opt_backends files, postgres, jwt

#Cache
auth_opt_cache true
auth_opt_cache_reset false
auth_opt_cache_db 3

#Files
auth_opt_password_path /etc/mosquitto/mosquitto-auth-plug/passwords
auth_opt_acl_path /etc/mosquitto/mosquitto-auth-plug/acls

#POSTGRESQL
auth_opt_pg_host localhost
auth_opt_pg_port 5432
auth_opt_pg_dbname loraserver_as
auth_opt_pg_user loraserver_as
auth_opt_pg_password loraserver_as
auth_opt_pg_userquery select password_hash from "user" where username = $1 and is_active = true limit 1
auth_opt_pg_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_pg_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

#JWT
auth_opt_jwt_remote false
auth_opt_jwt_db postgres
auth_opt_jwt_secret IEGVsUTr1iN1rPRGhu7rCJaQy4TXz6ABc+rh6kdskKQ=
auth_opt_jwt_userquery select count(*) from "user" where username = $1 and is_active = true limit 1
auth_opt_jwt_superquery select count(*) from "user" where username = $1 and is_admin = true
auth_opt_jwt_aclquery select distinct 'application/' || a.id || '/#' from "user" u inner join organization_user ou on ou.user_id = u.id inner join organization o on o.id = ou.organization_id inner join application a on a.organization_id = o.id where u.username = $1 and $2 = $2

At sudo mosquitto -c /etc/mosquitto/mosquitto.conf:

INFO[0000] Got 4 users from passwords file.
            
INFO[0000] created aclrecord {gateway/+/stats 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/rx 2} for user loragw
 
INFO[0000] created aclrecord {gateway/+/tx 1} for user loragw
 
INFO[0000] created aclrecord {gateway/+/stats 1} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/tx 2} for user loraserver
 
INFO[0000] created aclrecord {gateway/+/rx 1} for user loraserver
 
INFO[0000] created aclrecord {application/+/node/+/rx 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/join 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/ack 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/error 2} for user loraappserver
 
INFO[0000] created aclrecord {application/+/node/+/tx 1} for user loraappserver
 
INFO[0000] Got 11 lines from acl file.
                 
INFO[0000] Backend registered: Files
                   
INFO[0000] Backend registered: Postgres
                
INFO[0000] Backend registered: JWT
                     
INFO[0000] Cache activated                              
INFO[0000] started cache redis client

There was no [DEBU] as you mentioned on your reply above.

Just being sure about the auth_opt_jwt_secret, it is the same of /etc/defaults/lora-app-server JWT_Secret, isn’t it?


#18

From that log, it seems to be working. If you try to connect to mosquitto, you should see some debug messages about the connection intent. Just try:

mosquitto_sub -h localhost -u admin -P admin -t 'application/#'

In the default lora-app-server installation, that should work and you’d see this message printed:

DEBU[0004] user admin authenticated with backend Postgres

Yep, it’s the same, as the plugin make the same check against a JWT token as lora-app-server does.


#19

hI @iegomez,

When I have made the request, at same time logging with my account of LoRaServer, not admin/admin, I could not see any difference in sudo mosquitto -c /etc/mosquitto/mosquitto.conf command. The log is really iqual to the reply before. Nothing was add. :frowning:

If some password do not exist, in mosquitto_sub will appears some connection refused or it just not return anything?

Because I wrote a different password and it returns anything. Even writing without user, it return anything, just wait for some payload.


#20

Did you pull from the repo to get the changes and recompiled?

As for mosquitto_sub, I think it’ll keep trying to subscribe when it gets rejected by mosquitto, whereas it’ll fail with Error: Connection refused when mosquitto is not running. In the first case, when your user/pass pair is incorrect, you should see something like this:

DEBU[0011] checking user admin with backend Files
      
DEBU[0011] checking user admin with backend Postgres
   
DEBU[0011] checking user admin with backend JWT
        
DEBU[0011] jwt parse error: token contains an invalid number of segments
 
INFO[0011] jwt get user error: token contains an invalid number of segments