Giter Site home page Giter Site logo

mosquitto-jwt-auth's Introduction

mosquitto-jwt-auth's People

Contributors

stefanfoulis avatar wiomoc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mosquitto-jwt-auth's Issues

Configuring mosquitto.conf

Sorry for posting here, i have few questions...

  1. i configured my mosquitto.conf like this:

auth_plugin /home/user/mosquitoplugin/mosquitto-jwt-auth-master/target/release/libmosquitto_jwt_auth.so

auth_opt_jwt_alg HS256
auth_opt_jwt_sec_file /home/user/secret.txt
auth_opt_jwt_validate_exp false
auth_opt_jwt_validate_sub_match_username false

in the secret.txt i put a simple string.

Is this ok ?

Also, what are those options stand for ?
auth_opt_jwt_sec_env
auth_opt_jwt_sec_base64

i thought only the secret specified here auth_opt_jwt_sec_file matters. Can you give me some advise ? i'm a bit lost :)

Documentation request / offer

Thanks for library - it's just my lack of experience I'm sure, but I'm struggling to get jwt auth working....

Would it be possible to add some pointers to newbies like myself - for example, how should the token be passed in? as username, password...? does it need to contain any particular claims to make things work? Is there any further reading material that I or others could be pointed to?

I've looked and looked but of course I might have missed something obvious...

I'm happy to help write/format some short guidance if only I could get it working myself... I do appreciate that this isn't probably your highest priority! but despite mosquito and this plug-in's popularity I can't find very much info on it. I failed to find a better way to communicate than raising an issue - please forgive or correct me.

And also I would very much like to have some sort of acl applied to the token presenting clients - any advice as to how this might be configured would also be really wonderful. I've got the standard acl working in mosquitto I was just wondering how they would be integrated - by clientID and using that as a pattern match in the acl perhaps?

Thanks you in advance, for all the work you've already done, and perhaps, in anticipation of being able to help me and others a tiny bit more!

Kindest regards

Gareth

Wich public key format to use with EC alg (ES256) ?

For RSA plublic key, I found that you should use a base 64 encoded DER using PKCS1.

In python, this is given by:

base64.b64encode(public_jwk.prepared_key.public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.PKCS1
))

Now I'm trying to switch to EC based keys, I first tried to use a JWKS file (see #13 ), bit it seems unsupported for now. Now I'm trying to use the auth_opt_jwt_sec_base64 option, but I'm not sure how to format the key, because PKCS1 is RSA only.

I tried this:

base64.b64encode(public_jwk.prepared_key.public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
))

But with that I always get ValidationError(InvalidSignature). I'm sure that the token I use are properly signed because I can validate them using the https://jwt.io/ provided tool.

ACL: Support for client id and username

Is it possible to add support for Username / Client ID in the ACLs?

Mosquitto Docs

%c to match the client id of the client
%u to match the username of the client

The patterns available for substition are:

    %c to match the client id of the client

    %u to match the username of the client

The substitution pattern must be the only text for that level of hierarchy. Pattern ACLs apply to all users even if the "user" keyword has previously been given.

Example:

pattern write sensor/%u/data

Allow access for bridge connection messages:

pattern write $SYS/broker/connection/%c/state

jwt_sec_file: Reload file for rotating public key support

First of all, thanks for this crate!

For a long running mosquitto instance, it might be beneficial if the jwt public key file can be re-loaded instead of only reading it in once at start. This is because a lot of jwt servers have rotating public keys.

I thought about a spawned thread somewhere around here:

file_contents

With either another option like "auth_opt_jwt_sec_reload_sec 3600" or a file watch mechanism.

The secret would no longer be in secret: Vec<u8> but in secret: ArcSwap<Vec<u8>> (see arc_swap crate). ArcSwap basically allows thread safe pointer swaps and exterior mutability.

WDYT?

Not able to publish after configuring jwt token

mosquitto_pub -h localhost -t test -m "hello world" -u "root" -P "eyJhbGciOiJIUzI1NiJ9.eyJVc2VybmFtZSI6InJvb3QiLCJleHAiOjE2NTU5MDYwODcsImlhdCI6MTY1NTY0Njg4N30.LVRjr3uW_VZv_hbBQUijGELVgKkEZSGdSOBOR0L2EPo" -p 8083

When I publish, I am getting
Error: The connection was lost.
I am able to subscribe to it with JWT Token.

Do I need to configure ACL for this as I currently have no ACL file?

Mosquitto crashes when attempting login with jwt in username

I've experienced mosquitto crashing when I try to login without a password and use the jwt as username.

Being able to login in this way is useful when all we want to give the clients is a single "api-key".

I experienced this with the paho library (on python). I've not tried any other libraries yet.
https://www.eclipse.org/paho/clients/python/docs/#username-pw-set

If it does not turn out to be obvious where the error is happening, I can try to make an easier to reproduce example.

Wildcardsubscribtion is not working

I created the following JW Token. This should allow to subscribe to "test/#" but it dont.

Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjM5NDAwNTM3LCJleHAiOjE2Mzk2MTY1MzcsInN1YnMiOlsidGVzdFwvIyJdfQ.bp7vzz-fKAt5nlZ-xZbXZ3yUIyui1WFEqtJaEmyXLtI

{
  "typ": "JWT",
  "alg": "HS256"
}.{
  "sub": "test",
  "iat": 1639400537,
  "exp": 1639616537,
  "subs": [
    "test/#"
  ]
}.[Signature]

Then try to use the Token with mosqutto_sub:

mosquitto_sub  -d -c -i shell -p 9000 -t "test/#" -u "test" -P "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjM5NDAwNTM3LCJleHAiOjE2Mzk2MTY1MzcsInN1YnMiOlsidGVzdFwvIyJdfQ.bp7vzz-fKAt5nlZ-xZbXZ3yUIyui1WFEqtJaEmyXLtI"
Client shell sending CONNECT
Client shell received CONNACK (0)
Client shell sending SUBSCRIBE (Mid: 1, Topic: test/#, QoS: 0, Options: 0x00)
Client shell received SUBACK
Subscribed (mid: 1): 128
Client shell sending DISCONNECT
All subscription requests were denied.

Mosquitto Version: 2.0.14-0

Mosquitto Config

listener 9000 127.0.0.1
protocol mqtt
socket_domain ipv4
auth_plugin /usr/local/lib/libmosquitto_jwt_auth.so
auth_opt_jwt_alg HS256
auth_opt_jwt_sec_base64 RGFzIGlzdCBHZWhlaW0gNTE0
auth_opt_jwt_validate_exp true
auth_opt_jwt_validate_sub_match_username false

Expected: Subscription is ok
Actual: Subscription is deny with 0x80

MS Azure AD jwks integration

I am trying to validate MS Azure AD generated JWT tokens using jwks. However biscuit is throwing error decoding jwt: ValidationError(MissingAlgorithm). Since MS AD jwks doesn't contain alg field I am not sure if the error is due to that. Does this library work with MS Azure AD jwks? If so could you please share more details on how to integrate? Just to add I a testing on docker image of mosquitto eclipse.

Cannot load plugin

Load error: Error loading shared library libgcc_s.so.1: No such file or directory (needed by /mosquitto/plugins/libmosquitto_jwt_auth.so)

used Prebuild version for Linux

recommended way to install mosquitto-jwt-auth in docker

I am new to mosquitto and rust and am probably just missing some very obvious information.
I couldn't figure out yet how to install this plugin.
I am currently using the official docker image
.

Ideally I'd like to use the official image and just add a few layers to it to install this plugin.

I've seen other plugins install themselves using git clone and make, however this plugin does not have a Makefile.
Here I see there seems to be a cargo package. However if I do cargo install mosquitto-jwt-auth I get this error:

Step 6/11 : RUN cargo install mosquitto-jwt-auth
 ---> Running in f96144d4d563
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading mosquitto-jwt-auth v0.2.0
  Installing mosquitto-jwt-auth v0.2.0
error: specified package has no binaries
ERROR: Service 'mqtt' failed to build: The command '/bin/sh -c cargo install mosquitto-jwt-auth' returned a non-zero code: 101

ACL doesn't allow subscriptions to topics with wildcards, even if permissions would allow it

Hi! I was delighted to find this plugin, which seems like exactly what I need for a project I'm working on.
However, in the particular way I'm using it, it's exhibiting some behavior that's unexpected (to me at least)... not sure if it's a bug, or if I'm misunderstanding how this behavior is supposed to work.

So when the user authenticates against my web app, it looks up which "room" the user is supposed to have access to, and issues them a JWT that gives them permission to publish and subscribe to any topic under that room ID, using a multi-level wildcard:

{
  "iat": 1588141196,
  "exp": 1588227596,
  "sub": "d2925b0f-23ce-42ee-9a0e-f3779d3970bd",
  "publ": [
    "1/#"
  ],
  "subs": [
    "1/#"
  ]
}

When the client connects to Mosquitto, they present the token, and are successfully authenticated. Then they attempt to subscribe to 1/#, but the subscription doesn't seem to work.

It seems that mostquitto-jwt-auth is rejecting the subscription to 1/#, even though the user is presenting a token that gives them subs permission to 1/#.

Just to double-check that this is what the plugin is doing, and not a configuration error on my party, I tweaked one of the unit tests to test my use case:

    #[test]
    fn test_acl_check() {
        let mut instance = MosquittoJWTAuthPluginInstance::new();
        instance.config = Some(MosquittoJWTAuthPluginConfig {
            validation: Validation::default(),
            validate_sub_match_username: true,
            secret: Vec::new(),
        });

        let client_id0 = 33 as ClientID;

        instance.client_permissions.insert(
            client_id0,
            Permissions {
                r#pub: Vec::new(),
                sub: vec![
                    topic_utils::parse_topic_path("1/#", true).unwrap(),
                ],
            },
        );

        let result = instance.acl_check(client_id0, AclType::Subscribe, "1/#");
        assert_eq!(result, Ok(()));
    }

This test fails, returning Err(()) instead of Ok(()).

I should also note that this behavior seems to differ from the normal ACL behavior for Mosquitto. If I create an acl_file like this:

user testuser
topic readwrite 1/#

... the user seems to be able to subscribe to all topics under 1/ using 1/#

Public API of mosquitto-jwt-auth exposes UB to safe code

For example, the following safe program leads to mosquitto-jwt-auth performing Undefined Behavior:

// [dependencies]
// mosquitto-jwt-auth = "0.2.0"

fn main() {
    mosquitto_jwt_auth::mosquitto_sys::mosquitto_auth_plugin_init(
        0xdeadbeefusize as _,
        0xcafebabeusize as _,
        100,
    );
}
Segmentation fault (core dumped)

In general it is unsound for a safe API to result in UB.

Set the username from a claim field and use mosquitto ACL %c

Hi,

Is there a way to set the username from a claim field?
For instance i have a jwt token like that:

{
  "user_name": "[email protected]",
  "creationDate": "2020-10-28T15:33:30.792732Z",
  "client_id": "nebowebap_cloudtest",
  "aud": [
    "MyScriptSSO"
  ],
  "scope": [
    "read"
  ],
  "exp": 1605108810, 
  "jti": "723efff8-5d75-44a9-91c1-ff4430a615d8",
}

And i would like %c matches with the "user_name" field's value. (https://medium.com/jungletronics/mosquitto-acls-ac062aea3f9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.