1
0
mirror of https://github.com/funkypenguin/geek-cookbook/ synced 2025-12-12 17:26:19 +00:00
Files
geek-cookbook/docs/docker-swarm/authelia.md
David Young 31be95b704 Fix (some) broken links
Signed-off-by: David Young <davidy@funkypenguin.co.nz>
2023-02-07 13:13:28 +13:00

11 KiB

title, description
title description
Using Authelia to secure services in Docker Authelia is an open-source authentication and authorization server providing 2-factor authentication and single sign-on (SSO) for your applications via a web portal.

Authelia in Docker Swarm

Authelia is an open-source authentication and authorization server providing 2-factor authentication and single sign-on (SSO) for your applications via a web portal. Like [Traefik Forward Auth][tfa], Authelia acts as a companion of reverse proxies like Nginx, Traefik, or HAProxy to let them know whether queries should pass through. Unauthenticated users are redirected to Authelia Sign-in portal instead. Authelia is a popular alternative to a heavyweight such as [KeyCloak][keycloak].

Authelia Screenshot{ loading=lazy }

Features include

  • Multiple two-factor methods such as
  • Lockout users after too many failed login attempts
  • Highly Customizable Access Control using rules to match criteria such as subdomain, username, groups the user is in, and Network
  • Authelia Community Support
  • Full list of features can be viewed here

Authelia requirements

!!! 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

First, we create a directory to hold the data which authelia will serve:

mkdir /var/data/config/authelia

Create Authelia config file

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

!!! 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.

###############################################################
#                   Authelia configuration                    #
###############################################################

server:
  host: 0.0.0.0
  port: 9091

log:
  level: warn

# 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

# https://docs.authelia.com/configuration/miscellaneous.html#default-redirection-url
default_redirection_url: https://authelia.example.com

totp:
  issuer: authelia.example.com
  period: 30
  skew: 1

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.

# https://docs.authelia.com/configuration/access-control.html
access_control:
  default_policy: one_factor
  rules:
    - domain: "bitwarden.example.com"
      policy: two_factor

    - domain: "whoami-authelia-2fa.example.com"
      policy: two_factor      

    - domain: "*.example.com" # (1)!
      policy: one_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

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


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
  1. The wildcard rule must go last, since the first rule to match the request, wins

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

# To create a hashed password you can run the following command:
# `docker run authelia/authelia:latest authelia hash-password YOUR_PASSWORD``
users:
  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

To create a hashed password you can run the following command docker run authelia/authelia:latest authelia hash-password YOUR_PASSWORD

Authelia Docker Swarm config

Create a docker swarm config file in docker-compose syntax (v3), something like this example:

--8<-- "premix-cta.md"

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"
        
  whoami-1fa: # (1)!
    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: # (2)!
        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"

    networks:
      traefik_public:
        external: true 
  1. Optionally used to test 1FA authentication
  2. Optionally used to test 2FA authentication

!!! question "Why not just use Traefik Forward Auth?" While [Traefik Forward Auth][tfa] is a very lightweight, minimal authentication layer, which provides OIDC-based authentication, Authelia provides more features such as multiple methods of authentication (Hardware, OTP, Email), advanced rules, and push notifications.

Run Authelia

Launch the Authelia stack by running docker stack deploy authelia -c <path -to-docker-compose.yml>

Test Authelia

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. If (like me!) you didn't configure an SMTP server, you can still setup 2FA (TOTP or webauthn), and the setup link email instructions should be found in /var/data/config/authelia/notifications.txt

Now you're ready to test 1FA and 2FA auth, against the two "whoami" services defined in the docker-compose file.

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! 👍

Summary

What have we achieved? By adding a simple label to any service, we can secure any service behind our Authelia, with minimal processing / handling overhead, and benefit from the 1FA/2FA multi-layered features provided by Autheila.

!!! summary "Summary" Created:

* [X] Authelia configured and available to provide a layer of authentication to other services deployed in the stack

Authelia vs Keycloak

[KeyCloak][keycloak] is the "big daddy" of self-hosted authentication platforms - it has a beautiful GUI, and a very advanced and mature featureset. Like Authelia, KeyCloak can use an LDAP server as a backend, but unlike Authelia, KeyCloak allows for 2-way sync between that LDAP backend, meaning KeyCloak can be used to create and update the LDAP entries (Authelia's is just a one-way LDAP lookup - you'll need another tool to actually administer your LDAP database).

--8<-- "recipe-footer.md"