Setting up Authelia to work with Nginx Proxy Manager
Introduction
Every once in a while you'll have service that has does not have a user/password login. And though it doesn't perform anything critical or show anything crucial you would still like to put it behind something for your eyes only.
This is were Authelia comes in, it would sit between the user, usually you, and the service your trying to reach. Because we are also using a reverse proxy, in this case Nginx Proxy Manager by JC21 we have to make sure that all the DNS and subdomains get passed correctly.
I have previously went over deployment and configuration of NginxPM in this post: Docker Stack with Nginx and MariaDB.
Requirements
- Docker installed: [Post] or [Official]
- Nginx Proxy Manager installed: [Post] or [Official]
- Preferably have a domain and sub domains ready:
auth.domain.com
Docker Compose file
Below is the contents of the docker compose file, docker-compose.yml
, for Authelia.
version: '3.3'
networks:
frontend:
external: true
backend:
services:
authelia:
container_name: authelia-app
image: authelia/authelia:latest
volumes:
- ./config:/config
ports:
- 9091:9091
restart: unless-stopped
healthcheck:
disable: false
environment:
- TZ=America/Edmonton # Change to your timezone
depends_on:
- redis
networks:
- frontend
- backend
redis:
container_name: authelia-redis
image: redis:alpine
volumes:
- ./redis:/data
ports:
- 6378:6379
restart: unless-stopped
environment:
- TZ=America/Edmonton # Change to your timezone
networks:
- backend
The docker-compose.yml
file assumes a few things. first is that the external network frontend
exist and the second is that all container volumes are stored in a persistent volume. For organization its important to nest the docker-compose.yml
inside a folder usually named authelia
.
Before we can docker compose up -d
the file we need to do some prerequisite work first.
Configuration File
You're going to have to make and edit this configuration for your setup. This file also must be named: configuration and be nested into the Authelia
folder correctly.
To make a directory there and the file do the following:
mkdir docker/authelia/config;
nano docker/authelia/configuration.yml
The nesting should be like the following: home/user/docker/authelia/config/configuration.yml
.
##############################################################################
# Authelia configuration #
##############################################################################
server:
host: 0.0.0.0
port: 9091 # if you need this changed make sure it reflects also in the docker-compose.yml
log:
level: debug
jwt_secret: # Change me
default_redirection_url: https://auth.domain.com # Change me
totp:
issuer: domain.com # Change me
period: 30
skew: 1
#duo_api: ## If you want push notifictions of login attempts you can pay for this feature
# hostname: api-123456789.example.com
# integration_key: ABCDEF
# secret_key: yet-another-long-string-of-characters-and-numbers-and-symbols
authentication_backend:
disable_reset_password: false
file:
path: /config/users_database.yml # Make sure this file exists
password:
algorithm: argon2id
iterations: 1
salt_length: 16
parallelism: 8
memory: 64
access_control:
default_policy: deny
rules:
# Rules applied to everyone
- domain:
- "auth.domain.ca"
# - "some-app-with-api.yourdomain.com"
policy: bypass
- domain: # Proxies only requiring username and password
- "homepage.domain.com"
policy: one_factor
# networks:
# - 192.168.1.0/24
- domain: # Proxies needing 2 factor below
- "glances.domain.com"
# - "proxmox.yourdomain.com"
policy: two_factor
# networks:
# - 192.168.1.0/24
session:
name: authelia_session
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
secret: #change me
expiration: 3600 # 1 hour
inactivity: 7200 # 2 hours
domain: domain.com # Needs to be your root domain
redis:
host: authelia-redis
port: 6379
# This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE
password: authelia
regulation:
max_retries: 5
find_time: 2m
ban_time: 10m
theme: dark # options: dark, light
storage:
encryption_key: # change me
# The minimum length of this key is 20 characters.
local:
path: /config/db.sqlite3
notifier:
filesystem:
filename: /config/notification.txt
# smtp:
# username: <your-user@your-email-domain.org>
# password: <your-user-email-password-for-smtp>
# host: <your-email-host-url-or-ip>
# port: <your-email-port-for-smtp> # 25 non-ssl, 443 ssl, 587 tls
# sender: <sender@your-email-domain.org>
# subject: "[Authelia] {title}"
# disable_require_tls: false # set to true if your domain uses no tls or ssl only
# disable_html_emails: false # set to true if you don't want html in your emails
# tls:
# server_name: <your-email-host-url-or-ip>
# skip_verify: false
# minimum_version: TLS1.2
You will want to change the following lines to your own configuration:
Line 11 jwt_secret:
use openssl rand -hex 32
in a terminal to generate a 64 character random alphanumeric string.
Line 12 default_redirection_url:
, change this to your subdomain or domain that will be directed to Authelia. In this case it will be the subdomain https://auth.domain.com
.
Line 14 issuer:
, change this to your top level domain, in this case domain.com
Line 39 - "auth.domain.ca"
, change this to your auth URL. Leave the quotation marks.
Line 56 secret:
, change this to an alphanumeric string of at least 64 characters. You can use the previous command openssl rand -hex 32
to generate a different secret.
Line 66 password:
, generate a 64 character password.
Line 76 encryption_key:
, generate a key of at least 20 characters.access_control:
- You will enter the domain of services you want to put behind Authelia. Depending on where you place them, they will have different levels of authentication. For further granular control head to the official documentation on access_control.
Users Database file
You will also need to make a users_database.yml
that is nested in the config
folder you've previously made. You can use the following command to create a users_database.yml
inside of the config
folder.
nano docker/authelia/configuration.yml
Here's the layout of the users_database.yml
###############################################################
# Users Database #
###############################################################
# This file can be used if you do not have an LDAP set up.
# List of users
users:
JohnDoe:
displayname: "John Doe"
email: youremail@domain.com
# hash using docker run authelia/authelia:latest authelia hash-password SOMEPASSWORD
password: "$argon2id$v=19$m=65536,t=3,p=4$2fa01408014891e1020dc040e4839ed85706913abdabe13c95584003f4c9e88bfc"
groups:
- admins
- dev
JohnDoe
is the username during Authelia login.displayname
is how Authelia will display the user's name.email
for SMTP transactional emailspassword:
, you'll use docker run authelia/authelia:latest authelia hash-password SOMEPASSWORD
to generate a hashed password. SOMEPASSWORD
is the password you're going to use to login. I don't think it needs to be said but SOMEPASSWORD
should be change to a secure password then hashed. groups
is how you will give special access to users, remove groups if the user doesn't require them.
Nginx Proxy Manager Configuration (Authelia)
The nginx proxy syntax below will go in the advanced tab on the proxy host. To get there, do the following:
- Login to Nginx Proxy Manager
- Select Proxy Host
Add Proxy Host
Domain Names
field example: auth.domain.comscheme
is httpForward Hostname/IP
would be the container name or IP of the container. In our docker compose case:authelia-app
Forward Port
is 9091 or whatever you mapped- Enable
Block Common Exploits
andWebsockets Support
SSL
tab, get or assign the SSL certificate.- Enable
Froce SSL
,HTTP/2 Support
,HSTS Enabled
andHSTS subdomains
. Advanced
Tab and paste the following:
location / {
set $upstream_authelia http://IP.0.0.1:9091;
proxy_pass $upstream_authelia;
client_body_buffer_size 128k;
#Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# Advanced Proxy Config
send_timeout 5m;
proxy_read_timeout 360;
proxy_send_timeout 360;
proxy_connect_timeout 360;
# Basic Proxy Config
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
# If behind reverse proxy, forwards the correct IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from fc00::/7;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
Change Line 2: set $upstream_authelia
to your machine's LAN IP address or the container name, in this case http://IP.0.0.1:9091
;authelia-app
.Save
the Proxy Host.
Nginx Proxy Manager Configuration (Services)
With Authelia's proxy host setup we can now place Authelia between the web and services. To do so you would setup a proxy host as normal for your services or if you already have them running then it's just 1 more step.
In the Advanced
tab of the proxy host window you'll add the following after making changes to fit your services:
location /authelia {
internal;
set $upstream_authelia http://authelia-app:9091/api/verify; #ADD YOUR IP AND PORT OF AUTHELIA
proxy_pass_request_body off;
proxy_pass $upstream_authelia;
proxy_set_header Content-Length "";
# Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
client_body_buffer_size 128k;
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 4 32k;
send_timeout 5m;
proxy_read_timeout 240;
proxy_send_timeout 240;
proxy_connect_timeout 240;
}
location / {
set $upstream_dockerapp http://docker-app:61208; #CHANGE NAME AND IP AND PORT
proxy_pass $upstream_dockerapp; #change name of the service
auth_request /authelia;
auth_request_set $target_url $scheme://$http_host$request_uri;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
error_page 401 =302 http://auth.domain.com/?rd=$target_url; #change YOURDOMAIN.COM to your domain
client_body_buffer_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
send_timeout 5m;
proxy_read_timeout 360;
proxy_send_timeout 360;
proxy_connect_timeout 360;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
set_real_ip_from 192.168.1.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
Your going to have to change a few things in the Nginx syntax for services.
Line 3: set $upstream_authelia http://authelia-app:9091/api/verify;
Change the url to the IP of your server or the container name.
Line 33: set $upstream_glances http://docker-app:61208;
Change the value after the $upstream_
to a simple name of your service, example:docker
, homepage
, ghostblog
. Change the URL to the IP of your service or the container name.
Line 34: proxy_pass $upstream_docker;
Change the value after the $upstream_
to match Line 33.
Line 42: error_page 401 =302 http://auth.domain.com/?rd=$target_url;
Change the domain to your auth domain or subdomain.Save
the proxy host and visit the service.
Congrats You're Now Done and Ready for deployment.
For more documentation and help visit these resources:
Have fun and take care.