From 715332f384a2ba50165e9c082d8daf74c1130ece Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sun, 15 Mar 2026 10:16:26 -0300 Subject: [PATCH] refactor Authelia setup and configuration handling --- containers/authelia/Dockerfile-authelia | 7 ----- containers/authelia/entrypoint.sh | 28 +++++++++++++------ containers/caddy/process_config.py | 37 +++++++++++++++++-------- docker-compose-dev.yml | 2 +- init.sh | 5 ++++ 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/containers/authelia/Dockerfile-authelia b/containers/authelia/Dockerfile-authelia index b31073f..a276c04 100644 --- a/containers/authelia/Dockerfile-authelia +++ b/containers/authelia/Dockerfile-authelia @@ -1,13 +1,6 @@ -FROM alpine:latest AS tools -RUN apk add --no-cache inotify-tools - FROM authelia/authelia:latest -COPY --from=tools /usr/bin/inotifywait /usr/bin/inotifywait -COPY --from=tools /usr/lib/libinotifytools* /usr/lib/ - COPY entrypoint.sh /usr/local/bin/authelia-entrypoint.sh - RUN chmod +x /usr/local/bin/authelia-entrypoint.sh ENTRYPOINT ["/usr/local/bin/authelia-entrypoint.sh"] diff --git a/containers/authelia/entrypoint.sh b/containers/authelia/entrypoint.sh index a6f72fa..5b590d9 100644 --- a/containers/authelia/entrypoint.sh +++ b/containers/authelia/entrypoint.sh @@ -18,15 +18,27 @@ AUTHELIA_PID=$! sleep 3 echo "==> Watching ${CONFIG_PATH} for changes..." + +# Function to safely get hash in minimal environments +get_hash() { + md5sum "$CONFIG_PATH" 2>/dev/null | awk '{print $1}' || echo "error" +} + +LAST_HASH=$(get_hash) + while true; do - inotifywait -qq -e close_write,moved_to "${CONFIG_PATH}" 2>/dev/null || true - sleep 2 + sleep 3 + CURRENT_HASH=$(get_hash) - echo "==> Configuration change detected, restarting Authelia..." - kill "$AUTHELIA_PID" 2>/dev/null || true - wait "$AUTHELIA_PID" 2>/dev/null || true + if [ "$LAST_HASH" != "$CURRENT_HASH" ]; then + echo "==> Configuration change detected, restarting Authelia..." + LAST_HASH="$CURRENT_HASH" + + kill "$AUTHELIA_PID" 2>/dev/null || true + wait "$AUTHELIA_PID" 2>/dev/null || true - authelia --config "$CONFIG_PATH" & - AUTHELIA_PID=$! - echo "==> Authelia restarted with PID ${AUTHELIA_PID}" + authelia --config "$CONFIG_PATH" & + AUTHELIA_PID=$! + echo "==> Authelia restarted with PID ${AUTHELIA_PID}" + fi done diff --git a/containers/caddy/process_config.py b/containers/caddy/process_config.py index c35071f..ad7ea7d 100644 --- a/containers/caddy/process_config.py +++ b/containers/caddy/process_config.py @@ -86,6 +86,12 @@ def build_caddyfile(apps, auth_policies, routes): host_list = ", ".join(hosts) lines.append(f"{host_list} {{") + if has_authelia and app_id == "wireguard_webadmin": + lines.append(f" handle_path {AUTHELIA_PORTAL_PATH}/* {{") + lines.append(f" reverse_proxy {AUTHELIA_INTERNAL_URL}") + lines.append(f" }}") + lines.append("") + for static_route in static_routes: path_prefix = static_route.get("path_prefix", "") root_dir = static_route.get("root", "") @@ -142,15 +148,6 @@ def build_caddyfile(apps, auth_policies, routes): lines.append(f"}}") lines.append("") - if has_authelia: - server_address = os.environ.get("SERVER_ADDRESS", "localhost") - lines.append(f"{server_address} {{") - lines.append(f" handle_path {AUTHELIA_PORTAL_PATH}/* {{") - lines.append(f" reverse_proxy {AUTHELIA_INTERNAL_URL}") - lines.append(f" }}") - lines.append(f"}}") - lines.append("") - return "\n".join(lines) @@ -172,7 +169,11 @@ def build_authelia_config(auth_policies, routes, apps): "log": { "level": "info", }, - "jwt_secret": jwt_secret, + "identity_validation": { + "reset_password": { + "jwt_secret": jwt_secret, + }, + }, "authentication_backend": { "file": { "path": "/config/users_database.yml", @@ -283,7 +284,7 @@ def build_access_control_rules(auth_policies, routes, apps): rules.append(default_rule) return { - "default_policy": "deny", + "default_policy": "two_factor" if not rules else "deny", "rules": rules, } @@ -328,9 +329,18 @@ def build_identity_providers(auth_policies, server_address): } +DUMMY_USER = { + "_dummy_setup_user": { + "disabled": True, + "displayname": "Dummy Setup User", + "password": "$argon2id$v=19$m=65536,t=3,p=4$Nklqa1J5a3ZweDhlZnNlUw$5D8WJ+sT20eXj1U10qNnS2Ew/M40B8v1/37X2b1lG0I", + "email": "dummy@localhost", + } +} + def build_users_database(auth_policies): if not auth_policies: - return {"users": {}} + return {"users": DUMMY_USER} users_data = auth_policies.get("users", {}) groups_data = auth_policies.get("groups", {}) @@ -355,6 +365,9 @@ def build_users_database(auth_policies): users[username] = user_entry + if not users: + users = DUMMY_USER.copy() + return {"users": users} diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index caa9f4b..08dc516 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -27,7 +27,7 @@ services: - caddy_json_export:/caddy_json_export/ ports: # Do not directly expose the Django port to the internet, use some kind of reverse proxy with SSL. - # - "8000:8000" + - "8000:8000" # Warning: Docker will have a hard time handling large amount of ports. Expose only the ports that you need. # Ports for multiple WireGuard instances. (Probably, you just need one) - "51820-51839:51820-51839/udp" diff --git a/init.sh b/init.sh index 8772d2b..159b89f 100644 --- a/init.sh +++ b/init.sh @@ -16,6 +16,11 @@ fi # Django startup python manage.py migrate --noinput python manage.py collectstatic --noinput + +if [[ "${CADDY_ENABLED,,}" == "true" ]]; then + echo "Exporting Caddy configuration (auth_policies.json, applications.json, routes.json)..." + python manage.py shell -c "from app_gateway.caddy_config_export import export_caddy_config; export_caddy_config('/caddy_json_export')" || echo "Failed to export Caddy configuration." +fi if [[ "${DEV_MODE,,}" == "true" ]]; then echo "" echo ""