Из всех решений для 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, и не нужно тыкаться в панель, чтобы понять, что где настроено.
| Характеристика | Authelia | Authentik | Keycloak | ZITADEL |
|---|---|---|---|---|
| Легкость установки | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐ | ⭐⭐ |
| 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
└── secretsservices:
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: trueusers:
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 - добавление нового защищенного домена - это одна строчка в правилах и один лейбл на контейнер.




