MAATRIX / Блог / Как установить и настроить Authelia на VPS

Как установить и настроить Authelia на VPS

MAATRIX

Если на сервере крутится десяток self-hosted сервисов — Grafana, Portainer, какая-нибудь внутренняя админка — рано или поздно встаёт вопрос: у половины из них слабая или вообще отсутствующая аутентификация, и настраивать логин отдельно в каждом приложении утомительно и ненадёжно. Authelia решает это одним слоем: она встаёт перед вашими сервисами как forward-auth сервер, проверяет логин и второй фактор один раз, а дальше пускает пользователя дальше через Nginx или Traefik. Ниже — рабочая установка на VPS с Docker Compose, от нуля до защищённого дашборда за 2FA.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое forward-auth и зачем он нужен

Authelia не проксирует трафик сама — она отвечает на один-единственный вопрос: «этот пользователь авторизован для этого запроса или нет?». Работает это так:

  1. Пользователь идёт на grafana.example.com.
  2. Nginx или Traefik, прежде чем отдать ответ, делает внутренний подзапрос к Authelia (auth_request в Nginx, middleware forwardAuth в Traefik).
  3. Если у пользователя нет валидной сессии — Authelia отвечает 401, и прокси редиректит его на страницу логина auth.example.com.
  4. После успешного логина (пароль + при необходимости TOTP-код) Authelia ставит сессионную куку на домен .example.com, и все поддомены её видят.
  5. Дальнейшие запросы к любому защищённому сервису проходят проверку сессии мгновенно, без повторного ввода пароля.

Плюс схемы — единый вход (SSO) и 2FA для всего, что стоит за прокси, без правок кода приложений. Минус — лишний компонент в цепочке и единая точка отказа: упадёт Authelia — упадёт доступ ко всем защищённым сервисам разом. Для критичных панелей закладывайте это в план резервирования.

Authelia — не замена полноценному identity-провайдеру уровня Keycloak: сложные сценарии с множеством клиентов и федерацией через SAML ей не по силам (хотя базовый OIDC-provider в ней тоже есть). Если нужен полноценный SSO для десятков приложений — присмотритесь к Keycloak в Docker Compose. Authelia же хороша именно как лёгкая прослойка для сервисов, у которых своей аутентификации нет или она слабая.

Требования и подготовка сервера

Authelia — компактный бинарник на Go, ресурсов ест немного: 512 МБ RAM и 1 vCPU достаточно даже вместе с Redis. Понадобится:

  • VPS с Ubuntu 24.04 (подойдёт любой дистрибутив с Docker, но команды ниже — под Ubuntu);
  • установленные Docker и Docker Compose plugin;
  • домен с возможностью создавать поддомены (например, auth.example.com, app.example.com);
  • уже работающий реверс-прокси — Nginx или Traefik — с выпущенным SSL-сертификатом.

Если прокси ещё не настроен — сначала разверните его: Nginx как reverse-proxy на VPS или Traefik на VPS. Ниже разберём оба варианта интеграции — выбирайте свой.

Создайте рабочую директорию и структуру:

sudo mkdir -p /opt/authelia/config
sudo mkdir -p /opt/authelia/secrets
cd /opt/authelia

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка Authelia через Docker Compose

Базовый docker-compose.yml с Redis для хранения сессий (без него сессии живут только в памяти контейнера и теряются при рестарте):

services:
  authelia:
    image: authelia/authelia:4.38
    container_name: authelia
    restart: unless-stopped
    volumes:
      - ./config:/config
    networks:
      - proxy
    environment:
      - TZ=Europe/Moscow
    expose:
      - "9091"
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    container_name: authelia-redis
    restart: unless-stopped
    volumes:
      - redis-data:/data
    networks:
      - proxy

networks:
  proxy:
    external: true

volumes:
  redis-data:

Сеть proxy должна быть общей с вашим реверс-прокси (создайте её заранее: docker network create proxy, если ещё не создана). Версию образа 4.38 на конец августа 2026 стоит свериться с актуальным тегом на Docker Hub — проект обновляется часто.

Теперь конфиг config/configuration.yml — сердце всей настройки:

theme: dark

server:
  address: 'tcp://:9091'

log:
  level: info

totp:
  issuer: example.com

authentication_backend:
  file:
    path: /config/users_database.yml

access_control:
  default_policy: deny
  rules:
    - domain: "*.example.com"
      policy: one_factor
    - domain: "grafana.example.com"
      policy: two_factor

session:
  name: authelia_session
  domain: example.com
  expiration: 1h
  inactivity: 5m
  redis:
    host: redis
    port: 6379

regulation:
  max_retries: 3
  find_time: 2m
  ban_time: 5m

storage:
  local:
    path: /config/db.sqlite3

notifier:
  filesystem:
    filename: /config/notification.txt

Замените example.com на ваш домен. access_control — ядро логики: по умолчанию всё запрещено (deny), а правилами разрешаете доступ по доменам и указываете, нужен ли только пароль (one_factor) или пароль плюс TOTP (two_factor). Для чувствительных панелей вроде Grafana ставьте two_factor без исключений.

Секцию notifier в продакшене лучше заменить с filesystem на smtp (address: 'submission://smtp.example.com:587', sender, username) — иначе ссылки для сброса пароля будут падать в текстовый файл внутри контейнера, а не приходить на почту. Пароль от SMTP не пишите в основной конфиг — вынесите его через переменную окружения с суффиксом _FILE, как секреты ниже.

Секреты и хеширование сессий

Authelia требует несколько случайных секретов — не должны совпадать и не должны попадать в репозиторий. Сгенерируйте:

cd /opt/authelia/secrets
openssl rand -hex 32 > jwt_secret
openssl rand -hex 32 > session_secret
openssl rand -hex 32 > storage_encryption_key
openssl rand -base64 32 > smtp_password
chmod 600 *

Подключите их в docker-compose.yml через переменные окружения _FILE:

services:
  authelia:
    # ...
    environment:
      - AUTHELIA_JWT_SECRET_FILE=/secrets/jwt_secret
      - AUTHELIA_SESSION_SECRET_FILE=/secrets/session_secret
      - AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE=/secrets/storage_encryption_key
      - AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/secrets/smtp_password
    volumes:
      - ./config:/config
      - ./secrets:/secrets:ro

Файлы монтируются read-only, процесс читает значение при старте. Если сервер придётся переносить — не забудьте перенести и папку secrets, без неё зашифрованное хранилище станет нечитаемым.

Пользователи и пароли

По умолчанию Authelia хранит пользователей в YAML-файле — нормально для 1-20 человек, для большего числа смотрите в сторону LDAP-бэкенда. Создайте config/users_database.yml:

users:
  admin:
    displayname: "Admin"
    password: "$argon2id$v=19$m=65536,t=3,p=4$..."
    email: admin@example.com
    groups:
      - admins

Хеш пароля генерируется встроенной утилитой контейнера, вводить пароль в открытом виде в файл нельзя:

docker run --rm authelia/authelia:4.38 authelia crypto hash generate argon2 --password 'ваш-пароль'

Команда выведет строку вида $argon2id$v=19$m=65536,t=3,p=4$... — её и вставляете в password:. Argon2id — рекомендуемый алгоритм по умолчанию, менять его нет смысла без специфичных требований совместимости.

Запускаем стек:

docker compose up -d
docker compose logs -f authelia

В логах должно появиться Startup complete без ошибок парсинга конфига — Authelia довольно строго валидирует YAML при старте и сразу падает при опечатке, что удобно для отладки.

Интеграция с Nginx

С Nginx добавьте сначала общий блок для аутентификации, а затем подключайте его к каждому защищаемому server:

# /etc/nginx/snippets/authelia-location.conf
location /authelia {
    internal;
    proxy_pass http://authelia:9091/api/verify;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header Content-Length "";
    proxy_pass_request_body off;
}

location @authelia_proxy_signin {
    internal;
    return 302 https://auth.example.com/?rd=$target_url;
}

В блоке защищаемого сервиса (например, grafana.example.com):

server {
    server_name grafana.example.com;

    auth_request /authelia;
    auth_request_set $target_url $scheme://$http_host$request_uri;
    error_page 401 = @authelia_proxy_signin;

    auth_request_set $user $upstream_http_remus_user;
    proxy_set_header Remote-User $user;
    auth_request_set $groups $upstream_http_remote_groups;
    proxy_set_header Remote-Groups $groups;

    include /etc/nginx/snippets/authelia-location.conf;

    location / {
        proxy_pass http://grafana:3000;
    }
}

Заголовки Remote-User и Remote-Groups передают приложению информацию о пользователе, если оно умеет читать headers-based авторизацию (Grafana умеет через auth.proxy). Если приложение об этом не знает — просто получаете защиту входа без проброса личности внутрь.

Интеграция с Traefik

С Traefik интеграция чище — через middleware, без ручного дублирования location-блоков в каждом конфиге. В docker-compose.yml сервиса Authelia добавьте labels:

  authelia:
    # ...
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.authelia.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
      - "traefik.http.services.authelia.loadbalancer.server.port=9091"
      - "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.example.com/"
      - "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
      - "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"

А в защищаемом сервисе достаточно одной строки:

  grafana:
    # ...
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.grafana.rule=Host(`grafana.example.com`)"
      - "traefik.http.routers.grafana.middlewares=authelia@docker"

Это удобнее Nginx-варианта: защита нового сервиса — одна label, а не блок location. Поэтому связка Traefik + Authelia часто встречается в небольших продакшен-инсталляциях с десятком контейнеров.

Проверка и типичные проблемы

Откройте https://grafana.example.com — должно перекинуть на https://auth.example.com/?rd=.... Введите логин/пароль, при первом входе Authelia предложит настроить TOTP — отсканируйте QR-код приложением-аутентификатором (Google Authenticator, Aegis, 1Password) и введите код подтверждения.

Частые проблемы при первой настройке:

  • Кука не долетает до поддоменов. Проверьте, что session.domain — это родительский домен (example.com), а не поддомен, и что Authelia и защищаемые сервисы сидят на реальных поддоменах этого корня.
  • 401 без редиректа. Обычно error_page 401 = @authelia_proxy_signin не сработал — проверьте, что блок объявлен раньше остальных location: Nginx матчит по порядку директив внутри server.
  • Redis недоступен, сессии не сохраняются между рестартами. Убедитесь, что redis в одной сети с authelia и что session.redis.host — это имя сервиса, а не localhost.
  • Argon2-хеш не проходит валидацию. Хеш должен быть сгенерирован той же версией образа — при мажорном апгрейде формат менялся, пересоздайте пользователей после апдейта.

Для отладки временно поднимите log.level: debug — Authelia подробно пишет, на каком шаге отклонила запрос.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Authelia бесплатна для коммерческого использования?

Да, это open-source проект под Apache 2.0, ограничений на коммерческое использование нет.

Можно ли использовать Authelia без Docker?

Да, есть бинарные сборки под Linux, но Docker Compose — самый предсказуемый способ развёртывания и обновления, особенно вместе с Redis.

Заменяет ли Authelia VPN?

Нет, она защищает вход в веб-сервисы через прокси, но не создаёт сетевой туннель и не скрывает факт существования сервиса в интернете. Для доступа без публикации портов наружу сочетайте её с WireGuard или закрывайте панель фаерволом.

Что будет, если контейнер Authelia упадёт?

Все защищённые сервисы станут недоступны — это единая точка отказа. Настройте restart: unless-stopped и мониторинг контейнера.

Нужен ли отдельный SSL-сертификат для auth.example.com?

Да, он выпускается так же, как для остальных поддоменов, через Let's Encrypt.

Как защитить сам конфиг Authelia от брутфорса пароля?

Секция regulation в конфиге уже ограничивает число попыток (max_retries) и банит на время (ban_time) — плюс не будет лишним поставить fail2ban перед Nginx как дополнительный слой на уровне сетевых попыток.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →