emqx / emqx-auth-jwt

EMQX JWT Authentication Plugin
https://www.emqx.com
Apache License 2.0
29 stars 24 forks source link

Some help with key/cert please... #121

Open citkane opened 4 years ago

citkane commented 4 years ago

EMQX v4.0.6 Ubuntu 18.04 - installed from repo

I am new to EMQX, and trying to set up jwt-auth from vanilla in a dev environment. I am following the docs.

emqx_auth_jwt.conf is:

# etc/plugins/emqx_auth_jwt.conf

## Key
auth.jwt.secret = emqxsecret

## The way the client carries the token
## Value: username | password
auth.jwt.from = password

## Advanced options
## Public key file, certificate is used when signing the key
auth.jwt.pubkey = etc/certs/jwt_public_key.pem

## Value: on | off
auth.jwt.verify_claims = off

## auth.jwt.verify_claims.$name = expected

## Variables:
##  - %u: username
##  - %c: clientid
# auth.jwt.verify_claims.username = %u

etc/certs/jwt_public_key.pem does not exist from clean install (Ubuntu 18.04), and I cannot find instructions for creating it from "emqxsecret".

I have tried:

  1. creating fresh private / public keys and using the new public.pem
  2. commenting out auth.jwt.pubkey = etc/certs/jwt_public_key.pem

But in all circumstances, when trying to start the emqx_auth_jwt plugin from dashboard, I am getting the following error:

{emqx_auth_jwt, {bad_return, {{emqx_auth_jwt_app,start,[normal,[]]}, {'EXIT', {{badmatch,{error,enoent}}, [{emqx_auth_jwt_app,read_pubkey,0, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,63}]}, {emqx_auth_jwt_app,auth_env,0, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,55}]}, {emqx_auth_jwt_app,start,2, [{file, "/emqx-rel/_build/emqx-pkg/lib/emqx_auth_jwt/src/emqx_auth_jwt_app.erl"}, {line,35}]}, {application_master,start_it_old,4, [{file,"application_master.erl"},{line,277}]}]}}}}}

I believe that this is not an error, but me missing some basic key/cert concept here, but I cannot find documentation to help get me up and running.

Thanks in advance...

citkane commented 4 years ago

I resolved the first of my issues: auth.jwt.pubkey = etc/certs/jwt_public_key.pem needs to locate to an absolute OS dir, it is not an alias or relative path.

For Ubuntu 18.04 install from repo: auth.jwt.pubkey = /etc/emqx/certs/jwt_public_key.pem

I am still struggling with the next one: What does jwt_public_key.pem do?

I am able to drop in any public cert at that filename, and:

  1. The emqx behaviour stays the same for the default JWT provided in the docs. (Client is authorised)
  2. I create a new HS256 JWT from the secret, which gives a much shorter string than the default JWT, and the client is still authorised.
  3. I create a new JWT from RSA 2048 private key (with corresponding public.pem in EMQX), and the client is not authorised.

I am guessing that the trick is to create a RSA private/public keypair from the HMAC Hash Secret which supports HS256 validation - but how do I do that???? The googling is now becoming EPIC...

citkane commented 4 years ago

Ok, solved..... Please excuse my temporary stupidity.

This is an either/or situation, so use either [HMAC HS256] OR [RSA / ECDSA]

So, using jose in node.js as an example:

const { 
    JWK: { generateSync, asKey },
    JWT 
} = require('jose');

//for HMAC
const secretKey = asKey('emqxsecret', {
    alg: 'HS256'
});
//OR for RSA
const privateKey = generateSync('RSA', 2048, {
    alg: 'RS256'
})
const publicKey = privateKey.toPEM()
console.log(publicKey); //this is /etc/emqx/certs/jwt_public_key.pem

//SIGN
const testToken = JWT.sign({
    test: 'test'
}, (privateKey || secretKey), {
    expiresIn: '1 day'
});

console.log(testToken); //the JWT token to be passed to EMQx
HJianBo commented 4 years ago

Sorry @citkane We are very busy these days.

The last logic is right, don't worry about that.