Simple and minimalist forward auth service intended for use with reverse proxies (Traefik, Caddy, nginx, etc)

Overview

nforwardauth

Actions status Docker Image Size Docker Image Version

nforwardauth is an extremely lightweight, blazing fast forward auth service that lets you use a single authentication middleware for all your sites. It is intended for use with reverse proxies like Traefik, Caddy, nginx, and others to allow/deny access via an auth wall.

Screenshot

Why nforwardauth?

The inspiration for nforwardauth came from my frustration with using basic auth as a simple way to protect my self-hosted server applications. I wanted something that was more user-friendly and streamlined, and that didn't require me to authenticate with every site and allowed me to autofill my passwords with my password manager.

I also wanted something that could be used in conjunction with other self-host server homepages like Homer and homepage. I was impressed with how Organizr's forwardauth worked, but I found it to be too complex and heavy for my needs. That's why I decided to create nforwardauth, a simple and lightweight alternative that gets the job done without any unnecessary bells and whistles.

How it works

Here is a simple illustration of how nforwardauth integrates with reverse proxies. (Note: you do not have to protect all sites with forwardauth as they don't have to be configured with the middleware):

Diagram

When you visit a route/host that is protected by nforwardauth, the server will first forward the request to nforwardauth which will check whether or not your request contains a valid access token. If your request does not, you will be redirected to the nforwardauth login page. Upon logging in, you will be redirected to the URI of your initial request.

nforwardauth uses a passwd file to store valid credentials. Currently, it only supports username and password combinations (similar to that of HTTP basic auth).

Getting started

How the passwd file works

nforwardauth uses a passwd file to store usernames and hashed passwords for authentication. To use nforwardauth, you'll need to create a passwd file and mount it as a volume when you run the container.

Here's an example of how to create an initial passwd file with a single user named test and the password test. We'll use the mkpasswd command to generate a sha-512 hashed version of the password and echo the username and hashed password into the passwd file.

echo "test:$(mkpasswd -m sha-512 test)" >> /path/to/passwd

The passwd file should contain one line per use in the format username:hased_password.

When you run the nforwardauth container, you should mount the passwd file as a volume with the -v option when using the command line, like this:

docker run -p 3000:3000 \
  -e TOKEN_SECRET=example-secret-123 \
  -e AUTH_HOST=nforwardauth.localhost.com \
  -v /path/to/passwd:/passwd \
  nosduco/nforwardauth:v1

With your passwd file mounted, nforwardauth will use it to authenticate users when they access sites with the forwardauth middleware. You will only need to login once to access all sites behind the middleware.

Simple configuration:

Here is a very simple configuration using Traefik v2 and protecting a simple whoami container behind the forwardauth middleware.

version: '3'

services:
  traefik:  # Basic traefik v2 configuration
    image: traefik:v2.9
    command: --providers.docker
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # Mount docker socket as read-only

  nforwardauth: # nforwardauth example configuration (for use behind HTTPS by default)
    image: nosduco/nforwardauth:v1
    environment:
      - TOKEN_SECRET=example-secret-123 # Secret to use when signing auth token
      - AUTH_HOST=nforwardauth.yourdomain.com # Where nforwardauth can be accessed/redirected to for login
    labels:
      - "traefik.http.routers.nforwardauth.rule=Host(`nforwardauth.yourdomain.com`)"
      - "traefik.http.middlewares.nforwardauth.forwardauth.address=http://nforwardauth:3000"
      - "traefik.http.services.nforwardauth.loadbalancer.server.port=3000"
    volumes:
      - "/path/to/passwd:/passwd:ro" # Mount local passwd file at /passwd as read only

  whoami: # whoami example container accessible at "whoami.yourdomain.com" behind nforwardauth middleware
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
      - "traefik.http.routers.whoami.middlewares=nforwardauth"

In the example, if you navigate to whoami.yourdomain.com you will be redirected to the nforwardauth login page. Once you sign in with valid credentials, you will be redirected back to whoami.yourdomain.com and subsequent visits to the site will not require a login.

Look at the examples directory in the repository or the below details section for more examples

For more advanced scenarios and configurations

Advanced configuration

Here is an example similar to the above above to support HTTP by using the available configuration properties

version: '3'

services:
  traefik: 
    image: traefik:v2.9
    command: --api.insecure=true --providers.docker
    ports:
      - "80:80" # HTTP port
      - "8080:8080" # Web UI port (enabled by --api.insecure=true)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # Mount docker socket as read-only

  nforwardauth:
    image: nosduco/nforwardauth:v1
    environment:
      - TOKEN_SECRET=example-secret-123 # Secret to use when signing auth token
      - COOKIE_SECURE=false # Do not set cookies as secure (WARNING: ONLY USE IN DEV OR LAN-ONLY HOSTS)
      - AUTH_HOST=nforwardauth.localhost.com # (required)
      - COOKIE_DOMAIN=localhost.com # Set domain for the cookies. This value will allow cookie and auth on *.yourdomain.com (including base domain)
      - COOKIE_NAME=nforwardauth # Set name for the cookie (helpful if running multiple instances of nforwardauth to prevent collision)
      - PORT=3000 # Set specific port to listen on 
    labels:
      - "traefik.http.routers.nforwardauth.rule=Host(`nforwardauth.localhost.com`)"
      - "traefik.http.middlewares.nforwardauth.forwardauth.address=http://nforwardauth:3000"
      - "traefik.http.services.nforwardauth.loadbalancer.server.port=3000"
    volumes:
      - "/path/to/passwd:/passwd:ro" # Mount local passwd file at /passwd as ready only

  whoami: # whoami example container accessible at "whoami.localhost.com" behind nforwardauth middleware
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.localhost.com`)"
      - "traefik.http.routers.whoami.middlewares=nforwardauth"

Available Evironment Variables

bold variables are required

Variable Description Type Default Example
AUTH_HOST URL where nforwardauth is accessible string N/A nforwardauth.yourdomain.com
TOKEN_SECRET Secret to use when signing the auth token string N/A example_secret_123
COOKIE_SECURE Whether or not to set cookies with secure flag boolean true false
COOKIE_DOMAIN Set the domain for the cookies, allow auth on sites beyond the root domain string Inferred by base url of AUTH_HOST mydomain.com
COOKIE_NAME Set name for the cookies. Helpful if running multiple instances to prevent collision string nforwardauth auth-token-1
PORT Set port to litsen on number 3000 80

Roadmap

Here are some current todo's for the project:

  • Find and fix bugs
  • Add CRSF token/cookie for protection
  • Better documentation and examples
  • Add built-in themes for login page
  • Documentation on how to write your own login page and mount at /public on the container
  • Improved error handling and logging
  • Futher integrations with proxies, loadbalancers, and homepage applications

If you have a suggestion or feature, please feel free to submit an issue and influence the list.

Contributing

If you find a bug or have a suggestion for how to improve nforwardauth or additional functionality, please feel free to submit an issue or a pull request. We welcome contributions from the community and are committed to making nforwardauth as useful as possible for everyone who uses it.

License

nforwardauth is released under the MIT license. please see the LICENSE file for details.

You might also like...
Make and use playgrounds locally.

cargo playground Cargo playground opens a local playground in the editor of your choice. Install You can install it directly using cargo $ cargo insta

rust database for you to use and help me make!

Welcome To Rust Database! What is this? this is a database for you to git clone and use in your project! Why should i use it? It is fast and it takes

An attempt to start documenting the rust sdk for temporal and how to use it following some of the examples in typescript

This is an attempt to start documenting the rust sdk for temporal and how to use it following some of the examples in typescript.

A tool to use docker / podman / oci containers with rust

contain-rs A tool to use docker / podman / oci containers with rust TODO improve error types improve error reporting handle std error for child proces

Small, clean, easy to use programming language

Thistle A modern, simplistic multi-paradigm language supporting object-oriented features Hello World! import IO object Main def main(): unit

A collection (eventually) of examples that use some non-beginner things.

nannou examples A collection (eventually) of examples that use some non-beginner things. Right now the only example combines nannou's standard draw AP

Demonstration of how to use the rust object_store crate

Introduction Demonstration of how to use the Rust object_store crate Example

Game development practices with Rust programming language. I want to use different crates for this.

Hazır Oyun Motorlarını Kullanarak Rust Dili Yardımıyla Oyunlar Geliştirmek Rust programlama dilinde oyun geliştirmek için popüler birkaç hazır çatıyı

A dos attack for you to use!

Welcome To Rust Dos attacker! Why should I use it? It has unrivaled speeds because it is built in rust and hand optimized. It also comes with an AI mo

Releases(v1.0.1)
Owner
Tony Duco
`kill -9 $(pidof everything_bad)`
Tony Duco
Fast fail2ban-like tools for parsing nginx logs

Fast2ban This is simple fail2ban-like replacement written in Rust. Usage: ./fast2ban # reads default config.toml from current directory ./fast2ban <co

null 36 May 10, 2023
Super-simple, fully Rust powered "memory" (doc store + semantic search) for LLM projects, semantic search, etc.

memex Super simple "memory" for LLM projects, semantic search, etc. Running the service Note that if you're running on Apple silicon (M1/M2/etc.), it'

Spyglass Search 15 Jun 19, 2023
A comprehensive and FREE Online Rust hacking tutorial utilizing the x64, ARM64 and ARM32 architectures going step-by-step into the world of reverse engineering Rust from scratch.

FREE Reverse Engineering Self-Study Course HERE Hacking Rust A comprehensive and FREE Online Rust hacking tutorial utilizing the x64, ARM64 and ARM32

Kevin Thomas 98 Jun 21, 2023
A bunch of links to blog posts, articles, videos, etc for learning Rust

rust-learning A bunch of links to blog posts, articles, videos, etc for learning Rust. Feel free to submit a pull request if you have some links/resou

Camille TJHOA 9k Jan 4, 2023
Reverse-engineered Rust client for Instagram's Threads app.

Instagram Threads API Unofficial, Reverse-Engineered Rust client for Instagram's Threads. Usage use threads_api::Threads; let client = Threads::new()

Miguel Piedrafita 66 Jul 12, 2023
Rust-based linux reverse shell listener.

Catch Rust-based linux reverse shell listener. Installation TODO: fix this installation guide, but this kinda works: mkdir /opt/catch/ cd /opt/catch/

Jazz 3 Aug 8, 2024
A simpler and 5x faster alternative to HashMap in Rust, which doesn't use hashing and doesn't use heap

At least 5x faster alternative of HashMap, for very small maps. It is also faster than FxHashMap, hashbrown, ArrayMap, and nohash-hasher. The smaller

Yegor Bugayenko 12 Apr 19, 2023
A tiny service that downloads files over HTTP links, with resume and restart support.

Http Drogue Http Drogue is a tiny service that downloads files over HTTP from links you provide. It can restart and resume interrupted downloads. Http

Kaan Barmore-Genç 4 Feb 27, 2023
Charted's email service built in Rust that can be connected via gRPC

email-service is a small microservice to help transfer emails towards other people without trying to implement it in different languages. This is used in charted-server for member invitations, passwordless authentication, and more.

charted 7 Mar 6, 2023
Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.

Speedy2D Hardware-accelerated drawing of shapes, images, and text, with an easy to use API. Speedy2D aims to be: The simplest Rust API for creating a

null 223 Dec 26, 2022