Authelia — открытый портал аутентификации для собственных веб-сервисов. Он не заменяет приложения, а встаёт перед ними: обратный прокси спрашивает у Authelia, можно ли пустить пользователя, и только потом передаёт запрос дальше. Один вход, второй фактор, единые правила доступа и журнал попыток — всё в одном месте, без правки каждого сервиса. Ниже — установка в Docker, подключение через nginx, настройка TOTP и WebAuthn, диагностика.
Как работает проверка доступа
Схема простая. Браузер приходит на cloud.example.com, nginx делает внутренний подзапрос к API проверки на Authelia. Если сессии нет, прокси перенаправляет на портал auth.example.com, где пользователь вводит логин, пароль и код. После успеха Authelia ставит подписанную cookie на домен верхнего уровня, и прокси получает заголовки с именем пользователя и группами. Эти заголовки приложение может использовать для авторизации.
Состояние сессий хранится в Redis, пользователи — в файле или LDAP, правила доступа — в YAML. Такой набор достаточно надёжен для домашней лаборатории и небольшой компании.
Установка и структура каталогов
Готовых пакетов нет, проект публикует образы Docker и бинарники. Для сервера удобнее compose: рядом лежат конфигурация и данные.
mkdir -p /opt/authelia/{config,redis}
cd /opt/authelia
touch config/configuration.yml config/users_database.yml
chmod 600 config/users_database.yml
Compose описывает два сервиса. Authelia слушает 9091 на localhost, наружу её публикует прокси. Redis хранит сессии и не должен быть доступен из сети.
services:
authelia:
image: authelia/authelia:4
restart: unless-stopped
volumes:
- ./config:/config
ports:
- "127.0.0.1:9091:9091"
environment:
TZ: Europe/Moscow
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 900 1
volumes:
- ./redis:/data
Секреты генерируются встроенной командой. Для базовой схемы достаточно секрета сессии; ключ шифрования нужен для локальной базы, HMAC — для сброса пароля. Потеря секрета сбрасывает все сессии.
docker compose run --rm authelia authelia crypto rand --length 64 --charset alphanumeric
docker compose up -d
docker compose logs -f authelia
Пользователи и пароли
Пароли в файле хранятся только в виде хеша Argon2id. Хеш генерируется встроенной командой, пароль вводится в приглашении, а не в аргументах — формат вручную не придумывайте. Для каждого заводится отдельная запись с группами и почтой.
docker compose run --rm authelia authelia crypto hash generate argon2
docker compose run --rm authelia authelia storage user totp generate admin
Вторая команда создаёт секрет TOTP и ссылку для QR-кода. Ссылку открывают в приложении-аутентификаторе, а секрет сохраняют в менеджере паролей как резервный способ восстановления. Для WebAuthn-ключей регистрация выполняется из портала: пользователь входит с паролем и добавляет аппаратный ключ или биометрию.
Конфигурация портала
Минимальный файл задаёт порт, хранилище и политику по умолчанию. Полный список ключей большой, но для старта хватает нескольких разделов.
server:
address: 'tcp://:9091'
endpoints:
authz:
auth-request:
implementation: 'AuthRequest'
authentication_backend:
file:
path: '/config/users_database.yml'
session:
secret: '<секрет сессии>'
cookies:
- domain: 'example.com'
authelia_url: 'https://auth.example.com'
redis:
host: 'redis'
port: 6379
storage:
encryption_key: '<ключ шифрования>'
local:
path: '/config/db.sqlite3'
access_control:
default_policy: 'deny'
rules:
- domain: 'cloud.example.com'
policy: 'two_factor'
Домен cookie должен быть общим родителем для портала и защищаемых сервисов, иначе браузер не передаст сессию. Политика two_factor требует второй фактор, one_factor — только пароль, bypass пропускает без проверки и годится лишь для служебных адресов внутри сети.
Подключение через nginx
В конфигурации сайта появляется внутренний location и проверка авторизации. Важно передать исходный URL и метод: по ним Authelia строит решение и адрес редиректа.
location / {
auth_request /authelia;
auth_request_set $redirection_url $upstream_http_location;
auth_request_set $user $upstream_http_remote_user;
error_page 401 =302 $redirection_url;
proxy_set_header Remote-User $user;
proxy_pass http://127.0.0.1:8080;
}
location = /authelia {
internal;
proxy_pass http://127.0.0.1:9091/api/authz/auth-request;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
Путь /api/authz/auth-request соответствует реализации AuthRequest. В старых конфигурациях встречается /api/verify — сверьтесь с документацией версии, иначе получите циклический редирект. После правки проверьте синтаксис и перезагрузите nginx.
sudo nginx -t
sudo systemctl reload nginx
curl -sI https://cloud.example.com | grep -i location
Второй фактор и защита от подбора
TOTP работает без интернета и не зависит от производителя телефона. WebAuthn надёжнее: ключ привязан к домену и не поддаётся фишингу. Разумная схема — разрешить оба метода, а администраторам выдать аппаратные ключи. Секрет TOTP сохраняют в менеджере паролей, а сброс выполняет администратор.
Раздел регулирования ограничивает число попыток: задайте пять неудач и блокировку на десять минут. Если сервис смотрит в интернет, добавьте fail2ban на журнал nginx и ограничьте портал по подсетям.
Не забудьте про время. Код TOTP живёт 30 секунд, и расхождение часов больше чем на минуту ломает вход. На сервере должен работать chrony или systemd-timesyncd, а на телефоне — автоматическая синхронизация.
Диагностика
Типичные симптомы: бесконечный редирект, 401 после успешного входа и отсутствие заголовка с пользователем в приложении. Начинайте с журнала Authelia и проверки, что прокси видит портал по внутреннему адресу.
docker compose logs --tail=100 authelia
curl -s http://127.0.0.1:9091/api/health
docker compose exec redis redis-cli ping
journalctl -u nginx -n 50 --no-pager
Ответ OK от health означает, что процесс жив, но не проверяет Redis и конфигурацию. Если вход проходит, а приложение не видит пользователя, ищите опечатку в имени заголовка: nginx и приложение должны использовать одно и то же написание. Циклический редирект чаще всего вызван неверным authelia_url или доменом cookie.
Резервное копирование и обновление
Копируйте каталог config, дамп Redis и файл секретов. Обновление образа выполняйте с тегом мажорной версии, а не latest: миграции схемы между крупными выпусками требуют отдельного шага. Перед обновлением сделайте снимок машины или копию каталога.
Чек-лист внедрения
- Портал доступен только по HTTPS, порт 9091 закрыт снаружи.
- Cookie выставлена на общий родительский домен с флагами Secure и HttpOnly.
- Политика по умолчанию — deny, исключения перечислены явно.
- Для администраторов включены TOTP и WebAuthn, секреты TOTP сохранены.
- Redis не опубликован в сеть, сессии переживают перезапуск.
- Настроены лимиты попыток и синхронизация времени.
Итог
Authelia превращает набор разрозненных сервисов в одну точку входа с общей политикой. Прокси остаётся тонким, приложения не переписываются, а второй фактор включается одним правилом. Начните с одного тестового домена, убедитесь, что заголовки доходят до приложения, и только потом переводите остальные сервисы. Отдельное внимание — секретам, домену cookie и времени: там возникает большинство проблем.