Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
goldyfruit committed May 1, 2022
1 parent f9e2413 commit 30de67f
Show file tree
Hide file tree
Showing 33 changed files with 863 additions and 1,253 deletions.
16 changes: 0 additions & 16 deletions .editorconfig

This file was deleted.

6 changes: 0 additions & 6 deletions .github/dependabot.yml

This file was deleted.

20 changes: 0 additions & 20 deletions .github/workflows/docker-publish.yml

This file was deleted.

15 changes: 0 additions & 15 deletions .github/workflows/merge-upstream.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
.idea/**
*.so
*.pem

dev/**
jwt.conf
1 change: 0 additions & 1 deletion .keepalive

This file was deleted.

49 changes: 9 additions & 40 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,44 +1,17 @@
FROM nginx:1.19.10-alpine as base
FROM nginx:alpine as base

FROM base as builder

ARG JWT_MODULE_PATH=/usr/local/lib/ngx-http-auth-jwt-module
ARG LIBJWT_VERSION=1.12.1

RUN mkdir -p $JWT_MODULE_PATH/src

RUN apk add --no-cache \
# nginx
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
curl \
gnupg \
libxslt-dev \
gd-dev \
# libjwt
jansson-dev \
autoconf \
automake \
libtool \
cmake \
check-dev

# BEGIN libjwt install
RUN mkdir libjwt \
&& curl -sL https://github.com/benmcollins/libjwt/archive/v${LIBJWT_VERSION}.tar.gz \
| tar -zx -C libjwt/ --strip-components=1 \
&& cd libjwt \
&& autoreconf -i \
&& ./configure \
&& make all \
&& make check \
&& make install
RUN apk add --no-cache gcc libc-dev make openssl-dev pcre-dev zlib-dev \
linux-headers curl gnupg libxslt-dev gd-dev jansson-dev autoconf \
automake libtool cmake check-dev \
-X http://dl-cdn.alpinelinux.org/alpine/edge/testing libjwt-dev

# NGINX_VERSION is a variable available within the nginx:alpine Docker image
RUN curl -fSL http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -o nginx.tar.gz \
&& mkdir -p /usr/src \
&& tar -zxC /usr/src -f nginx.tar.gz \
Expand All @@ -51,14 +24,10 @@ RUN cd /usr/src/nginx-${NGINX_VERSION} \
&& ./configure --with-compat --add-dynamic-module=$JWT_MODULE_PATH \
&& make modules

FROM base

ARG LIBJWT=libjwt.so.1.7.0
FROM nginx:alpine

COPY --from=builder /usr/src/nginx-${NGINX_VERSION}/objs/ngx_http_auth_jwt_module.so /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so
COPY --from=builder /usr/local/lib/${LIBJWT} /lib

RUN apk add --no-cache jansson \
&& sed -i '1iload_module modules/ngx_http_auth_jwt_module.so;' /etc/nginx/nginx.conf \
&& ln -s /lib/${LIBJWT} /lib/libjwt.so.1 \
&& ln -s /lib/${LIBJWT} /lib/libjwt.so
-X http://dl-cdn.alpinelinux.org/alpine/edge/testing libjwt \
&& sed -i '1iload_module modules/ngx_http_auth_jwt_module.so;' /etc/nginx/nginx.conf
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018
Copyright (c) 2022

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
11 changes: 0 additions & 11 deletions Makefile

This file was deleted.

177 changes: 83 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,122 +1,111 @@
[github-license-url]: /blob/master/LICENSE
[docker-url]: https://hub.docker.com/r/maxxt/nginx-jwt-module/
[![Alpine version](https://img.shields.io/badge/Alpine-Edge-green.svg?style=flat&logoColor=FFFFFF&color=87567)](https://alpinelinux.org/)
[![Nginx version](https://img.shields.io/badge/Nginx-1.21.6-green.svg?style=flat&logoColor=FFFFFF&color=87567)](https://nginx.org/en/)
[![Docker pulls](https://img.shields.io/docker/pulls/smartgic/nginx-jwt-module.svg?style=flat&logo=docker&logoColor=FFFFFF&color=87567)](https://hub.docker.com/r/smartgic/mnginx-jwt-module)
[![Discord](https://img.shields.io/discord/809074036733902888)](https://discord.gg/sHM3Duz5d3)

# Nginx jwt auth module
[![Build Status](https://img.shields.io/github/license/maxx-t/nginx-jwt-module.svg)][github-license-url]
[![Build Status](https://img.shields.io/docker/build/maxxt/nginx-jwt-module.svg)][docker-url]
[![Docker pulls](https://img.shields.io/docker/pulls/maxxt/nginx-jwt-module.svg)][docker-url]
# Nginx JWT authentication module

This is an NGINX module to check for a valid JWT.

Inspired by [TeslaGov](https://github.com/TeslaGov/ngx-http-auth-jwt-module), [ch1bo](https://github.com/ch1bo/nginx-jwt) and [tizpuppi](https://github.com/tizpuppi/ngx_http_auth_jwt_module), this module intend to be as light as possible and to remain simple.
- Docker image based on the [official nginx Dockerfile](https://github.com/nginxinc/docker-nginx) (alpine).
- Light image (~16MB).
Inspired by [TeslaGov](https://github.com/TeslaGov/ngx-http-auth-jwt-module) and [max-lt](https://github.com/max-lt/nginx-jwt-module) repositories.

## Module:
- Docker image based on the [official nginx Dockerfile](https://github.com/nginxinc/docker-nginx) _(Alpine)_.
- Light image _(~10MB compressed)_.

### Example Configuration:
```nginx
server {
auth_jwt_key "0123456789abcdef" hex; # Your key as hex string
auth_jwt off;
## NGINX Directives

location /secured-by-cookie/ {
auth_jwt $cookie_MyCookieName;
}
location /secured-by-auth-header/ {
auth_jwt on;
}
location /secured-by-auth-header-too/ {
auth_jwt_key "another-secret"; # Your key as utf8 string
auth_jwt on;
}
location /secured-by-rsa-key/ {
auth_jwt_key /etc/keys/rsa-public.pem file; # Your key from a PEM file
auth_jwt on;
}
This module requires several new `nginx.conf` directives, which can be specified in on the `main`, `server` or `location` level.

location /not-secure/ {}
}
```nginx
auth_jwt_key "646f6e2774207472792c206974277320612066616b6520736563726574203a29"; # see docs below for format based on algorithm
auth_jwt_loginurl "https://yourdomain.com/loginpage";
auth_jwt_enabled on;
auth_jwt_algorithm HS256; # or RS256
auth_jwt_validate_email on; # or off
auth_jwt_use_keyfile off; # or on
auth_jwt_keyfile_path "/app/pub_key";
```

> Note: don't forget to [load](http://nginx.org/en/docs/ngx_core_module.html#load_module) the module in the main context: <br>`load_module /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so;`
### Directives:

Syntax: auth_jwt $variable | on | off;
Default: auth_jwt off;
Context: http, server, location

Enables validation of JWT.<hr>
The default algorithm is `HS256`, for symmetric key validation. When using `HS256`, the value for `auth_jwt_key` should be specified in `hex` format. It is recommended to use at least 256-bits of data _(32 pairs of hex characters or 64 characters in total)_ as in the example above. Note that using more than 512-bits will not increase the security. For key guidelines please see NIST Special Publication 800-107 Recommendation for Applications Using Approved Hash Algorithms, Section 5.3.2 The HMAC Key.

Syntax: auth_jwt_key value [encoding];
Default: ——
Context: http, server, location
The configuration also supports the `auth_jwt_algorithm` `RS256`, for RSA 256-bit public key validation. If using `auth_jwt_algorithm RS256;`, then the `auth_jwt_key` field must be set to your public key **OR** `auth_jwt_use_keyfile` should be set to `on` with the `auth_jwt_keyfile_path` set to the public key path _(Nginx won't start if the `auth_jwt_use_keyfile` is set to `on` without a keyfile)_.

Specifies the key for validating JWT signature (must be hexadecimal).<br>
The *encoding* otpion may be `hex | utf8 | base64 | file` (default is `utf8`).<br>
The `file` option requires the *value* to be a valid file path (pointing to a PEM encoded key).
That is the public key, rather than a PEM certificate. I.e.:

<hr>

Syntax: auth_jwt_alg any | HS256 | HS384 | HS512 | RS256 | RS384 | RS512 | ES256 | ES384 | ES512;
Default: auth_jwt_alg any;
Context: http, server, location

Specifies which algorithm the server expects to receive in the JWT.
```nginx
auth_jwt_key "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0aPPpS7ufs0bGbW9+OFQ
RvJwb58fhi2BuHMd7Ys6m8D1jHW/AhDYrYVZtUnA60lxwSJ/ZKreYOQMlNyZfdqA
rhYyyUkedDn8e0WsDvH+ocY0cMcxCCN5jItCwhIbIkTO6WEGrDgWTY57UfWDqbMZ
4lMn42f77OKFoxsOA6CVvpsvrprBPIRPa25H2bJHODHEtDr/H519Y681/eCyeQE/
1ibKL2cMN49O7nRAAaUNoFcO89Uc+GKofcad1TTwtTIwmSMbCLVkzGeExBCrBTQo
wO6AxLijfWV/JnVxNMUiobiKGc/PP6T5PI70Uv67Y4FzzWTuhqmREb3/BlcbPwtM
oQIDAQAB
-----END PUBLIC KEY-----";
```

### Embedded Variables:
**OR**

Module supports embedded variables:
```nginx
auth_jwt_use_keyfile on;
auth_jwt_keyfile_path "/etc/nginx/pub_key.pem";
```

$jwt_header
A typical use would be to specify the key and loginurl on the main level and then only turn on the locations that you want to secure _(not the login page)_.
Unauthorized requests are given `302 "Moved Temporarily"` responses with a location of the specified `loginurl`.

returns whole header
```nginx
auth_jwt_redirect off;
```

$jwt_grant
If you prefer to return `401 Unauthorized`, you may turn `auth_jwt_redirect` to `off`.

returns whole grant
```nginx
auth_jwt_validation_type AUTHORIZATION;
auth_jwt_validation_type COOKIE=rampartjwt;
```

$jwt_header_name
By default the authorization header is used to provide a JWT for validation. However, you may use the `auth_jwt_validation_type` configuration to specify the name of a cookie that provides the JWT.

returns header.name
```nginx
auth_jwt_validate_email off;
```

$jwt_grant_name
By default, the module will attempt to validate the email address field of the JWT, then set the x-email header of the session, and will log an error if it isn't found. To disable this behavior, for instance if you are using a different user identifier property such as `sub`, set `auth_jwt_validate_email` to the value `off`.

returns grant.name
## Example

### Build:
This module is built inside a docker container, from the [nginx](https://hub.docker.com/_/nginx/)-alpine image.
In this example, the route `/` from `push.smartgic.io` listening on port `80` is protected by a JWT authentication. If the JWT is valid then, the request is redirected to https://pushgateway.appdomain.cloud. Only the `POST` is allowed.

```bash
./build.sh # Will create a "jwt-nginx" (Dockerfile)
```nginx
server {
listen 80;
server_name push.smartgic.io;
location / {
if ($request_method ~ ^(GET|PATCH|PUT|DELETE|OPTIONS|HEAD)$) {
return 403;
}
auth_jwt_key "646f6e2774207472792c206974277320612066616b6520736563726574203a29";
auth_jwt_enabled on;
proxy_set_header Host pushgateway.appdomain.cloud;
proxy_pass https://pushgateway.appdomain.cloud;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_buffering off;
}
}
```

### Test:
#### Default usage:
```bash
./test.sh # Will create a "jwt-nginx-test" image (from test-image/Dockerfile) based on the "jwt-nginx" one.
```
#### Set image name:
```bash
./test.sh your-image-to-test
```
example:
```bash
./test.sh jwt-nginx-s1 # tests the development image
```
#### Use current container:
```bash
./test.sh --current my-container
```
example:
```bash
# In a first terminal:
docker run --rm --name my-test-container -p 8000:8000 jwt-nginx-test
There is a complete example of JWT and TLS _(via Let's Encrypt)_ in the `examples` directory.

# In a second one:
./test.sh --current my-test-container
```
## Encode a `string` to `hex` using Python.

```python
key = "don't try, it's a fake secret :)".encode("utf-8")
print(key.hex())
646f6e2774207472792c206974277320612066616b6520736563726574203a29
```
19 changes: 0 additions & 19 deletions build.sh

This file was deleted.

2 changes: 1 addition & 1 deletion config
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ngx_addon_name=ngx_http_auth_jwt_module

ngx_module_type=HTTP
ngx_module_name=ngx_http_auth_jwt_module
ngx_module_srcs="$ngx_addon_dir/src/ngx_http_auth_jwt_module.c"
ngx_module_srcs="$ngx_addon_dir/src/ngx_http_auth_jwt_binary_converters.c $ngx_addon_dir/src/ngx_http_auth_jwt_header_processing.c $ngx_addon_dir/src/ngx_http_auth_jwt_string.c $ngx_addon_dir/src/ngx_http_auth_jwt_module.c"
ngx_module_libs="-ljansson -ljwt"

. auto/module
Loading

0 comments on commit 30de67f

Please sign in to comment.