↓ Перейти к основному содержимому
  1. Posts/
  2. IAM и IdP решения./

Authelia в Docker: устанавливаем ForwardAuth-защиту для сервисов за Traefik

··1325 слов·7 минут· loading · loading · ·
Stilicho2011
Автор
Stilicho2011
Пишу о homelab, self-hosting, автоматизации и open-source решениях
Оглавление
IAM-решения - This article is part of a series.
Part : This Article

Из всех решений для SSO/2FA, которые я разбирал на канале, Authelia - самое легковесное. Если Authentik и Keycloak - это полноценные IAM-платформы со своей базой пользователей и веб-консолью, то Authelia скорее “охранник на входе”: она не заменяет ваши сервисы и не хранит про них ничего, а просто встает перед Traefik (или NGINX/Caddy) и решает один вопрос - пускать конкретного человека дальше или сначала спросить пароль и код из приложения-аутентификатора. Развернутое сравнение Authelia с Authentik, Keycloak и ZITADEL - в отдельной статье.

Если статья или видео оказались полезны - поддержать канал можно на бусти, ссылка в контактах.

Что она умеет
#

  • Защита любых веб-приложений по домену или конкретному URI - точечно, а не все-или-ничего.
  • 2FA: TOTP, Duo, WebAuthn.
  • Пользователи - из простого YAML-файла, LDAP или Active Directory, на выбор.
  • ForwardAuth-интеграция с Traefik, NGINX, Caddy.
  • ACL - правила доступа по домену, группе, сети.

У нее принципиально нет собственного веб-интерфейса для управления - вся конфигурация в YAML-файлах, а пользователи заводятся руками или скриптом. Для кого-то это минус (Authentik в этом смысле удобнее для нетехнического члена семьи), а для меня - скорее плюс: конфиг лежит в git, изменения видны в diff, и не нужно тыкаться в панель, чтобы понять, что где настроено.

ХарактеристикаAutheliaAuthentikKeycloakZITADEL
Легкость установки⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
2FA✅✅✅✅
SSO✅✅✅✅
Open Source✅✅✅✅
Веб-интерфейс❌ (только конфиг)✅✅✅
Потребление ресурсовНизкоеСреднееВысокоеСреднее
ACL✅✅Ограниченно❌

(Оценки “звездочками” - мое субъективное ощущение по итогам установки всех четырех, не результат замеров.)

Если нужна максимальная простота и минимум ресурсов на не самом мощном homelab-сервере - Authelia отличный выбор. Если хочется веб-панель для не-технических пользователей семьи - смотрите в сторону Authentik.

Что понадобится
#

  • Docker и Docker Compose.
  • Уже настроенный обратный прокси - у меня Traefik.
  • Домены с HTTPS (Let’s Encrypt/Cloudflare - без разницы).
  • Базовое знание YAML - конфиг весь текстовый, магии в интерфейсе не будет.

Структура проекта
#

authelia/
├── configuration.yml
├── users.yml
├── docker-compose.yml
└── secrets
services:
    authelia:
        image: "authelia/authelia:4.39.20" # не используйте :latest - зафиксируйте версию явно, актуальную смотрите на https://github.com/authelia/authelia/releases
        container_name: "authelia"
        volumes:
            - "./secrets:/secrets:ro"
            - "./config:/config"
            - "./logs:/var/log/authelia/"
        networks:
            proxy:
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.authelia.rule=Host(`authelia.stilicho.ru`)"
            - "traefik.http.routers.authelia.entrypoints=https"
            - "traefik.http.routers.authelia.tls=true"
            - "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/verify?rd=https://authelia.stilicho.ru"
            - "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
            - "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
            - "traefik.http.services.authelia.loadbalancer.server.port=9091"
        environment:
            TZ: "Europe/Moscow"
            AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: "/secrets/JWT_SECRET" # tr -cd '[:alnum:]' < /dev/urandom | fold -w 64 | head -n 1 > ./secrets/JWT_SECRET
            AUTHELIA_SESSION_SECRET_FILE: "/secrets/SESSION_SECRET" # tr -cd '[:alnum:]' < /dev/urandom | fold -w 64 | head -n 1 > ./secrets/SESSION_SECRET
            AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: "/secrets/STORAGE_ENCRYPTION_KEY" # tr -cd '[:alnum:]' < /dev/urandom | fold -w 64 | head -n 1 > ./secrets/STORAGE_ENCRYPTION_KEY

    #whoami-secure:
    #    image: "traefik/whoami"
    #    restart: "unless-stopped"
    #    container_name: "whoami-secure"
    #    labels:
    #        - "traefik.enable=true"
    #        - "traefik.http.routers.whoami-secure.rule=Host(`whoami-secure.stilicho.ru`)"
    #        - "traefik.http.routers.whoami-secure.entrypoints=https"
    #        - "traefik.http.routers.whoami-secure.middlewares=authelia@docker"
    #    networks:
    #        proxy:

networks:
    proxy:
        external: true
users:
    stilicho: ## Username
        displayname: "stilicho"
        ## WARNING: This is a default password for testing only!
        ## IMPORTANT: Change this password before deploying to production!
        ## Generate a new hash using the instructions at:
        ## https://www.authelia.com/reference/guides/passwords/#passwords
        ## Password is 'authelia'
        password: "$argon2id$v=19$m=65536,t=3,p=4$uSPUUUh/a5U7pNso6g2cMA$YJECeQHkv/qXZDB3W9ADkWj7DMSJRWcn/pVHTUvCbtI"
        email: "authelia@authelia.com"
        groups:
            - "admin"
            - "dev"
server:
    address: tcp://0.0.0.0:9091/
log:
    level: debug
theme: dark
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE
#jwt_secret:
default_redirection_url: https://authelia.stilicho.ru
totp:
    issuer: authelia.com

# duo_api:
#  hostname: api-123456789.example.com
#  integration_key: ABCDEF
#  # This secret can also be set using the env variables AUTHELIA_DUO_API_SECRET_KEY_FILE
#  secret_key: 1234567890abcdefghifjkl

authentication_backend:
    file:
        path: /config/users.yml
        password:
            algorithm: argon2
            # Recommended Parameters
            # Uses 2 GiB memory, then immediately releases it.
            # See https://www.authelia.com/reference/guides/passwords/#recommended-parameters-argon2
            # See https://www.rfc-editor.org/rfc/rfc9106.html#section-4 for details on tuning the parameters for your hardware.
            # After saving configuration file, password hash can be generated by running: docker run -v ./configuration.yml:/configuration.yml --rm authelia/authelia:latest authelia crypto hash generate --config /configuration.yml --password 'yourpassword'
            argon2:
                variant: argon2id
                iterations: 1
                memory: 2097152
                parallelism: 4
                key_length: 32
                salt_length: 16
            # Recommended Parameters when constrained by low memory or low powered hardware. Uses 64 KiB memory, then immediately releases it.
            # argon2:
            #   variant: argon2id
            #   iterations: 3
            #   memory: 65536
            #   parallelism: 4
            #   key_length: 32
            #   salt_length: 16

access_control:
    default_policy: deny
    rules:
        # Rules applied to everyone
        - domain: traefik-dashboard.stilicho.ru
          policy: two_factor
        #- domain: portainer.stilicho.ru #для portainer есть oidc
        #  policy: two_factor
        - domain: nginx.stilicho.ru
          policy: two_factor

session:
    name: authelia_session
    # This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
    #secret:
    expiration: 14400 # 4 hour
    inactivity: 14400 # 4 hour
    domain: stilicho.ru # Should match whatever your root protected domain is

    # redis:
    #   host: redis
    #   port: 6379
    #   # This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE
    #   # password: authelia

regulation:
    max_retries: 3
    find_time: 120
    ban_time: 300

storage:
    #encryption_key: /secrets/STORAGE_ENCRYPTION_KEY # Now required
    local:
        path: /config/db.sqlite3

#password_policy:
#  zxcvbn:
#    enabled: true
#    min_score: 4

#identity_providers:
#  oidc:
## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
## See: https://www.authelia.com/c/oidc
#    clients:
#      - client_id: 'portainer'
#        client_name: 'Portainer'
#        client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'  # The digest of 'insecure_secret'.
#        public: false
#        authorization_policy: 'two_factor'
#        require_pkce: false
#        pkce_challenge_method: ''
#        redirect_uris:
#          - 'https://portainer.stilicho.ru'
#        scopes:
#         - 'openid'
#          - 'profile'
#          - 'groups'
#          - 'email'
#        response_types:
#          - 'code'
#        grant_types:
#          - 'authorization_code'
#        access_token_signed_response_alg: 'none'
#        userinfo_signed_response_alg: 'none'
#        token_endpoint_auth_method: 'client_secret_post'

#log:
#  level: info
#  format: text
#  file_path: /logs/authelia.log
#  keep_stdout: false

notifier:
    # smtp:
    #   username: test
    #   # This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
    #   password: password
    #   host: mail.example.com
    #   port: 25
    #   sender: admin@example.com
    filesystem:
        filename: /config/notification.txt

На что здесь стоит обратить внимание:

  • Три секрета через _FILE (JWT_SECRET, SESSION_SECRET, STORAGE_ENCRYPTION_KEY) - генерируются той же командой из комментария в compose-файле (tr -cd '[:alnum:]' < /dev/urandom | fold -w 64 | head -n 1 > ./secrets/ИМЯ), по одному запуску на каждый файл. Без них Authelia просто не поднимется - это не опциональные настройки для продвинутых, а обязательный минимум.
  • Хэш пароля в users.yml - в примере это тестовый хэш для пароля authelia. Оставлять его как есть даже “просто чтобы посмотреть” не стоит - сгенерируйте свой командой из комментария (authelia crypto hash generate) сразу, экономия пяти минут того не стоит.
  • log: level: debug в configuration.yml - удобно на этапе первой настройки, чтобы видеть, что происходит при каждом запросе, но после того как все заработало, стоит вернуть на info - иначе лог быстро разрастется, а толку от него для повседневной работы никакого.
  • access_control.rules - именно здесь описывается, какие домены защищены и какой уровень доступа нужен (two_factor, one_factor, bypass). default_policy: deny означает, что все, что не описано явно правилом, - заблокировано по умолчанию. Правило пишется сверху вниз, и совпадает первое подходящее - порядок правил имеет значение.
  • session.domain - должен совпадать с корневым доменом, для которого вы защищаете сервисы (у меня stilicho.ru), иначе cookie сессии Authelia не будет виден поддоменам защищенных сервисов, и авторизация не переживет переход между ними.
  • Закомментированный блок whoami-secure в compose-файле - тестовый сервис traefik/whoami, специально оставленный для проверки: раскомментируйте его, чтобы убедиться, что forwardAuth-мидлварь реально спрашивает пароль перед тем, как показать страницу, прежде чем вешать защиту на настоящие сервисы.

Проверка
#

Поднимаем стек:

docker compose up -d

Открываем защищенный домен в браузере - должно перекинуть на форму логина Authelia, а не сразу на сервис. Вводим логин/пароль из users.yml, дальше - запрос TOTP-кода (если настроили). После успешного входа Authelia редиректит обратно на исходный адрес, и дальше запросы к этому домену идут без повторного логина в пределах session.expiration.

Если вместо формы логина видите сразу защищенный сервис - значит forwardAuth-мидлварь не подключена к роутеру этого сервиса (traefik.http.routers.<сервис>.middlewares=authelia@docker должен быть в лейблах), а не проблема самой Authelia.

Вывод
#

Authelia - не замена полноценному IAM-решению, а простой и легкий “стражник” перед вашими сервисами, если не нужна ни своя база пользователей с веб-панелью, ни OIDC-интеграции на каждый чих. Конфиг весь в текстовых файлах, ресурсов почти не ест, а после того как разберетесь один раз с секретами и access_control - добавление нового защищенного домена - это одна строчка в правилах и один лейбл на контейнер.

IAM-решения - This article is part of a series.
Part : This Article

Related

Установка и настройка Keycloak

··1171 слово·6 минут· loading · loading
Пошаговая инструкция по установке и настройке Keycloak для организации SSO и двухфакторной аутентификации с обратным прокси. Рассмотрены конфигурация Docker Compose, первый вход в админку, создание realm и клиента, а также рекомендации по повышению безопасности.

Authentik: обзор, архитектура, возможности и сравнение с Keycloak

··1013 слов·5 минут· loading · loading
Подробный обзор Authentik - open source системы для централизованной аутентификации и авторизации (IdP/SSO). Рассмотрим зачем нужны IAM-решения, архитектуру, ключевые функции и сравнение с альтернативами.

TOTP vs WebAuthn vs Passwordless: в чем разница и что выбрать

··1542 слов·8 минут· loading · loading
Подробно о TOTP, WebAuthn, passkeys и Passwordless Login: как они работают, их сильные и слабые стороны, а также рекомендации по выбору подходящей технологии для входа в свои сервисы.