mirror of
https://github.com/funkypenguin/geek-cookbook/
synced 2025-12-13 09:46:23 +00:00
Improve Authelia recipe
Signed-off-by: David Young <davidy@funkypenguin.co.nz>
This commit is contained in:
@@ -20,9 +20,17 @@ Features include
|
||||
* Authelia [Community](https://discord.authelia.com/) Support
|
||||
* Full list of features can be viewed [here](https://www.authelia.com/docs/features/)
|
||||
|
||||
--8<-- "recipe-tfa-ingredients.md"
|
||||
## Authelia requirements
|
||||
|
||||
## Preparation
|
||||
!!! summary "Ingredients"
|
||||
Already deployed:
|
||||
|
||||
* [X] [Docker swarm cluster](/docker-swarm/design/) with [persistent shared storage](/docker-swarm/shared-storage-ceph/)
|
||||
* [X] [Traefik](/docker-swarm/traefik/) configured per design
|
||||
|
||||
New:
|
||||
|
||||
* [ ] DNS entry for your auth host (*"authelia.yourdomain.com" is a good choice*), pointed to your [keepalived](/docker-swarm/keepalived/) IP
|
||||
|
||||
### Setup data locations
|
||||
|
||||
@@ -30,106 +38,113 @@ First, we create a directory to hold the data which authelia will serve:
|
||||
|
||||
```bash
|
||||
mkdir /var/data/config/authelia
|
||||
cd /var/data/config/authelia
|
||||
```
|
||||
|
||||
### Create config file
|
||||
### Create Authelia config file
|
||||
|
||||
Authelia configurations are defined in `/var/data/config/authelia/configuration.yml`. Some are required and some are optional. So begin by creating an empty configuration.yml file and add content to it as defined below. Optional configuration settings can be viewed on Authelia's [Documentation](https://www.authelia.com/docs/configuration/)
|
||||
Authelia configurations are defined in `/var/data/config/authelia/configuration.yml`. Some are required and some are optional. The following is a variation of the default example config file. Optional configuration settings can be viewed on in [Authelia's documentation](https://www.authelia.com/docs/configuration/)
|
||||
|
||||
!!! warning
|
||||
Your variables may vary significantly from what's illustrated below, and it's best to read up and understand exactly what each option does.
|
||||
|
||||
```yml
|
||||
###############################################################
|
||||
# Authelia configuration #
|
||||
###############################################################
|
||||
???+ note "Much scroll, very text. Click here to collapse it for better readability"
|
||||
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
```yaml
|
||||
###############################################################
|
||||
# Authelia configuration #
|
||||
###############################################################
|
||||
|
||||
log:
|
||||
level: warn
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
|
||||
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE
|
||||
# I used this site to generate the secret: https://www.grc.com/passwords.htm
|
||||
jwt_secret: SECRET_GOES_HERE
|
||||
log:
|
||||
level: warn
|
||||
|
||||
# https://docs.authelia.com/configuration/miscellaneous.html#default-redirection-url
|
||||
default_redirection_url: https://auth.example.com
|
||||
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE
|
||||
# I used this site to generate the secret: https://www.grc.com/passwords.htm
|
||||
jwt_secret: SECRET_GOES_HERE
|
||||
|
||||
totp:
|
||||
issuer: authelia.com
|
||||
period: 30
|
||||
skew: 1
|
||||
# https://docs.authelia.com/configuration/miscellaneous.html#default-redirection-url
|
||||
default_redirection_url: https://authelia.example.com
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
# customize passwords based on https://docs.authelia.com/configuration/authentication/file.html
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
salt_length: 16
|
||||
parallelism: 8
|
||||
memory: 1024 # blocks this much of the RAM. Tune this.
|
||||
totp:
|
||||
issuer: authelia.example.com
|
||||
period: 30
|
||||
skew: 1
|
||||
|
||||
# https://docs.authelia.com/configuration/access-control.html
|
||||
access_control:
|
||||
default_policy: one_factor
|
||||
rules:
|
||||
- domain: "*.example.com"
|
||||
policy: one_factor
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
# customize passwords based on https://docs.authelia.com/configuration/authentication/file.html
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
salt_length: 16
|
||||
parallelism: 8
|
||||
memory: 1024 # blocks this much of the RAM. Tune this.
|
||||
|
||||
- domain: "bitwarden.example.com"
|
||||
policy: two_factor
|
||||
# https://docs.authelia.com/configuration/access-control.html
|
||||
access_control:
|
||||
default_policy: one_factor
|
||||
rules:
|
||||
- domain: "bitwarden.example.com"
|
||||
policy: two_factor
|
||||
|
||||
session:
|
||||
name: authelia_session
|
||||
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
|
||||
# Used a different secret, but the same site as jwt_secret above.
|
||||
secret: SECRET_GOES_HERE
|
||||
expiration: 3600 # 1 hour
|
||||
inactivity: 300 # 5 minutes
|
||||
domain: example.com # Should match whatever your root protected domain is
|
||||
- domain: "whoami-authelia-2fa.example.com"
|
||||
policy: two_factor
|
||||
|
||||
regulation:
|
||||
max_retries: 3
|
||||
find_time: 120
|
||||
ban_time: 300
|
||||
|
||||
storage:
|
||||
encryption_key: SECRET_GOES_HERE
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
- domain: "*.example.com"
|
||||
policy: one_factor
|
||||
|
||||
|
||||
notifier:
|
||||
smtp:
|
||||
username: SMTP_USERNAME
|
||||
# This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
|
||||
# password: # use docker secret file instead AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
|
||||
host: SMTP_HOST
|
||||
port: 587 #465
|
||||
sender: SENDER_EMAIL
|
||||
session:
|
||||
name: authelia_session
|
||||
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
|
||||
# Used a different secret, but the same site as jwt_secret above.
|
||||
secret: SECRET_GOES_HERE
|
||||
expiration: 3600 # 1 hour
|
||||
inactivity: 300 # 5 minutes
|
||||
domain: example.com # Should match whatever your root protected domain is
|
||||
|
||||
# For testing purpose, notifications can be sent in a file. Be sure map the volume in docker-compose.
|
||||
# filesystem:
|
||||
# filename: /tmp/authelia/notification.txt
|
||||
regulation:
|
||||
max_retries: 3
|
||||
find_time: 120
|
||||
ban_time: 300
|
||||
|
||||
```
|
||||
storage:
|
||||
encryption_key: SECRET_GOES_HERE_20_CHARACTERS_OR_LONGER
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
|
||||
### Create User Accounts
|
||||
|
||||
notifier:
|
||||
# smtp:
|
||||
# username: SMTP_USERNAME
|
||||
# # This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
|
||||
# # password: # use docker secret file instead AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
|
||||
# host: SMTP_HOST
|
||||
# port: 587 #465
|
||||
# sender: batman@example.com # customize for your setup
|
||||
|
||||
# For testing purpose, notifications can be sent in a file. Be sure map the volume in docker-compose.
|
||||
filesystem:
|
||||
filename: /config/notification.txt
|
||||
```
|
||||
|
||||
### Create Authelia user Accounts
|
||||
|
||||
Create `/var/data/config/authelia/users_database.yml` this will be where we can create user accounts and give them groups
|
||||
|
||||
```yaml
|
||||
# To create a hashed password you can run the following command:
|
||||
# `docker run authelia/authelia:latest authelia hash-password YOUR_PASSWORD``
|
||||
users:
|
||||
username:
|
||||
displayname: "Funky Penguin"
|
||||
password: "HASHED_PASSWORD"
|
||||
email: myemail@example.com
|
||||
batman: # each new user should be defined in a dictionary like this
|
||||
displayname: "Batman"
|
||||
# replace this with your hashed password. This one, for the purposes of testing, is "password"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=4$cW1adlh3UjhIRE9zSmZyZw$xA4S2X8BjE7LVb4NndJCZnoyHgON5w3FopO4vw5AQxE"
|
||||
email: batman@example.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
@@ -138,102 +153,101 @@ users:
|
||||
To create a hashed password you can run the following command
|
||||
`docker run authelia/authelia:latest authelia hash-password YOUR_PASSWORD`
|
||||
|
||||
### Setup Docker Swarm
|
||||
### Authelia Docker Swarm config
|
||||
|
||||
Create a docker swarm config file in docker-compose syntax (v3), something like this:
|
||||
Create a docker swarm config file in docker-compose syntax (v3), something like this example:
|
||||
|
||||
--8<-- "premix-cta.md"
|
||||
|
||||
```yaml
|
||||
version: "3.2"
|
||||
???+ note "Much scroll, very YAML. Click here to collapse it for better readability"
|
||||
|
||||
```yaml
|
||||
version: "3.2"
|
||||
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia
|
||||
volumes:
|
||||
- /var/data/config/authelia:/config
|
||||
networks:
|
||||
- traefik_public
|
||||
deploy:
|
||||
labels:
|
||||
# traefik common
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik_public
|
||||
|
||||
# traefikv1
|
||||
- traefik.frontend.rule=Host:authelia.example.com
|
||||
- traefik.port=80
|
||||
- 'traefik.frontend.auth.forward.address=http://authelia:9091/api/verify?rd=https://authelia.example.com/'
|
||||
- 'traefik.frontend.auth.forward.trustForwardHeader=true'
|
||||
- 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
|
||||
|
||||
# traefikv2
|
||||
- "traefik.http.routers.authelia.rule=Host(`authelia.example.com`)"
|
||||
- "traefik.http.routers.authelia.entrypoints=https"
|
||||
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
|
||||
# - "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://authelia.example.com"
|
||||
# - "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
|
||||
# - "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups"
|
||||
|
||||
# This simply validates that traefik forward authentication is working
|
||||
whoami-1fa:
|
||||
image: containous/whoami
|
||||
networks:
|
||||
- traefik_public
|
||||
deploy:
|
||||
labels:
|
||||
# traefik
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_public"
|
||||
|
||||
# traefikv1
|
||||
- "traefik.frontend.rule=Host:whoami-authelia-1fa.example.com"
|
||||
- traefik.port=80
|
||||
- 'traefik.frontend.auth.forward.address=http://authelia:9091/api/verify?rd=https://authelia.example.com/'
|
||||
- 'traefik.frontend.auth.forward.trustForwardHeader=true'
|
||||
- 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
|
||||
|
||||
# traefikv2
|
||||
- "traefik.http.routers.whoami-authelia-1fa.rule=Host(`whoami-authelia-1fa.example.com`)"
|
||||
- "traefik.http.routers.whoami-authelia-1fa.entrypoints=https"
|
||||
- "traefik.http.routers.whoami-authelia-1fa.middlewares=authelia"
|
||||
- "traefik.http.services.whoami-authelia-1fa.loadbalancer.server.port=80"
|
||||
|
||||
|
||||
whoami-2fa:
|
||||
image: containous/whoami
|
||||
networks:
|
||||
- traefik_public
|
||||
deploy:
|
||||
labels:
|
||||
# traefik
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_public"
|
||||
|
||||
# traefikv1
|
||||
- "traefik.frontend.rule=Host:whoami-authelia-2fa.example.com"
|
||||
- traefik.port=80
|
||||
- 'traefik.frontend.auth.forward.address=http://authelia:9091/api/verify?rd=https://authelia.example.com/'
|
||||
- 'traefik.frontend.auth.forward.trustForwardHeader=true'
|
||||
- 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
|
||||
|
||||
# traefikv2
|
||||
- "traefik.http.routers.whoami-authelia-2fa.rule=Host(`whoami-authelia-2fa.example.com`)"
|
||||
- "traefik.http.routers.whoami-authelia-2fa.entrypoints=https"
|
||||
- "traefik.http.routers.whoami-authelia-2fa.middlewares=authelia"
|
||||
- "traefik.http.services.whoami-authelia-2fa.loadbalancer.server.port=80"
|
||||
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia
|
||||
volumes:
|
||||
- /var/data/config/authelia:/config
|
||||
networks:
|
||||
- traefik_public
|
||||
deploy:
|
||||
labels:
|
||||
# traefik common
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik_public
|
||||
|
||||
# traefikv1
|
||||
- traefik.frontend.rule=Host:auth.example.com
|
||||
- traefik.port=80
|
||||
- 'traefik.frontend.auth.forward.address=http://authelia:9091/api/verify?rd=https://auth.example.com/'
|
||||
- 'traefik.frontend.auth.forward.trustForwardHeader=true'
|
||||
- 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
|
||||
|
||||
# traefikv2
|
||||
- "traefik.http.routers.authelia.rule=Host(`auth.example.com`)"
|
||||
- "traefik.http.routers.authelia.entrypoints=https"
|
||||
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
|
||||
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.example.com"
|
||||
- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
|
||||
- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups"
|
||||
|
||||
# This simply validates that traefik forward authentication is working
|
||||
whoami:
|
||||
image: containous/whoami
|
||||
networks:
|
||||
- traefik_public
|
||||
deploy:
|
||||
labels:
|
||||
# traefik
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_public"
|
||||
|
||||
# traefikv1
|
||||
- "traefik.frontend.rule=Host:whoami.example.com"
|
||||
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
||||
- "traefik.frontend.auth.forward.address=http://authelia:9091/api/verify?rd=https://auth.example.com"
|
||||
- "traefik.frontend.auth.forward.authResponseHeaders=X-Forwarded-User"
|
||||
- "traefik.frontend.auth.forward.trustForwardHeader=true"
|
||||
|
||||
# traefikv2
|
||||
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
|
||||
- "traefik.http.routers.whoami.entrypoints=https"
|
||||
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.whoami.middlewares=forward-auth@file"
|
||||
traefik_public:
|
||||
external: true
|
||||
```
|
||||
|
||||
|
||||
networks:
|
||||
traefik_public:
|
||||
external: true
|
||||
```
|
||||
|
||||
### Traefik Configuration
|
||||
|
||||
Now that we have created authelia we will need to configure traefik so we can run authelia in front of our services. We will first need to create a traefik middleware in `/var/data/config/traefik/middlewares.yml`
|
||||
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
forward-auth:
|
||||
forwardAuth:
|
||||
address: "http://authelia:9091/api/verify?rd=https://auth.example.com"
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- "Remote-User"
|
||||
- "Remote-Groups"
|
||||
```
|
||||
|
||||
We will then need to add the following to `traefik.toml`
|
||||
|
||||
```yaml
|
||||
[providers.file]
|
||||
filename = "/etc/traefik/middlewares.yml"
|
||||
```
|
||||
|
||||
!!! Why not just use Traefik Forward Auth
|
||||
The default Traefik forward Auth is a very minimal authentication service that provides google and openID authentication. Authelia provides more features such as multiple methods of authentication (Hardware, OTP, Email) and push notifications.
|
||||
|
||||
Now if we wish to put authelia behind a service all we will need to do is add the following to the labels
|
||||
|
||||
`- "traefik.http.routers.service.middlewares=forward-auth@file"`
|
||||
!!! question "Why not just use Traefik Forward Auth?"
|
||||
[Traefik Forward Auth][tfa] is a very minimal authentication layer that provides google and openID authentication. Authelia provides more features such as multiple methods of authentication (*Hardware, OTP, Email*) and push notifications.
|
||||
|
||||
## Serving
|
||||
|
||||
@@ -241,12 +255,14 @@ Now if we wish to put authelia behind a service all we will need to do is add th
|
||||
|
||||
Launch the Authelia stack by running ```docker stack deploy authelia -c <path -to-docker-compose.yml>```
|
||||
|
||||
## Testing
|
||||
## Test Authelia
|
||||
|
||||
To test the service works successfully. Try to access a service that you had added the middleware label to. If it works successfully you will be presented with a login screen
|
||||
To test the service works successfully, try logging into authelia itself first, as a user whose password you've setup in `/var/data/config/authelia/users_database.yml`. You'll notice that upon successful login, you're requested to setup 2FA. You probably didn't configure an SMTP server, but the contents of the email request should be found in ``/var/data/config/authelia/notifications.txt`
|
||||
|
||||
{ loading=lazy }
|
||||
Now you're ready to test 1FA and 2FA auth, against the two "whoami" services defined in the docker-compose file.
|
||||
|
||||
[^1]: The inclusion of Authelia was due to the efforts of @bencey in Discord (Thanks Ben!)
|
||||
Try to access each in turn, and confirm that you're _not_ prompted for 2FA on whoami-authelia-1fa, but you _are_ prompted for 2FA on whoami-authelia-2fa ;)
|
||||
|
||||
[^1]: The initial inclusion of Authelia was due to the efforts of @bencey in Discord (Thanks Ben!)
|
||||
|
||||
--8<-- "recipe-footer.md"
|
||||
|
||||
Reference in New Issue
Block a user