From ff5d88f8abef922200c67c2757c9d7d653744ff9 Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 18 Jul 2025 11:20:51 +0200 Subject: [PATCH] Add Container Authelia --- ansible/playbooks/heyer.systems/docker1.yml | 6 + .../defaults/main.yml | 113 ++++++++++++++++++ .../deploy_container_authelia/files/.gitkeep | 0 .../handlers/main.yml | 0 .../deploy_container_authelia/meta/main.yml | 0 .../deploy_container_authelia/tasks/main.yml | 44 +++++++ .../templates/.env.j2 | 2 + .../templates/configuration.yml.j2 | 72 +++++++++++ .../templates/docker-compose.yml.j2 | 34 ++++++ .../templates/users.yml.j2 | 11 ++ .../deploy_container_authelia/vars/main.yml | 1 + 11 files changed, 283 insertions(+) create mode 100644 ansible/roles/deploy_container_authelia/defaults/main.yml create mode 100644 ansible/roles/deploy_container_authelia/files/.gitkeep create mode 100644 ansible/roles/deploy_container_authelia/handlers/main.yml create mode 100644 ansible/roles/deploy_container_authelia/meta/main.yml create mode 100644 ansible/roles/deploy_container_authelia/tasks/main.yml create mode 100644 ansible/roles/deploy_container_authelia/templates/.env.j2 create mode 100644 ansible/roles/deploy_container_authelia/templates/configuration.yml.j2 create mode 100644 ansible/roles/deploy_container_authelia/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/deploy_container_authelia/templates/users.yml.j2 create mode 100644 ansible/roles/deploy_container_authelia/vars/main.yml diff --git a/ansible/playbooks/heyer.systems/docker1.yml b/ansible/playbooks/heyer.systems/docker1.yml index b7d19a5..4e7f905 100644 --- a/ansible/playbooks/heyer.systems/docker1.yml +++ b/ansible/playbooks/heyer.systems/docker1.yml @@ -65,3 +65,9 @@ tags: - n8n - docker-container + - role: deploy_container_authelia + tags: + - authelia + - sso + - auth + - docker-container \ No newline at end of file diff --git a/ansible/roles/deploy_container_authelia/defaults/main.yml b/ansible/roles/deploy_container_authelia/defaults/main.yml new file mode 100644 index 0000000..dbaf64d --- /dev/null +++ b/ansible/roles/deploy_container_authelia/defaults/main.yml @@ -0,0 +1,113 @@ +############ +# Authelia # +############ + +# --------------------- +# General Configuration +# --------------------- +container_authelia_version: latest # Authelia container image tag/version +container_authelia_domain: authelia.example.com # Fully Qualified Domain Name (FQDN) for Authelia + +# --------------------- +# Server Settings +# --------------------- +container_authelia_server_port: 9091 # Port on which Authelia will listen + +# --------------------- +# Logging +# --------------------- +container_authelia_log_level: debug # Log level: trace, debug, info, warn, error +container_authelia_log_file_path: /var/log/authelia/authelia.log # Path to log file +container_authelia_log_keep_stdout: true # Also log to STDOUT (recommended for containers) + +# --------------------- +# Identity Validation / Password Reset +# --------------------- +container_authelia_elevated_session_2fa: true # Require 2FA for elevated sessions +container_authelia_jwt_lifespan: "5 minutes" # Expiration time for password reset links +container_authelia_jwt_secret: "nyt4JDvuhU6SGp7H0vaEs0rfGETjI26fRQPJZzwdWPuXsmHdAun2hryiJDyDPRuC" # docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --charset alphanumeric + +# --------------------- +# TOTP (Two-Factor Authentication) +# --------------------- +container_authelia_totp_disable: false # Disable TOTP (false = enabled) +container_authelia_totp_issuer: example.com # Issuer name shown in authenticator apps +container_authelia_totp_period: 30 # Time interval in seconds +container_authelia_totp_skew: 1 # Allowed time drift (in periods) + +# --------------------- +# Password Policy (Zxcvbn) +# --------------------- +container_authelia_zxcvbn_enabled: true # Enable password strength validation +container_authelia_zxcvbn_min_score: 4 # Minimum strength score (0–4) + +# --------------------- +# Authentication Backend (File-based) +# --------------------- +container_authelia_auth_file_path: /config/users.yml # Path to user configuration file +container_authelia_auth_algorithm: argon2 # Password hashing algorithm +container_authelia_auth_argon2_variant: argon2id +container_authelia_auth_argon2_iterations: 3 +container_authelia_auth_argon2_memory: 65535 +container_authelia_auth_argon2_parallelism: 4 +container_authelia_auth_argon2_key_length: 32 +container_authelia_auth_argon2_salt_length: 16 + +# --------------------- +# Access Control +# --------------------- +container_authelia_access_default_policy: deny # Default access policy (deny/one_factor/two_factor) +container_authelia_access_rules: + - domain: "traefik.example.com" + policy: "one_factor" + - domain: "whoami-secure.example.com" + policy: "two_factor" + +# --------------------- +# Session Configuration +# --------------------- +container_authelia_session_name: authelia_session # Name of the session cookie +container_authelia_session_key: "zB3d7gTWVbhB5jFQVkjtxfhVZ4aEaFwKHWNa81jjqSL7JgV5HmqOAULDhlJA0muI" # docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --charset alphanumeric +container_authelia_session_cookies: + - domain: "example.com" + authelia_url: "https://auth.example.com" + +# --------------------- +# Security Regulation (Brute Force Protection) +# --------------------- +container_authelia_regulation_max_retries: 4 # Max failed login attempts before ban +container_authelia_regulation_find_time: 120 # Time window to count failed attempts (in seconds) +container_authelia_regulation_ban_time: 300 # Ban duration after reaching retry limit (in seconds) + +# --------------------- +# Storage +# --------------------- + +container_authelia_storage_encryption_key: "B4g3XlMfiBJPUXqrZmxfE1CccUASi1r2Cxpr8q9QbmQ3Rvx1RDJvZ1J3DTqkR2a5" # docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --charset alphanumeric +container_authelia_storage_path: /config/db.sqlite3 # Path to SQLite storage file + +# --------------------- +# Notifications +# --------------------- +container_authelia_notifier_disable_startup_check: false # Disable notifier startup check (recommended: false) +container_authelia_notifier_file: /config/notification.txt # File path used for file-based notifications + +# --------------------- +# User Configuration (for file-based backend) +# --------------------- +# !! SECURITY WARNING !!: +# Passwords must always be hashed (argon2, bcrypt, sha512, etc.). +# Never store plain-text passwords in production. +# Use this guide to generate secure hashes: +# https://www.authelia.com/reference/guides/passwords/#passwords + +container_authelia_users: + - username: authelia + displayname: 'Authelia User' + # docker run --rm -it authelia/authelia:latest authelia crypto hash generate argon2 + # !! Replace the password with a secure hashed password + password: '$6$rounds=50000$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4tlwCFm5r6NTOZZ5qRFN/' + email: 'authelia@authelia.com' + groups: + - 'admin' + - 'dev' diff --git a/ansible/roles/deploy_container_authelia/files/.gitkeep b/ansible/roles/deploy_container_authelia/files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/deploy_container_authelia/handlers/main.yml b/ansible/roles/deploy_container_authelia/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/deploy_container_authelia/meta/main.yml b/ansible/roles/deploy_container_authelia/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/deploy_container_authelia/tasks/main.yml b/ansible/roles/deploy_container_authelia/tasks/main.yml new file mode 100644 index 0000000..1d9f9e5 --- /dev/null +++ b/ansible/roles/deploy_container_authelia/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- name: Ensure data directories exist + ansible.builtin.file: + path: "{{ container_base_dir }}/data/{{ item }}" + state: directory + mode: '0755' + loop: + - "secrets" + - "config" + - "logs" + become: false + +- name: Ensure authelia.log file exists + ansible.builtin.file: + path: "{{ container_base_dir }}/data/logs/authelia.log" + state: touch + mode: '0644' + become: false + +- name: Deploy Docker Compose and .env files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ container_base_dir }}/{{ item.dest }}" + mode: '0644' + loop: + - { src: 'docker-compose.yml.j2', dest: 'docker-compose.yml' } + - { src: '.env.j2', dest: '.env' } + - { src: 'users.yml.j2', dest: 'data/config/users.yml' } + - { src: 'configuration.yml.j2', dest: 'data/config/configuration.yml' } + become: false + +- name: Stop Container + community.docker.docker_compose_v2: + project_src: "{{ container_base_dir }}" + state: absent + docker_host: "unix:///run/user/1000/docker.sock" + become: false + +- name: Start Container + community.docker.docker_compose_v2: + project_src: "{{ container_base_dir }}" + pull: always + docker_host: "unix:///run/user/1000/docker.sock" + become: false diff --git a/ansible/roles/deploy_container_authelia/templates/.env.j2 b/ansible/roles/deploy_container_authelia/templates/.env.j2 new file mode 100644 index 0000000..f3446ab --- /dev/null +++ b/ansible/roles/deploy_container_authelia/templates/.env.j2 @@ -0,0 +1,2 @@ +AUTHELIA_VERSION={{ container_authelia_version }} +AUTHELIA_DOMAIN={{ container_authelia_domain }} \ No newline at end of file diff --git a/ansible/roles/deploy_container_authelia/templates/configuration.yml.j2 b/ansible/roles/deploy_container_authelia/templates/configuration.yml.j2 new file mode 100644 index 0000000..01c4530 --- /dev/null +++ b/ansible/roles/deploy_container_authelia/templates/configuration.yml.j2 @@ -0,0 +1,72 @@ +server: + address: 'tcp4://:{{ container_authelia_server_port | default(9091) }}' + +log: + level: {{ container_authelia_log_level | default('debug') }} + file_path: '{{ container_authelia_log_file_path | default("/var/log/authelia/authelia.log") }}' + keep_stdout: {{ container_authelia_log_keep_stdout | default(true) }} + +identity_validation: + elevated_session: + require_second_factor: {{ container_authelia_elevated_session_2fa | default(true) }} + reset_password: + jwt_lifespan: '{{ container_authelia_jwt_lifespan | default("5 minutes") }}' + jwt_secret: {{ container_authelia_jwt_secret }} + +totp: + disable: {{ container_authelia_totp_disable | default(false) }} + issuer: '{{ container_authelia_totp_issuer | default("example.com") }}' + period: {{ container_authelia_totp_period | default(30) }} + skew: {{ container_authelia_totp_skew | default(1) }} + +password_policy: + zxcvbn: + enabled: {{ container_authelia_zxcvbn_enabled | default(true) }} + min_score: {{ container_authelia_zxcvbn_min_score | default(4) }} + +authentication_backend: + file: + path: '{{ container_authelia_auth_file_path | default("/config/users.yml") }}' + password: + algorithm: '{{ container_authelia_auth_algorithm | default("argon2") }}' + argon2: + variant: '{{ container_authelia_auth_argon2_variant | default("argon2id") }}' + iterations: {{ container_authelia_auth_argon2_iterations | default(3) }} + memory: {{ container_authelia_auth_argon2_memory | default(65535) }} + parallelism: {{ container_authelia_auth_argon2_parallelism | default(4) }} + key_length: {{ container_authelia_auth_argon2_key_length | default(32) }} + salt_length: {{ container_authelia_auth_argon2_salt_length | default(16) }} + +access_control: + default_policy: '{{ container_authelia_access_default_policy | default("deny") }}' + rules: +{% for rule in container_authelia_access_rules %} + - domain: '{{ rule.domain }}' + policy: '{{ rule.policy }}' +{% endfor %} + +session: + name: '{{ container_authelia_session_name | default("authelia_session") }}' + secret: {{ container_authelia_session_key }} + + cookies: +{% for cookie in container_authelia_session_cookies %} + - domain: '{{ cookie.domain }}' + authelia_url: '{{ cookie.authelia_url }}' +{% endfor %} + +regulation: + max_retries: {{ container_authelia_regulation_max_retries | default(4) }} + find_time: {{ container_authelia_regulation_find_time | default(120) }} + ban_time: {{ container_authelia_regulation_ban_time | default(300) }} + +storage: + encryption_key: {{ container_authelia_storage_encryption_key }} + + local: + path: '{{ container_authelia_storage_path | default("/config/db.sqlite3") }}' + +notifier: + disable_startup_check: {{ container_authelia_notifier_disable_startup_check | default(false) }} + filesystem: + filename: '{{ container_authelia_notifier_file | default("/config/notification.txt") }}' diff --git a/ansible/roles/deploy_container_authelia/templates/docker-compose.yml.j2 b/ansible/roles/deploy_container_authelia/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..74a821a --- /dev/null +++ b/ansible/roles/deploy_container_authelia/templates/docker-compose.yml.j2 @@ -0,0 +1,34 @@ +--- +services: + authelia: + image: authelia/authelia:${AUTHELIA_VERSION} + container_name: authelia + volumes: + - './data/secrets:/secrets:ro' + - './data/config:/config' + - './data/logs/authelia.log:{{ container_authelia_log_file_path }}' + networks: + traefik: + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.http.routers.authelia.entrypoints=http" + - "traefik.http.routers.authelia.rule=Host(`${AUTHELIA_DOMAIN:?error}`)" + - "traefik.http.middlewares.authelia-https-redirect.redirectscheme.scheme=https" + - "traefik.http.routers.authelia.middlewares=authelia-https-redirect" + - "traefik.http.routers.authelia-secure.entrypoints=https" + - "traefik.http.routers.authelia-secure.rule=Host(`${AUTHELIA_DOMAIN:?error}`)" + - "traefik.http.routers.authelia-secure.tls=true" + - "traefik.http.routers.authelia-secure.service=authelia" + - "traefik.http.services.authelia.loadbalancer.server.port=9091" + # Authelia Middleware + - "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth" + - "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true" + - "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email" + environment: + TZ: 'EUROPE/BERLIN' + X_AUTHELIA_CONFIG_FILTERS: 'template' + +networks: + traefik: + external: true \ No newline at end of file diff --git a/ansible/roles/deploy_container_authelia/templates/users.yml.j2 b/ansible/roles/deploy_container_authelia/templates/users.yml.j2 new file mode 100644 index 0000000..e30c185 --- /dev/null +++ b/ansible/roles/deploy_container_authelia/templates/users.yml.j2 @@ -0,0 +1,11 @@ +users: +{% for user in container_authelia_users %} + {{ user.username }}: + displayname: '{{ user.displayname }}' + password: '{{ user.password }}' + email: '{{ user.email }}' + groups: +{% for group in user.groups %} + - '{{ group }}' +{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/ansible/roles/deploy_container_authelia/vars/main.yml b/ansible/roles/deploy_container_authelia/vars/main.yml new file mode 100644 index 0000000..750dfc7 --- /dev/null +++ b/ansible/roles/deploy_container_authelia/vars/main.yml @@ -0,0 +1 @@ +container_base_dir: /opt/docker/authelia \ No newline at end of file