1. Как это работает
Authelia — это open-source сервер аутентификации. Он стоит перед вашими приложениями и решает: пускать пользователя или нет.
Механизм называется forward auth («переадресованная аутентификация»). Работает так: когда пользователь открывает, например, grafana.ваш-сайт.ru, Nginx не отдаёт страницу сразу. Сначала он спрашивает Authelia: «Этот пользователь авторизован?»
Сценарий запроса
- 1Браузер открывает grafana.ваш-сайт.ru
- 2Nginx делает внутренний запрос к Authelia: «разрешить?»
- 3Authelia проверяет cookie сессии. Если нет — редирект на auth.ваш-сайт.ru
- 4Пользователь вводит логин + пароль + TOTP-код из приложения
- 5Authelia создаёт сессию и перенаправляет обратно на Grafana
- 6Nginx получает 200 от Authelia и открывает Grafana
После входа сессия работает для всех защищённых поддоменов сразу. Открываете Gitea — не нужно входить снова. Открываете n8n — тоже. Это и есть SSO (Single Sign-On, единый вход).
🔑 Один логин
Один аккаунт Authelia вместо десятка логинов в разных приложениях.
📱 TOTP 2FA
Код из Google Authenticator или любого TOTP-приложения. Без телефона не войти.
🛡️ Централизация
Управляете доступом в одном месте. Добавить пользователя — одна строка в файле.
2. Что понадобится
Пример структуры доменов
Authelia работает на auth.vps-example.ru. Ваши приложения: grafana.vps-example.ru, gitea.vps-example.ru, n8n.vps-example.ru. Все они защищены одним входом. В статье используем домен example.ru — замените на свой.
3. Установка Authelia
Запустим Authelia как Docker-контейнер. Создадим рабочую директорию и файл конфигурации.
Структура файлов
sudo mkdir -p /opt/authelia/config
cd /opt/autheliaИтоговая структура директории:
/opt/authelia/
├── docker-compose.yml
└── config/
├── configuration.yml # главный конфиг Authelia
└── users_database.yml # пользователи и хэши паролейdocker-compose.yml
Authelia запускается одним контейнером. Порт 9091 привязываем только к localhost — Nginx будет обращаться к нему локально:
services:
authelia:
image: authelia/authelia:latest
container_name: authelia
restart: unless-stopped
ports:
- "127.0.0.1:9091:9091"
volumes:
- ./config:/config
environment:
- TZ=Europe/MoscowСгенерировать секретные ключи
Authelia требует три уникальных секрета. Генерируем их один раз и сохраняем — они пойдут в конфиг:
# JWT-ключ (для ссылок сброса пароля)
openssl rand -hex 32
# Ключ сессии
openssl rand -hex 32
# Ключ шифрования базы данных
openssl rand -hex 32Каждая команда выведет строку из 64 символов. Скопируйте три разные строки — они потребуются в следующем шаге.
4. Конфигурация
Создаём главный файл конфигурации. Замените example.ru на ваш домен и вставьте три сгенерированных секрета:
theme: 'auto'
server:
address: 'tcp://:9091'
log:
level: 'info'
# Секрет для подписи ссылок сброса пароля
# (вставьте первую строку из openssl rand -hex 32)
identity_validation:
reset_password:
jwt_secret: 'ВСТАВЬТЕ_ПЕРВЫЙ_СЕКРЕТ'
authentication_backend:
file:
path: '/config/users_database.yml'
watch: true # автоматически применять изменения в файле
password:
algorithm: argon2id
# Сессии — общие для всех поддоменов example.ru
session:
# (вставьте второй секрет)
secret: 'ВСТАВЬТЕ_ВТОРОЙ_СЕКРЕТ'
cookies:
- name: 'authelia_session'
domain: 'example.ru' # ваш базовый домен
authelia_url: 'https://auth.example.ru' # URL входа в Authelia
expiration: '12h' # сессия живёт 12 часов
inactivity: '45m' # закрыть через 45 мин без активности
# Хранилище — SQLite (достаточно для одного VPS)
storage:
# (вставьте третий секрет)
encryption_key: 'ВСТАВЬТЕ_ТРЕТИЙ_СЕКРЕТ'
local:
path: '/config/db.sqlite3'
# Уведомления — в файл (не требует почтового сервера)
# Ссылки для сброса пароля будут записываться в этот файл
notifier:
filesystem:
filename: '/config/notification.txt'
# Правила доступа
access_control:
default_policy: deny # запрещено всё, что не разрешено явно
rules:
# Authelia сама должна быть доступна без авторизации
- domain: 'auth.example.ru'
policy: bypass
# Все остальные поддомены — только после входа + TOTP
- domain: '*.example.ru'
policy: two_factorВажно: домен в session.cookies
Указывайте базовый домен (example.ru), а не поддомен (auth.example.ru). Именно так браузер сможет отправлять сессионную cookie на все поддомены — и Authelia не будет просить авторизацию при переходе между приложениями.
Если хотите уведомления по почте
Замените блок notifier на SMTP-конфигурацию:
notifier:
smtp:
address: 'submission://smtp.yandex.ru:587'
username: 'вы@yandex.ru'
password: 'пароль_приложения'
sender: 'Authelia <вы@yandex.ru>'5. Пользователи и пароли
Authelia хранит пользователей в простом YAML-файле. Пароли хранятся хэшированными — нельзя просто написать пароль в открытом виде. Сначала сгенерируем хэш.
Шаг 1: сгенерировать хэш пароля
Запустите команду — она спросит пароль интерактивно и выведет хэш:
docker run --rm -it authelia/authelia:latest authelia crypto hash generate argon2Enter Password:
Confirm Password:
Digest: $argon2id$v=19$m=65536,t=3,p=4$abc123...XYZ$hashed...valueСтрока начиная с $argon2id$ — это хэш пароля. Скопируйте её целиком.
Шаг 2: создать файл пользователей
users:
admin:
disabled: false
displayname: 'Администратор'
# Вставьте полный хэш из предыдущей команды:
password: '$argon2id$v=19$m=65536,t=3,p=4$ВАШHЭШ'
email: 'admin@example.ru'
groups:
- adminsЧтобы добавить второго пользователя — добавьте ещё один блок под ключом users с новым именем. Authelia увидит изменение сразу (параметр watch: true) — перезапуск не нужен.
Запустить Authelia
cd /opt/authelia
docker compose up -dПроверьте что Authelia запустилась и слушает порт 9091:
docker compose logs -f autheliaВ логах должны быть строки level=info msg="Startup complete". Если есть ошибки — скорее всего опечатка в configuration.yml (YAML чувствителен к отступам).
6. Настройка Nginx
Настройка состоит из двух частей: виртуальный хост для самой Authelia, и защита ваших приложений через forward auth.
Шаг 1: виртуальный хост Authelia
Это страница входа — auth.example.ru. Сначала создайте минимальный HTTP-конфиг — он нужен certbot для прохождения ACME-проверки:
server {
listen 80;
server_name auth.example.ru;
}sudo ln -s /etc/nginx/sites-available/auth.example.ru /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxsudo certbot certonly --nginx -d auth.example.ruТеперь замените содержимое файла на полный конфиг с HTTPS:
server {
listen 80;
server_name auth.example.ru;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name auth.example.ru;
ssl_certificate /etc/letsencrypt/live/auth.example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.example.ru/privkey.pem;
# Внутренний endpoint для проверки авторизации (используется другими хостами)
location /internal/authelia/authz {
internal;
proxy_pass http://127.0.0.1:9091/api/authz/auth-request;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-URI $request_uri;
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
}
# Веб-интерфейс Authelia (страница входа)
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}sudo nginx -t && sudo systemctl reload nginxШаг 2: защитить приложение
Теперь добавим защиту Authelia к любому приложению. Пример — Grafana на grafana.example.ru. Сначала создайте HTTP-конфиг и получите сертификат:
server {
listen 80;
server_name grafana.example.ru;
}sudo ln -s /etc/nginx/sites-available/grafana.example.ru /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot certonly --nginx -d grafana.example.ruЗамените содержимое файла на полный конфиг с forward auth:
server {
listen 80;
server_name grafana.example.ru;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name grafana.example.ru;
ssl_certificate /etc/letsencrypt/live/grafana.example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/grafana.example.ru/privkey.pem;
location / {
# --- Authelia forward auth ---
# Перед каждым запросом спрашиваем Authelia: можно?
auth_request /internal/authelia/authz;
# Сохраняем данные о пользователе из ответа Authelia
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
# Если Authelia вернула 401 — редирект на страницу входа
# После входа Authelia вернёт пользователя обратно (&rd=...)
error_page 401 = @authelia_redirect;
# Передаём информацию о вошедшем пользователе в бэкенд
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
# --- конец блока Authelia ---
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Редирект на страницу входа Authelia
location @authelia_redirect {
internal;
return 302 https://auth.example.ru/?rd=$scheme://$http_host$request_uri;
}
# Сюда Authelia делает internal-запрос для проверки сессии
location /internal/authelia/authz {
internal;
proxy_pass http://127.0.0.1:9091/api/authz/auth-request;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-URI $request_uri;
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
}
}sudo nginx -t && sudo systemctl reload nginxДля каждого следующего приложения
Повторите ту же схему: создайте HTTP-конфиг → ln -s → certbot → замените на полный конфиг с HTTPS. Блоки auth_request, @authelia_redirect и /internal/authelia/authz одинаковые во всех конфигах — просто скопируйте, замените server_name и порт proxy_pass.
7. Первый вход и настройка TOTP
Откройте браузер и перейдите на любой защищённый поддомен — например grafana.example.ru. Вас перенаправит на страницу входа Authelia.
Первая авторизация — пошагово
- 1
Ввести логин и пароль
Имя пользователя из users_database.yml (например: admin) и пароль, хэш которого вы сгенерировали.
- 2
Зарегистрировать TOTP
При первом входе Authelia покажет QR-код. Откройте Google Authenticator → «+» → «Сканировать QR-код». Сканируйте. QR-код показывается только один раз — сканируйте сразу!
- 3
Ввести код из приложения
Приложение покажет 6-значный код, который меняется каждые 30 секунд. Введите его для подтверждения.
- 4
Authelia сохраняет сессию
Вас перенаправит обратно на Grafana. Теперь все поддомены открываются без повторного входа до истечения сессии (12 часов по умолчанию).
QR-код показывается только один раз
Если вы закрыли страницу до сканирования — не страшно. Сбросьте TOTP и начните заново: docker exec authelia authelia storage user totp delete admin. При следующем входе QR-код появится снова.
8. Гибкие правила доступа
Правила в access_control.rules применяются по порядку — срабатывает первое совпавшее. Authelia поддерживает четыре политики:
| Политика | Что делает | Когда использовать |
|---|---|---|
bypass | Пропускает без авторизации | Публичные сайты, API-эндпоинты, сама Authelia |
one_factor | Только логин + пароль | Приложения без 2FA (если вы доверяете сети) |
two_factor | Пароль + TOTP-код | Все чувствительные приложения — рекомендуется |
deny | Блокирует запрос | Явно запретить доступ (обычно не нужно при default_policy: deny) |
Примеры правил
access_control:
default_policy: deny
rules:
# Authelia сама — без авторизации
- domain: 'auth.example.ru'
policy: bypass
# Публичный сайт — без авторизации
- domain: 'blog.example.ru'
policy: bypass
# Grafana только для группы admins, и только с 2FA
- domain: 'grafana.example.ru'
subject: 'group:admins'
policy: two_factor
# n8n — достаточно одного пароля
- domain: 'n8n.example.ru'
policy: one_factor
# Все остальные поддомены — два фактора
- domain: '*.example.ru'
policy: two_factorВторой пользователь с ограниченным доступом
Добавьте в users_database.yml второго пользователя с другой группой:
users:
admin:
disabled: false
displayname: 'Администратор'
password: '$argon2id$...'
email: 'admin@example.ru'
groups:
- admins
vasya:
disabled: false
displayname: 'Василий'
password: '$argon2id$...' # отдельный хэш пароля Василия
email: 'vasya@example.ru'
groups:
- familyТеперь можно ограничить Nextcloud только группой family:
- domain: 'nextcloud.example.ru'
subject: 'group:family'
policy: two_factorИзменения в configuration.yml применяются после перезапуска контейнера:docker compose restart authelia
9. Частые проблемы
Authelia запустилась, но при входе бесконечный редирект
Причина: неправильный домен в session.cookies.domain — указан поддомен вместо базового, или домен не совпадает с адресом сайта.
Решение:
session:
cookies:
- domain: 'example.ru' # НЕ auth.example.ru
authelia_url: 'https://auth.example.ru'Nginx выдаёт 500 при обращении к защищённому приложению
Причина: блок /internal/authelia/authz не определён в данном server-блоке. Он должен быть в каждом виртуальном хосте, который использует auth_request.
Решение:
Скопируйте блок location /internal/authelia/authz из примера выше в каждый защищённый server-блок.
Authelia не запускается: ошибка в конфиге
YAML очень требователен к отступам. Используйте только пробелы (не табуляции), и одинаковое количество пробелов на каждом уровне.
Диагностика:
docker compose logs authelia | grep -i errorВ логах будет указана строка с ошибкой. Проверьте отступы вокруг неё.