A simple nginx auth_request backend providing MFA and lockout mechanisms
Report Bug
·
Request Feature
Table of Contents
A simple self-hosted authentication backend for nginx. Has the following features:
- Multiple database backends (sqlite, mysql, postgres)
- Support for running in a cluster
- Faking logins and/or presenting a captcha after a given number of failed attempts from a given source
- Pure rust with
#![forbid(unsafe_code)]
- Proper handling of credential material. All passwords salted+peppered with argon2id
Instructions are provided below to install from source or install via package manager. Once ruuth is installed and configured, NGINX must be configured to use it as an authentication backend
Distro packages are provided where possible. For all other cases, project must be build/run from source
- Clone the repo
git clone https://github.com/outurnate/ruuth.git
- Build via cargo
cargo build --release
- Customize the config file. A template is provided at
pkg/ruuth.toml
- Start the server
./target/release/ruuth --config ./pkg/ruuth.toml run
- Download the RPM package
curl -OsSL https://github.com/Outurnate/ruuth/releases/download/v0.1.5/ruuth-0.1.5-1.x86_64.rpm
- Install the package
sudo rpm -i ruuth-0.1.5-1.x86_64.rpm
- Customize the config file
sudo vi /etc/ruuth.toml
- Enable and start the systemd service
sudo systemctl enable --now ruuth
Minimal sample configuration is provided below. You will want to consult your distro's provided nginx.conf
to ensure you do not overwrite any necessary customizations
worker_processes 1;
error_log /var/log/nginx/error.log;
error_log /var/log/nginx/error.log notice;
error_log /var/log/nginx/error.log info;
events { worker_connections 1024; }
# We define a shared backend definition that refers
# to the local/remote instance of ruuth. Update this
# to match your config file
upstream ruuth
{
server 127.0.0.1:3000;
}
http
{
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# This server block represents the resource we wish
# to secure. We define an internal-only validate
# route for NGINX to reach our auth server. We can
# define any number of these for different applications
server
{
listen 443 ssl http2;
server_name example.com;
ssl_certificate cert.pem;
ssl_certificate_key key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /validate
{
# We wish to ensure we do not unnecessarily expose ruuth to the internet
internal;
# Pass the validate path to the backend
proxy_pass http://ruuth/validate;
proxy_set_header Host $http_host;
# ruuth ignores the body, so we should discard it
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# We include the original IP for rate-limiting and blacklisting
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Lastly, we need to pass through cookies to ensure the validation
# handler is able to see the user's session cookie
auth_request_set $saved_set_cookie $upstream_http_set_cookie;
proxy_set_header Set-Cookie $saved_set_cookie;
}
# Setup auth_request and define the 401 handler
auth_request /validate;
error_page 401 @error401;
location @error401
{
# In place of a 401 error, we rewrite to a 302 that shows the login page
return 302 https://auth.example.com/?url=$scheme://$http_host$request_uri;
}
# Here's our dummy content
location /
{
root /usr/share/nginx/html;
index index.html index.htm;
}
}
# We define a single authentication server for serving
# the login/logout pages and handlers
server
{
listen 443 ssl http2;
server_name auth.example.com;
ssl_certificate cert.pem;
ssl_certificate_key key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /
{
# Pass the validate path to the backend
proxy_pass http://ruuth;
proxy_set_header Host $http_host;
# We include the original IP for rate-limiting and blacklisting
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
To add users to the database, use the following command
ruuth --config /etc/ruuth.toml add-user --username hblue
You will be prompted to set a password. Once the password is accepted, the TOTP secret URL will be shown. To disable the QR code on the terminal, use the following form
ruuth --config /etc/ruuth.toml add-user --username hblue --show-qr-code
Users can be deleted with the following command
ruuth --config /etc/ruuth.toml delete-user --username hblue
To reset the password for a user, use the following command
ruuth --config /etc/ruuth.toml reset-password --username hblue
To generate a new TOTP secret for a user, use the following command (also supports --show-qr-code
)
ruuth --config /etc/ruuth.toml reset-mfa --username hblue
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement"
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the GPLv3 License. See LICENSE.md
for more information.
Joe Dillon - @outurnate - [email protected]
Project Link: https://github.com/outurnate/ruuth