Установка и настройка matrix (Synapse), MAS, LiveKit, lk‑jwt‑service, Element‑web, Ketesa совместно с панелью 3x‑ui

от автора

Возникла идея написать подробную инструкцию по установке и настройке matrix. Всё, что нашёл в интернете — это либо устаревшая, неактуальная информация 3–4 летней давности без использования MAS, либо неполная информация с обрезанными конфигурационными файлами, по типу «догадайся сам и допиши». Также все инструкции, которые есть в интернете, в основном, по установке в контейнере docker. Я же поделюсь с вами инструкцией по установке без каких либо контейнеров.

В условиях блокировки Телеграм и других популярных мессенджеров, протокол matrix дает возможность организовать, например, связь между членами семьи, родственниками и друзьями, не используя ВПН. Постараюсь доступно объяснить и показать все шаги установки и настройки, чтобы это было понятно большинству «чайников». Под «чайниками» я подразумеваю людей, которые знают, что такое терминал в линукс и на базовом уровне умеют им пользоваться.

Возможно, я «перегрузил» статью описанием разделов и параметров конфигураций Synapse и MAS, но просто предоставить конфигурационный файл без объяснения, для чего нужен тот или иной параметр, было бы неправильно. Я максимально подробно «разобрал» эти две самых главных конфигурации.

Зачем нужна установка matrix совместно с панелью 3x‑ui? Всё просто — для экономии денег. Если у вас уже есть сервер с установленной панелью, то зачем арендовать еще один сервер для matrix? Всё можно установить на один сервер. Другой вопрос — правильно ли это? Возможно, нет, но у меня такая схема работает несколько месяцев без сбоев.

В качестве сервера я решил использовать Synapse. Потому что:

  1. Это эталонная, самая первая реализация сервера для matrix. Synapse разрабатывается той же командой (ранее matrix.org, сейчас element‑hq), что и сам протокол, он является главным полигоном для внедрения всех новых функций и реализует все функции протокола Matrix.

  2. Максимальная совместимость со спецификацией matrix.

  3. Есть подробная документация по конфигурации.

  4. Нативная поддержка функции Simplified Sliding Sync, которая поддерживается в новых клиентах, например, в Element X.

  5. Для Synapse есть панель администрирования Ketesa.

Для слабого сервера Synapse не совсем подходящий вариант в плане производительности, но если не использовать федерацию, то даже 1 ГБ оперативной памяти хватит на сотню пользователей при общении tet‑a-tet в приватных комнатах. У Synapse есть перспективная альтернатива — tuwunel. Этот сервер потребляет оперативной памяти в разы меньше, что делает его «имбой» для использования на слабом «железе». Но, всегда есть «но». Поддержку MAS в tuwunel добавили с версии 1.8.0, и пока непонятно, как это всё будет работать. Чтобы говорить о полноценной и некорявой работе с MAS, нужны испытания и отзывы. Также в tuwunel нет графической панели администратора, все команды для управления сервером нужно вводить вручную, что для кого-то будет не очень удобным. В этом плане Synapse с Ketesa выглядят интереснее. Если у вас слабое «железо», вышеперечисленные нюансы вам не критичны и нужна именно высокая производительность, то смело устанавливайте tuwunel.

В качестве клиента для андроид я выбрал Element X. Потому что:

  1. Он написан на Rust и работает быстрее того же Element Classic.

  2. Есть поддержка Simplified Sliding Sync. Вход в приложение и отображение сообщений происходят мгновенно, независимо от того, в скольких тысячах комнат вы состоите.

  3. Полноценные групповые звонки через Element Call (MatrixRTC + Livekit).

  4. Поддерживает сквозное шифрование (E2EE) аудио и видео.

  5. Это перспективный клиент, он развивается и обновляется.

Matrix Authentication Service (MAS) новый сервис аутентификации, заменяющий встроенную в Synapse систему логинов и паролей. MAS решает проблему с переходом на современные стандарты OAuth2.0 и OIDC (OpenID Connect). Разделяет обязанности, сервера занимаются своим делом — синхронизацией комнат, сообщений и шифрованием, MAS своим — аутентификацией. MAS не нужен для работы Element X, но MAS необходим для регистрации на сервере matrix через Element X.

LiveKit это современная open‑source платформа для передачи аудио и видео в реальном времени. Если совсем просто, это готовый «движок» для создания групповых звонков, видеоконференций и стриминга. В контексте экосистемы Matrix и Element X он выполняет роль медиа‑сервера (SFU — Selective Forwarding Unit). Его задача — взять видеопотоки от участников группового созвона, быстро распределить их и раздать всем остальным. Сам Synapse работать с тяжелым видео‑ и аудиотрафиком не умеет, поэтому для групповых звонков (от 3 человек и более) ему делегируют эту задачу в связке с LiveKit. Работает на базе технологии WebRTC.

MatrixRTC Authorization Service (lk‑jwt‑service). Это мостик между Synapse и LiveKit. У LiveKit «из коробки» нет встроенного понимания, кто является легитимным пользователем Matrix, а кто — нет. Возникает ситуация: Вы не можете сделать сервер LiveKit полностью открытым для интернета, иначе любой посторонний сможет использовать ваши серверные мощности для своих трансляций. Вы не можете просто раздать всем пользователям единый пароль от LiveKit, так как это небезопасно. MatrixRTC Authorization Service решает эту проблему. Он проверяет личность Matrix‑пользователя и выписывает ему временный «пропуск» для входа в виде JSON Web Token (JWT).

Схема совместной работы Synapse и 3x‑ui на одном сервере (и домене) выглядит так: наружу порт 443 слушает только xray, который принимает весь трафик, идущий на сервер. Трафик, который не предназначен для него (трафик matrix‑synapse), xray через настроенный fallback направляет в веб‑сервер nginx. Тот, в свою очередь, направляет трафик нужным сервисам, таким как Synapse, MAS, LiveKit, lk‑jwt‑service.

Подразумевается, что у вас есть арендованный VPS сервер с установленной операционной системой (Ubuntu/Debian server), установлена панель 3x‑ui, вы умеете пользоваться ssh клиентом, например, PuTTY (или любым другим) и он настроен для соединения с вашим VPS сервером, а также умеете работать с текстовым редактором nano.

В начале, перед всеми установками, предоставлю конфигурационный файл nginx, вы можете просто копировать его содержимое в ваш файл. На моем сервере конфигурационный файл nginx находится по пути /etc/nginx/sites‑enabled/config

config
server {    listen 127.0.0.1:8080;    server_name servername;    root /var/www/html;    index index.htm index.html;    # Маршрутизация веб-интерфейса MAS и протоколов OAuth2/OIDC на порт 8082    # Перенаправляет страницы авторизации, регистрации, настроек аккаунта, а также системные манифесты,    # GraphQL API, политики конфиденциальности и стандартные конфигурации OpenID/OAuth2.    # Строго передает заголовок HTTPS, необходимый для работы безопасности OAuth2.    location ~ ^/(login|register|account|assets|oauth2|authorize|api|graphql|reauth|consent|complete-compat-sso|link|device|logout|\.well-known/(openid-configuration|oauth-authorization-server)|manifest\.webmanifest|policy\.txt|favicon\.ico) {        proxy_http_version 1.1;        proxy_pass http://127.0.0.1:8082;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto https;    }    # Перенаправление запросов авторизации (вход, выход, обновление токенов) на MAS    # Регулярное выражение перехватывает эндпоинты login, logout и refresh для версий API v1, v3 и unstable.    # Трафик отправляется на порт 8082 (Matrix Authentication Service), обеспечивая работу OIDC/OAuth2.    location ~ ^/_matrix/client/(v1|v3|unstable)/(login|logout|refresh) {        proxy_http_version 1.1;        proxy_pass http://127.0.0.1:8082;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto https;    }      # Взаимодействие с другими серверами Matrix (Федерация)    # Этот блок перенаправляет служебные запросы от удаленных серверов экосистемы Matrix    # на внутренний порт Synapse (8008), позволяя обмениваться сообщениями с внешним миром.    location /_matrix/federation/ {        proxy_pass http://127.0.0.1:8008;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-Proto $scheme;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    }    # Настройка автообнаружения Matrix (Серверные и клиентские файлы конфигурации)    # Эти блоки описывают отдачу служебных конфигураций из папки .well-known.    # - default_type application/json: принудительно сообщает браузерам и клиентам, что ответ является JSON-документом.    # - add_header Access-Control-Allow-Origin *: включает CORS (разрешает любым веб-клиентам, например Element Web, запрашивать эти файлы).    location /.well-known/matrix/client {        default_type application/json;        add_header Access-Control-Allow-Origin *;    }    location /.well-known/matrix/server {        default_type application/json;        add_header Access-Control-Allow-Origin *;    }      # Проксирование запросов к административному API Synapse (Synapse Admin API)    # Этот блок необходим для работы графических панелей управления (например, Ketesa).    # Он перенаправляет запросы управления сервером, комнатами и пользователями на внутренний порт 8008.    # Передает реальный IP-адрес администратора ($remote_addr) для корректного ведения логов безопасности.    location /_synapse/admin/ {        proxy_pass http://127.0.0.1:8008;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $remote_addr;        proxy_set_header X-Forwarded-Proto $scheme;    }    # Маршрутизация веб-интерфейса панели управления Ketesa (SPA-режим)    # Директива try_files ищет физический файл на диске. Если пользователь обновляет страницу     # внутри панели (например, /admin/users), Nginx не найдет такую папку и перенаправит     # запрос на /admin/index.html. Это позволяет JavaScript-роутеру Ketesa корректно работать.    location /admin/ {        try_files $uri $uri/ /admin/index.html;    }    # Агрессивное кэширование статики для ускорения работы Ketesa    # Регулярное выражение перехватывает все картинки, шрифты, скрипты и стили панели управления.    # Инструктирует браузер сохранить эти файлы у себя в памяти на 30 дней (expires 30d),    # чтобы не скачивать их заново при каждом открытии панели, экономя трафик вашего VPS.      location ~* ^/admin/.*\.(?:css|js|jpg|jpeg|gif|png|svg|ico|woff|woff2|ttf|eot|webp)$ {        expires 30d; # Set caching for static assets        add_header Cache-Control "public";    }      # Глобальное сжатие текстовых данных (Gzip)    # Включает архивацию ответов сервера «на лету» для всех текстовых форматов (HTML, CSS, JSON, JS).    # Сжимаются только ответы крупнее 1000 байт. Это значительно ускоряет загрузку интерфейса Ketesa    # на мобильных устройствах или медленном интернете.      gzip on;    gzip_types text/plain application/javascript application/json text/css text/xml application/xml+rss;    gzip_min_length 1000;    # Проксирование эндпоинта Matrix Rendezvous (Вход по QR-коду в Element X)    # Этот блок необходим для работы функции «Войти на новом устройстве с помощью QR-кода».    # Он перенаправляет сигнальный трафик связывания устройств на внутренний порт Synapse 8008.      location ~ ^/_synapse/client/rendezvous {        proxy_pass http://127.0.0.1:8008;        proxy_http_version 1.1;        proxy_set_header X-Forwarded-For $remote_addr;        proxy_set_header X-Forwarded-Proto $scheme;        proxy_set_header Host $host;        proxy_buffering off;        gzip off;    }    # Маршрутизация стандартизированного API Rendezvous (Вход в Element X по QR-коду)    # Этот блок обрабатывает запросы по спецификации MSC4108 (Matrix Spec Change) для связывания устройств.    # Трафик пересылается на порт 8008 к Synapse.    # - proxy_buffering off & gzip off: критически важно отключить буферизацию и сжатие, так как     #   процесс обмена ключами шифрования происходит в реальном времени через Long Polling.    location ~ ^/_matrix/client/unstable/org.matrix.msc4108/rendezvous {        proxy_pass http://127.0.0.1:8008;        proxy_http_version 1.1;        proxy_set_header X-Forwarded-For $remote_addr;        proxy_set_header X-Forwarded-Proto $scheme;        proxy_set_header Host $host;        proxy_buffering off;        gzip off;    }    # Основной шлюз для клиентского и служебного API Matrix (на порт 8008 к Synapse)    # Регулярное выражение объединяет три ключевых пути:    # - /_matrix: базовое API обмена сообщениями, звонков и синхронизации комнат.    # - /_synapse/client: внутренние клиентские эндпоинты самого Synapse.    # - /_synapse/mas: служебные запросы взаимодействия со службой аутентификации MAS.    # client_max_body_size 300M задает лимит на размер загружаемых файлов (медиа, видео) в 300 МБ.      location ~ ^(/_matrix|/_synapse/client|/_synapse/mas) {        proxy_pass http://127.0.0.1:8008;        proxy_http_version 1.1;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $remote_addr;        proxy_set_header X-Forwarded-Proto $scheme;        client_max_body_size 300M;    }      # Проксирование трафика медиа-сервера LiveKit (Групповые звонки WebRTC/SFU)    # Перенаправляет сигнальный трафик звонков на порт 7880, где запущен livekit-server.    # - ^~ /livekit/sfu/: приоритетный префиксный путь (отключает проверку регулярных выражений для скорости).    # - Upgrade и Connection: критически важны для апгрейда HTTP-соединения до постоянного WebSocket-туннеля.    # - proxy_buffering off: отключает задержки буферизации для передачи медиапотока «на лету».    # - proxy_..._timeout 120: увеличивает таймауты до 2 минут, чтобы звонки не обрывались в моменты тишины.    location ^~ /livekit/sfu/ {        proxy_pass http://localhost:7880/;        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;        proxy_send_timeout 120;        proxy_read_timeout 120;        proxy_buffering off;        proxy_set_header Accept-Encoding gzip;        proxy_set_header Upgrade $http_upgrade;        proxy_set_header Connection "upgrade";    }    # Проксирование сервиса авторизации звонков LiveKit (Генератор JWT-токенов)    # Перенаправляет запросы на порт 8084 (обычно lk-jwt-service).    # Этот сервис выдает временные цифровые пропуска (JWT) для Element X,    # позволяя пользователям легально подключаться к комнатам видеоконференций.    # Модификатор ^~ отключает регулярные выражения для ускорения обработки запроса.    location ^~ /livekit/jwt/ {        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;        proxy_pass http://localhost:8084/;    }    # Альтернативные эндпоинты авторизации звонков и проверки статуса LiveKit (порт 8084)    # Регулярное выражение перехватывает три корневых пути:    # - sfu/get и get_token: прямые служебные запросы от клиентов для получения JWT-пропусков к звонкам.    # - healthz: стандартная точка проверки работоспособности (Health check) самого сервиса токенов.    # Перенаправляет весь трафик на внутренний порт 8084.    location ~ ^/(sfu/get|get_token|healthz) {        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;        proxy_pass http://127.0.0.1:8084;    }    # Маршрутизация веб-клиента Element Web (Режим SPA)    # Директива try_files проверяет наличие реального файла на диске. Если пользователь обновит    # страницу, находясь внутри комнаты (например, /element-web/#/room/...), Nginx не найдет такую папку    # и перенаправит запрос на index.html, позволяя JavaScript-роутеру Element продолжить работу.    location /element-web/ {        try_files $uri $uri/ /element-web/index.html;    }    # Агрессивное кэширование тяжелой статики (Скрипты, стили, шрифты)    # Перехватывает все медиафайлы, JS и CSS веб-клиента. Инструктирует браузер жестко закэшировать    # их на 1 год (expires 1y). Это ускоряет повторную загрузку Element Web до долей секунды,    # так как браузер берет тяжелые файлы из локального диска, а не качает их заново с вашего VPS.    location ~* ^/element-web/.*\.(?:css|js|jpg|jpeg|gif|png|svg|ico|woff|woff2|ttf|eot|webp)$ {        expires 1y;        add_header Cache-Control "public, max-age=31536000";    }      # Запрет кэширования главного HTML-файла    # Гарантирует, что браузер пользователя никогда не задержит у себя index.html. При каждом входе    # клиент будет проверять этот файл на сервере. Это критически важно: когда вы обновите версию Element Web,    # index.html сошлется на новые JS-скрипты, и пользователи автоматически получат апдейт без очистки кэша.    location /element-web/index.html {        add_header Cache-Control "no-cache, no-store, must-revalidate";    }    # Запрет кэширования конфигурационного файла    # Файл config.json содержит настройки подключения к вашему Homeserver и MAS. Запрет кэширования    # гарантирует, что если вы измените адрес сервера или параметры интеграции, новые настройки    # вступят в силу у всех пользователей мгновенно при следующей перезагрузке страницы.    location ~ /element-web/config\.json$ {        add_header Cache-Control "no-cache, no-store, must-revalidate";    }    # Защита от ботов и сканеров уязвимостей (Блокировка бэкдоров)    # Регулярное выражение отлавливает запросы к скриптам PHP, ASP, JSP, CGI и Perl.    # return 444 — это спецкод Nginx, который мгновенно закрывает TCP-соединение без отправки HTTP-ответа,    # заставляя атакующего бота тратить время на ожидание таймаута и скрывая сам факт работы веб-сервера.    location ~* \.(php|asp|aspx|jsp|cgi|pl)$ {        return 444;    }}

servername замените на имя своего домена.

Порт 8008 предлагается по умолчанию в конфигурации Synapse, но вы можете заменить его на другой. Я оставил 8008.

Порт 8080 предлагается по умолчанию в конфигурациях MAS и lk‑jwt‑service, но так как 8080 порт слушает nginx, то для MAS я выбрал порт 8082, а для lk‑jwt‑service — 8084.

Обратите внимание на строку client_max_body_size 300M; Она определяет максимальный размер файла (картинки, видео, голосового сообщения), который вы или ваши пользователи сможете загрузить на сервер. В моем конфиг. файле указан размер 300 Мегабайт. Значение в этой строке должно совпадать со значением поля max_upload_size в конфиг. файле Synapse.

Проверим синтаксис и целостность конфигурационного файла Nginx:

nginx -t

Если всё в порядке, то должно быть:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

Перезагружаем Nginx:

systemctl restart nginx

Настройка fallback в панели 3x‑ui

Настроим fallback в xray. Заходим в панель 3x‑ui (версия панели на моем сервере 3.4.2), выбираем вкладку «Входящие», в столбце Меню нажимаем на карандаш.

В окне «Изменить подключение» выбираем «Расширенный шаблон». В нем выбираем либо вкладку «Все», либо «Настройки». Находим блок с названием fallbacks и прописываем в поле dest значение 8080.

Нажимаем кнопку «Сохранить изменения», перезапускаем xray. После этого все запросы, не относящиеся к xray, будут направляться им к nginx.

Установка Synapse и PostgreSQL

Далее установим сервер Synapse. Соединяемся с VPS сервером. Для начала проверим обновления и, если они есть, обновим все пакеты в системе:

apt update && apt upgrade

Устанавливаем matrix‑synapse:

apt install matrix-synapse-py3

При установке менеджер пакетов запустит интерактивный скрипт настройки. Скрипт попросит ввести основное имя сервера и на основе этого автоматически генерирует базовый рабочий файл конфигурации, а также уникальные ключи шифрования для подписи серверов. Есть важный нюанс. Если вы только создали сервер и на нем нет пользователей и комнат, а вы написали имя с ошибкой или просто решили изменить имя, то это можно сделать, запустив встроенный скрипт повторно:

dpkg-reconfigure matrix-synapse-py3

Он сам перезапишет файлы конфигурации и создаст новые ключи шифрования под нужное имя. Скрипт снова откроет текстовое окно, вы введете новое имя. Все файлы конфигурации Synapse складываются в одну системную директорию /etc/matrix‑synapse/

Внутри этой директории находятся следующие важные компоненты:

homeserver.yaml — это основной конфигурационный файл Synapse.

homeserver.signing.key — автоматически сгенерированный приватный ключ, которым ваш сервер подписывает события. Его нельзя терять или изменять.

conf.d/ — поддиректория для модульной конфигурации. Современный правильный подход для Debian/Ubuntu пакетов подразумевает, что вы можете не редактировать монолитный homeserver.yaml, а создавать отдельные.yaml файлы внутри папки conf.d/ (например, conf.d/mas.yaml или conf.d/database.yaml), и Synapse автоматически склеит их при старте.

Устанавливаем пакет postgresql. Этот сервер может одновременно обслуживать сотни независимых баз данных. Он будет работать как единый движок и для Synapse, и для MAS:

apt install postgresql

Заходим в консоль:

sudo -u postgres psql

Создаем пользователя Synapse:

CREATE USER synapse_user WITH PASSWORD ‘пароль_для_synapse’;

заменяете пароль_для_synapse своим паролем

Создаем базу данных synapse:

CREATE DATABASE synapse OWNER synapse_user LC_COLLATE = ‘C’ LC_CTYPE = ‘C’;

Подключаемся к созданной базе данных:

\c synapse

Выдаем права:

GRANT ALL PRIVILEGES ON SCHEMA public TO synapse_user;

GRANT CREATE ON SCHEMA public TO synapse_user;

Выходим из базы данных synapse:

\c postgres

Заодно создадим пользователя и базу данных MAS:

CREATE USER mas_user WITH PASSWORD ‘пароль_для_mas’;

CREATE DATABASE mas OWNER mas_user;

Заходим в базу данных MAS:

\c mas

Выдаем права:

GRANT USAGE, CREATE ON SCHEMA public TO mas_user;

Заходим в postgres:

\c postgres

Проверяем, всё ли прошло успешно:

\l

Должно быть так:

Если у вас так же, то поздравляю, значит, вы сделали всё правильно.

Перейдем к редактированию конфиг. файла Synapse:

nano /etc/matrix-synapse/homeserver.yaml

Приведем его к такому виду:

homeserver.yaml
---server_name: servernamelisteners:  - port: 8008    tls: false    type: http    x_forwarded: true    bind_addresses: ['127.0.0.1']    request_id_header: "X-Request-ID"    resources:      - names: [client, federation]        compress: falsedatabase:  name: psycopg2  txn_limit: 10000  args:    user: synapse_user    password: "пароль_для_synapse"    dbname: synapse    host: localhost    port: 5432    cp_min: 2    cp_max: 7log_config: "/etc/matrix-synapse/log.yaml"media_store_path: "/var/lib/matrix-synapse/media"max_upload_size: 300Mdynamic_thumbnails: truethumbnail_sizes:  - width: 32    height: 32    method: crop  - width: 96    height: 96    method: crop  - width: 320    height: 240    method: scale  - width: 640    height: 480    method: scale  - width: 800    height: 600    method: scalemedia_retention:  local_media_lifetime: 30d  remote_media_lifetime: 7dmax_image_pixels: 32Murl_preview_enabled: trueurl_preview_ip_range_blacklist:  - 127.0.0.0/8  - 10.0.0.0/8  - 172.16.0.0/12  - 192.168.0.0/16  - 100.64.0.0/10  - 192.0.0.0/24  - 169.254.0.0/16  - 192.88.99.0/24  - 198.18.0.0/15  - 192.0.2.0/24  - 198.51.100.0/24  - 203.0.113.0/24  - 224.0.0.0/4  - ::1/128  - fe80::/10  - fc00::/7  - 2001:db8::/32  - ff00::/8  - fec0::/10signing_key_path: "/etc/matrix-synapse/homeserver.signing.key"suppress_key_server_warning: true#federation_domain_whitelist: []macaroon_secret_key: "ваш_секрет"event_cache_size: 20Kcaches:  global_factor: 0.2  sync_response_cache_duration: 1menable_search: falseuser_directory:  enabled: true  search_all_users: true  prefer_local_users: true  exclude_remote_users: true  show_locked_users: truelimit_remote_rooms:  enabled: true  complexity: 0.5  complexity_error: "Сервер перегружен. Вход в эту комнату заблокирован администратором для экономии памяти."  admins_can_join: falsepresence:  enabled: falsematrix_authentication_service:  enabled: true  endpoint: http://localhost:8082/  secret: "ваш_секрет_MAS"push:  enabled: true  include_content: true  group_unread_count_by_room: falsematrix_rtc:  transports:    - type: livekit      livekit_service_url: https://servername/livekit/jwtexperimental_features:  msc4140_enabled: true  msc4222_enabled: true  msc2697_enabled: false  msc4108_enabled: true

измените servername на имя своего домена

В конфигурации Synapse очень много разделов, но для работы сервера нужны не все, поэтому я рассмотрю назначение и функции только тех разделов, которые есть в моем конфигурационном файле. Полная конфигурация есть по ссылке.

Конфигурационный файл Synapse в формате yaml и чувствителен к структуре, его необходимо проверить на ошибки перед запуском службы. Команда проверки выглядит так:

yamllint /etc/matrix-synapse/homeserver.yaml

Если проверка выдаст такое:

error line too long (число > 80 characters) (line‑length)

то это не критическая ошибка, а всего лишь предупреждение, что длина строки больше 80 символов. Проигнорируйте это сообщение.

Описание разделов и параметров в конфигурационном файле homeserver.yaml

server_name — эта строка задает общедоступный домен сервера. Имя указанное в этом параметре будет отображаться в конце имен пользователей и адресов комнат, созданных на вашем сервере. Например, если имя сервера example.com, имена пользователей на вашем сервере будут отображаться как @user:example.com. В большинстве случаев следует избегать использования поддомена matrix, такого как matrix.example.com или synapse.example.com в качестве имени сервера. Если все же хотите разместить Synapse на поддомене, сохранив при этом чистое имя servername, то рассмотрим этот вариант далее. Имя сервера должно состоять из строчных букв и может явно указывать порт. Напомню, что изменить имя сервера, если он запущен, вы создали комнаты и начали общение, будет нельзя, поэтому важно правильно настроить его перед запуском Synapse.

Раздел listeners определяет, на каком адресе и порту будет слушать Synapse, какие ресурсы будут размещены на этом порту и какой тип сетевого протокола будет использован. В него входят параметры:

port: номер сетевого порта, который будет слушать Synapse на сервере.

tls: поле определяющее включать ли шифрование внутри Synapse. Так как трафик, в моем случае, идет по схеме xray — nginx — synapse, и xray сам расшифровывает SSL/TLS, то указываем значение false.

type: тип протокола, почти всегда это http, так как Matrix общается через стандартные HTTP API‑запросы. Другими допустимыми параметрами являются manhole и metrics, но они нам не нужны.

x_forwarded: поле определяет, будет ли Synapse использовать заголовок X‑Forwarded‑For в качестве IP‑адреса клиента. Полезно, когда Synapse находится за обратным прокси‑сервером (в моем случае, nginx). Доступно только если в поле type установлено http.

bind_addresses: список локальных адресов для прослушивания. Значение по умолчанию — «все локальные интерфейсы». В моем случае, это localhost или 127.0.0.1

request_id_header: поле с именем заголовка, извлекаемого из каждого входящего запроса, который используется в качестве основы для идентификатора запроса. Идентификатор запроса используется в журналах регистрации и трассировке для сопоставления запросов. Если этот параметр не установлен, Synapse будет автоматически генерировать идентификаторы последовательных запросов. Эта опция полезна, когда Synapse подключен к обратному прокси‑серверу.

resources: список ресурсов, которые будут размещены на этом порту. Позволяет разделять разные типы трафика по разным портам для безопасности или производительности. Включает поля name и compress. Доступен только для listen http.

name: cписок имен HTTP ресурсов. Допустимые имена: client, consent, metrics, federation. Для моих задач нужны только client и federation.

compress: это поле отвечает за HTTP‑сжатие данных (Gzip) на стороне самого Matrix‑Synapse при отправке ответов клиентам или другим серверам. Если этот параметр установлен в true, Synapse будет самостоятельно сжимать передаваемые JSON‑данные (тело сообщений, списки комнат, историю синхронизации) перед тем, как отдать их в сеть. В моем конфигурационном файле стоит значение false, так как в конфиг. файле nginx уже включено глобальное сжатие.

Раздел database определяет базу данных, которую synapse использует для хранения всех своих данных. Включает следующие поля: name, txn_limit, args. Synapse устроен так, что сам по себе он не хранит переписку или настройки в файлах. Абсолютно всё, что происходит на сервере, записывается в базу данных через этот раздел:

  • Учетные записи: логины, хэши паролей, зарегистрированные устройства, токены доступа (включая MAS) и настройки профилей пользователей.

  • История комнат: текст всех сообщений, отправленные файлы (ссылки на них), реакции, emoji и служебные события (кто зашел, кто вышел).

  • Криптографические ключи: ключи сквозного шифрования (E2EE), истории устройств и подписи комнат.

  • Состояние федерации: данные о том, с какими внешними серверами ваш Synapse синхронизирован и на каком моменте истории они находятся.

name: это поле указывает, какой драйвер следует использовать для связи с системами управления базами данных (СУБД): sqlite3 (для SQLite) или psycopg2 (для PostgreSQL). Если имя не указано, Synapse по умолчанию будет использовать SQLite. По умолчанию используется значение «sqlite3». В моем конфиг. файле выбран psycopg2, пакет matrix‑synapse в Ubuntu уже включает его или подтягивает как зависимость.

txn_limit: указывает максимальное количество транзакций, которые необходимо выполнить для каждого соединения перед повторным подключением. 0 означает отсутствие ограничений. По умолчанию установлено значение 0.

args: этот подраздел предоставляет параметры, которые передаются в ядро базы данных, за исключением параметров, начинающихся с cp_, которые используются для настройки пула подключений Twisted.

Небольшое отступление о Twisted

Twisted — это популярный и мощный сетевой фреймворк, написанный на языке Python. Matrix‑Synapse полностью построен поверх Twisted. Именно этот фреймворк отвечает за то, как сервер принимает сетевые запросы от ваших клиентов (Element/Element X), общается с другими серверами и, в данном конкретном случае, как он взаимодействует с базой данных PostgreSQL.

Главная фишка Twisted — асинхронность. Обычные классические программы работают последовательно: если программе нужно сделать запрос к базе данных, она отправляет запрос и «замирает» (ждет), пока диск сервера прочитает данные и PostgreSQL вернет ответ. В это время программа не может обрабатывать другие задачи. Twisted работает совершенно иначе — по принципу асинхронности (Event‑driven / Управление событиями). Он использует один главный поток (так называемый Event Loop или «петля событий»): Synapse через Twisted отправляет тяжелый запрос в PostgreSQL. Но вместо того чтобы послушно ждать ответа, Twisted моментально переключается на другие задачи — например, принимает новое сообщение от вашего Element X или обрабатывает входящий файл. Как только PostgreSQL заканчивает работу и присылает данные, Twisted возвращается к первому запросу и отдает вам историю чата.

Благодаря этому Matrix‑Synapse может одновременно обслуживать сотни подключений и запросов, используя совсем немного процессорного времени. Каждое новое подключение к базе данных PostgreSQL (с вводом логина, пароля, проверкой прав и созданием сетевого сокета) — это очень «дорогая» и медленная операция для процессора VPS. Если бы Synapse создавал новое подключение для каждого клика в мессенджере, сервер бы быстро лег под нагрузкой. Чтобы этого не происходило, Twisted использует Connection Pool (Пул соединений): при запуске Synapse сразу создает, например, 5 постоянных подключений к PostgreSQL и держит их открытыми. Когда вам нужно загрузить чат, Synapse «берет напрокат» одно свободное соединение из пула Twisted, быстро вытягивает данные и тут же возвращает его обратно в пул.

Минимальный набор параметров для работы БД в подразделе args

user: имя пользователя PostgreSQL для подключения. По умолчанию оно совпадает с именем операционной системы пользователя, запускающего приложение. Это имя пользователя которого мы создавали выше — synapse_user.

password: пароль, который будет использоваться, если сервер требует аутентификации по паролю. Это пароль созданный выше для пользователя synapse — «пароль_для_synapse».

dbname: Имя базы данных. По умолчанию оно совпадает с именем пользователя. В моем конфиг. файле это synapse.

host: имя хоста, к которому подключаемся. В моем конфиг. файле это localhost.

port: номер порта для подключения к серверу или расширение имени файла сокета для подключений к Unix‑домену. Если в параметрах host или hostaddr указано несколько хостов, этот параметр может указывать список портов, разделенных запятыми, той же длины, что и список хостов, или может указывать один номер порта, который будет использоваться для всех хостов. Пустая строка или пустой элемент в списке, разделенном запятыми, указывает номер порта по умолчанию, установленный при сборке PostgreSQL. В моем конфиг. файле номер порта 5432.

cp_min и cp_max: параметры пула соединений. Synapse не создает новое подключение к PostgreSQL для каждого действия пользователя (это бы убило производительность). Вместо этого он сразу держит открытыми, например, 2 соединения (cp_min), а при высокой нагрузке (когда пользователи одновременно отправляют много сообщений) может временно открыть до 7 соединений (cp_max). В примере значения 2 и 7 просто потому, что в моем конфиг. файле указаны именно эти значения.

На этом раздел database заканчивается.


строка log_config определяет конфигурационный файл ведения журнала в формате yaml на языке python. По умолчанию используется значение null.

строка media_store_path определяет каталог, в котором хранятся загруженные изображения и вложения. По умолчанию используется «media_store».

dynamic_thumbnails: определяет, следует ли генерировать новые эскизы на лету, чтобы они точно соответствовали разрешению, запрошенному клиентом. Если значение true, то всякий раз, когда клиент запрашивает новое разрешение, сервер генерирует новый эскиз. Если значение false, сервер выбирает эскиз из предварительно рассчитанного списка. По умолчанию установлено значение false.

thumbnail_sizes: список миниатюр для предварительного расчета при загрузке изображения. Параметры для каждой записи включают: width:(целое число) ширина сгенерированного эскиза, height:(целое число) высота сгенерированного эскиза, method:(строка) способ подгонки размеров эскиза. Текущими параметрами являются обрезка (crop) и масштабирование (scale).

max_upload_size: наибольший разрешенный размер загружаемого файла в байтах. Если вы используете обратный прокси‑сервер, вам также необходимо установить это значение в конфигурации вашего обратного прокси‑сервера. По умолчанию установлено значение «50M». В моей конфигурации установлено 300М. Значение этого параметра должно соответствовать значению строки max_upload_size в конфиг. файле nginx.

media_retention: подраздел предназначен для автоматической очистки сервера от старых и неиспользуемых файлов. Он задает правила «срока годности» для картинок, видео, голосовых сообщений и файлов на вашем VPS, чтобы они со временем не забили всё свободное дисковое пространство. Содержит поля: local_media_lifetime и remote_media_lifetime. Эти поля определяют, будут ли удаляться медиафайлы, если к ним не было доступа в течение определенного периода времени. Обратите внимание, что доступ к медиафайлу осуществляется при загрузке в комнате в клиенте или иным образом локальным или удаленным пользователем. Если доступ к медиафайлам никогда не осуществлялся, вместо этого используется время создания медиафайла. Как миниатюры, так и исходный медиафайл будут удалены. Если ни один из этих параметров не задан, то медиафайлы этого типа очищаться не будут. Локальные или кэшированные удаленные носители, помещенные в карантин, не будут удалены. Аналогично, локальные носители, помеченные как защищенные от карантина, не будут удалены.

local_media_lifetime: время без доступа к локальному медиаресурсу, по истечении которого он будет удален. Если доступ к носителю никогда не осуществлялся, вместо этого используется время создания медиафайла. Будут удалены как эскизы, так и исходный медиафайл. Если значение не задано или равно нулю, локальный медиафайл не будет удален. По умолчанию используется значение null. Более понятно: определяет, сколько хранить файлы, которые загрузили вы сами (или пользователи вашего сервера).

remote_media_lifetime: время отсутствия доступа к удаленному медиаресурсу, по истечении которого он будет удален. Если доступ к медиафайлу никогда не осуществлялся, вместо этого используется время создания медиафайла. Будут удалены как эскизы, так и исходный медиафайл. Если значение не задано или равно нулю, удаленный медиафайл не будет удален. По умолчанию используется значение null. Более понятно: определяет, сколько хранить кэш картинок и файлов, «прилетевших» с других серверов Matrix.

url_preview_enabled: определяет автоматический предпросмотр ссылок в чатах (когда кидаешь ссылку на сайт, и Element показывает заголовок и картинку сайта). Чтобы включить, установите значение true. Если включено, необходимо указать черный список url_preview_ip_range_blacklist. По умолчанию установлено значение false. В моем конфиг. файле значение true.

url_preview_ip_range_blacklist: список диапазонов CIDR IP‑адресов, доступ к которым запрещен программе предварительного просмотра URL ссылок. Значений по умолчанию выкл: для работы предварительного просмотра ссылок необходимо явно указать список. Вам следует указать все внутренние службы в вашей сети, к которым вы не хотите допускать Synapse. В противном случае любой пользователь в любой комнате Matrix может заставить ваш Synapse отправлять произвольные запросы GET к вашим внутренним службам, что вызовет серьёзные проблемы с безопасностью (0.0.0.0 и:: всегда находятся в черном списке, независимо от того, указаны ли они здесь явно или нет, поскольку они соответствуют адресам, которые невозможно маршрутизировать). Примечание: Это значение игнорируется, когда используется HTTP‑прокси. По умолчанию используется значение null.

max_image_pixels: максимальное количество пикселей, которые будут отображаться в виде миниатюр. По умолчанию используется значение «32 М».

signing_key_path: путь к ключу подписи, с помощью которого будут подписываться события и запросы федерации. Если этот файл не существует, Synapse создаст новый ключ подписи при запуске и сохранит его в этом файле. Значение по умолчанию равно null. В моем конфиг. файле путь /etc/matrix‑synapse/homeserver.signing.key

federation_domain_whitelist: ограничивает федерацию указанным белым списком доменов. Если не указано иное, по умолчанию все домены будут включены в белый список. Примечание: это не мешает серверу присоединяться к комнатам, в которых находятся серверы, не включенные в белый список. Таким образом, эта опция действительно полезна только для создания «частной федерации», когда группа серверов вносит друг друга в белый список и имеет один и тот же белый список. Здесь хотел бы подробнее объяснить как работает этот параметр.

Это эффект «общего знакомого». Представим ситуацию: вы внесли в белый список только один внешний сервер — matrix.org. Сервер hacker.com у вас заблокирован. Вы заходите в какую‑нибудь публичную комнату, которая создана и крутится на сервере matrix.org. Ваш Synapse подключается к этой комнате на matrix.org (это разрешено, так как matrix.org в белом списке). Но в этой же самой комнате сидят пользователи с сервера hacker.com! Поскольку архитектура Matrix устроена так, что копия комнаты синхронизируется между всеми серверами‑участниками, ваш сервер начнет принимать сообщения и данные комнаты от сервера hacker.com опосредованно, через matrix.org. Вы будете видеть сообщения пользователей из черного списка, а они будут видеть ваши. Прямого соединения между вашим сервером и hacker.com не будет, но внутри этой комнаты вы всё равно будете находиться в одном пространстве. Что значит фраза про «private federation» (приватную федерацию)? Разработчики прямо говорят: этот параметр задумывался не для того, чтобы отгородиться от «плохих» серверов, оставив связь с «хорошими». Он эффективно работает только в одном сценарии: Вы, ваш друг и ваша компания (допустим, 3 отдельных VPS‑сервера) хотите сделать свою закрытую сеть мессенджеров, куда чужакам вход закрыт. Тогда вы делаете следующее: 1.Вы прописываете в белый список домены сервера Друга 1 и Друга 2. 2.Друг 1 прописывает в белый список вас и Друга 2. 3.Друг 2 прописывает в белый список вас и Друга 1. В этом списке нет ни matrix.org, ни других публичных серверов. Все три сервера доверяют только друг другу. Вот в таком сценарии («приватная федерация») чужаки к вам не пролезут ни напрямую, ни через общие комнаты, потому что общих комнат с внешним миром у вас просто не будет. Если хотите полной изоляции, то нужно выключить федерацию. Я оставил эту строку в конфиг. файле (на всякий случай), но закомментировал ее.

macaroon_secret_key: секрет, который используется для подписи токена доступа для гостевых пользователей, токена краткосрочного входа, используемого при входе по единому входу (OIDC или SAML2), и токена, используемого для отписки от уведомлений по электронной почте. Если ничего не указано, используется registration_shared_secret, если он указан; в противном случае секретный ключ выводится из ключа подписи. Внимание! Замена существующего ключа macaroon_secret_key на новый приведет к аннулированию токенов доступа для всех приглашенных пользователей. Это также приведет к разрыву ссылок для отмены подписки в электронных письмах, отправленных до изменения. Неудачливый пользователь может столкнуться со сбоем при входе через SSO, и ему придется начинать все сначала. Подробнее и простым языком об этом параметре.

Параметр macaroon_secret_key — это секретный ключ, который Matrix‑Synapse использует для шифрования и проверки подлинности специальных внутренних токенов, называемых Macaroons (макаруны). В веб‑разработке очень популярны токены JWT (JSON Web Tokens). Но в Synapse для некоторых внутренних задач используются Macaroons — это более продвинутый и гибкий аналог JWT, придуманный в Google. Их главное свойство — делегирование с ограничениями. Сервер может выдать токен, а потом «на лету» сузить его права, не обращаясь к базе данных. В Synapse эти токены используются в основном для: Процесса авторизации/регистрации: когда служба авторизации (например, MAS или консольный скрипт) запрашивает одноразовый талон (nonce) для создания пользователя, Synapse выдает его в виде Macaroon‑токена. Сторонних модулей и капчи: Когда нужно временно подтвердить, что пользователь прошел проверку. Зачем нужен macaroon_secret_key? Чтобы никто в интернете не мог сам подделать такой токен и прикинуться администратором, Synapse подписывает каждый макарун криптографическим ключом. Этот ключ и задается параметром macaroon_secret_key. Если ключ секретный и надежный, никто, кроме Synapse, не сможет прочитать или изменить токен. Если кто‑то узнает этот ключ, он сможет штамповать любые токены и, например, регистрировать пользователей в обход ваших запретов. Ключ можно сгенерировать, например, такой командой:

openssl rand -hex 32

event_cache_size: количество событий, которые нужно кэшировать в памяти. По умолчанию используется значение 10 тыс. Как и в случае с другими кэшами, на это влияет параметр caches.global_factor (см. ниже). Например, значение по умолчанию равно 10 КБ, а значение global_factor по умолчанию равно 0,5. Поскольку 10 КБ * 0,5 равно 5 КБ, размер event cache size будет равен 5 КБ. Кэш, на который влияет эта конфигурация, называется «getEvent». Обратите внимание, что этот параметр не входит в раздел «caches».

Раздел caches: коэффициент кэширования. Это коэффициент, который может быть применен к каждому из кэшей Synapse для увеличения или уменьшения максимального количества записей, которые могут быть сохранены. Этот параметр имеет следующие дополнительные опции:

global_factor: управляет коэффициентом глобального кэширования, который является коэффициентом кэширования по умолчанию для всех кэшей, если для этого кэша не задан конкретный коэффициент. Это также может быть установлено с помощью переменной среды SYNAPSE_CACHE_FACTOR. Настройка с помощью переменной окружения имеет приоритет перед настройкой через конфигурационный файл. Значение по умолчанию равно 0.5, что вдвое уменьшит размер всех кэшей. Обратите внимание, что изменение этого значения также влияет на пул HTTP‑соединений.

sync_response_cache_duration: определяет, как долго кэшируются результаты /sync запроса после получения успешного ответа. Увеличение продолжительности может помочь клиентам с прерывистыми подключениями за счет увеличения объема используемой памяти. Нулевое значение означает, что ответы на синхронизацию не кэшируются. Значение по умолчанию 2m. В моей конфигурации значение 1m. Остальные параметры раздела caches трогать не будем. Этого будет достаточно.

enable_search: если установлено значение false, новые сообщения не будут индексироваться для поиска, и пользователи будут получать сообщения об ошибках при поиске сообщений. По умолчанию установлено значение true. В моем конфиг. файле установлено false. Если простым языком, то при значении false не будет работать поиск по сообщениям и при попытке поиска будет выдавать ошибку. На слабом сервере лучше отключить.

Раздел user_directory определяет параметры, относящиеся к каталогу пользователей, могут ли пользователи выполнять поиск в каталоге пользователей. Если значение false, то на все запросы возвращаются пустые ответы. То есть глобальный поиск пользователей внутри вашего сервера полностью перестанет работать. Чтобы начать чат с кем‑то, вам придется вводить его точный Matrix ID (например, @alex:yourdomain.com). Предупреждение: Хотя домашний сервер может определять, в каком подмножестве пользователей выполняется поиск, спецификация Matrix требует, чтобы домашние серверы включали (как минимум) пользователей, видимых в общественных помещениях, и пользователей, находящихся в одной комнате с запрашивающим. Использование false повышает производительность, но нарушает это требование. По умолчанию используется значение true.

search_all_users: определяет как будет работать поиск пользователей. Когда установлено false, то вы можете найти через поиск пользователя только в том случае, если у вас с ним есть хотя бы одна общая комната. Если на сервере зарегистрирован условный @boss, а вы с ним ни разу не пересекались в чатах, поиск Element его вам просто не покажет. Когда установлено true, то любой зарегистрированный пользователь сервера может через поиск найти абсолютно любого другого пользователя вашего сервера, даже если они вообще не знакомы и не состоят в общих комнатах.

prefer_local_users: определяет, следует ли отдавать предпочтение локальным пользователям в результатах поискового запроса. Если установлено значение true, локальные пользователи с большей вероятностью будут отображаться выше удаленных пользователей при поиске в каталоге пользователя. По умолчанию установлено значение false.

exclude_remote_users: если установлено значение true, поиск будет возвращать только локальных пользователей. По умолчанию установлено значение false. В моем конфиг. файле этот параметр установлен true, так как мне не нужен поиск пользователей по федерации.

show_locked_users: определяет, показывать ли заблокированных пользователей в результатах поискового запроса. По умолчанию имеет значение false.

presence: включает/выключает отслеживание присутствия. Позволяет пользователям видеть состояние (например, онлайн/оффлайн) других локальных и удаленных пользователей. Включение этой функции сильно увеличивает нагрузку на оперативную память, поэтому для слабого «железа» presence лучше отключить.

enabled: установите значение false, чтобы отключить отслеживание присутствия на этом домашнем сервере.

Раздел limit_remote_rooms: когда эта опция включена, перед тем, как пользователь присоединится к новой удаленной комнате, будет проверяться «сложность» комнаты. Если она превышает предельное значение сложности, сервер запретит присоединение или немедленно покинет ее. Это полезно для домашних серверов, которые ограничены в ресурсах. В Synapse сложность комнаты измеряется количеством событий текущего состояния в комнате, разделенных на 500. «Текущий» здесь означает последнее состояние, то есть если пользователь присоединяется, затем уходит, затем присоединяется, это будет засчитываться как 1 текущее событие m.room.member state.

enabled: включена ли эта проверка. Значение по умолчанию равно false.

complexity: предел, при превышении которого комнаты не могут быть присоединены. Значение по умолчанию равно 1.0.

complexity_error: выводит пользовательское сообщение об ошибке когда комната слишком сложная. По умолчанию используется значение «Ваш домашний сервер не может присоединить комнаты такого размера или сложности. Пожалуйста, обратитесь к администратору вашего сервера или обновите свой экземпляр, чтобы присоединиться к этой комнате.»

admins_can_join: позволяет администраторам сервера присоединяться к сложным комнатам. По умолчанию установлено значение false. То есть если установить true, то администратор сможет зайти в ту комнату, при попытке зайти в которую, обычному пользователю выдаст ошибку и сообщение описанное выше.

Раздел matrix_authentication_service настраивает интеграцию с Matrix Authentication Service (MAS). Это «мостик», который связывает сервер Synapse с внешней системой аутентификации MAS. Этот раздел нужен для того, чтобы передать управление логином, регистрацией и сессиями пользователей от самого Synapse к MAS. Содержит следующие поля:

enabled: определяет включать ли интеграцию с MAS. Если для этого параметра задано значение false, Synapse будет использовать свой устаревший внутренний API аутентификации. По умолчанию установлено значение false.

endpoint: URL, по которому Synapse может связаться с MAS. Для этого должны быть подключены ресурсы обнаружения и oauth. По умолчанию используется значение «http://localhost:8080».

force_http2: принудительное использование HTTP/2 через открытый текст (H2C) при подключении к MAS. MAS поддерживает это изначально, но если между Synapse и MAS находится обратный прокси‑сервер, то может не работать. Значение по умолчанию равно false. В моем случае это поле не нужно.

secret: общий секрет, который будет использоваться для проверки подлинности запросов от и к MAS. Важно! Этот секрет должен совпадать с полем secret в разделе matrix в конфиг. файле MAS.

secret_path: альтернативой secret является чтение общего секрета из файла. Файл должен быть в виде обычного текстового файла, содержащего только секрет. Synapse считывает секретный файл из данного файла один раз при запуске. В моем случае не указан, так как уже есть поле secret.

Раздел push определяет параметры push‑уведомлений. Включает следующие поля:

enabled: включает или отключает механизм подсчета уведомлений и непрочитанных сообщений в комнатах. Если установлено false, пользователи перестанут видеть счетчики непрочитанных сообщений в клиентах, и уведомления работать не будут.

include_content: клиенты, запрашивающие push‑уведомления, могут получать либо текст сообщения, отправленного в уведомлении, вместе с другими данными, такими как имя отправителя, либо только идентификатор события и идентификатор комнаты (event_id_only). Если клиенты выбирают отправку основного текста, этот параметр определяет, будет ли запрос уведомления содержать информацию о событии (другие сведения, такие как имя отправителя, по‑прежнему включаются). Если параметр event_id_only включен, это не имеет никакого эффекта. На современных устройствах Android содержимое уведомлений по‑прежнему будет отображаться, поскольку оно загружается приложением. iPhone, однако, отправит уведомление только о том, что пришло сообщение и от кого оно пришло. Установите значение false, чтобы включать только идентификатор события и комнаты в push‑уведомления. По умолчанию установлено значение true.

group_unread_count_by_room: при получении push‑уведомления также отправляется количество непрочитанных сообщений. Это число может быть рассчитано как количество непрочитанных сообщений для пользователя или как количество комнат, в которых у пользователя есть непрочитанные сообщения. Если значение равно true, push‑клиенты будут видеть количество комнат с непрочитанными сообщениями в них. Установите значение false, чтобы вместо этого отправлять количество непрочитанных сообщений. По умолчанию установлено значение true. Если простым языком, то это поле управляет тем, что отображается в бейдже (красном кружке) на иконке приложения. Если true, то бейдж показывает количество комнат, в которых есть непрочитанные сообщения. (Например, если у вас 2 непрочитанных сообщения в одной комнате и 1 в другой, бейдж покажет 2). Если false, то бейдж показывает общее количество непрочитанных сообщений во всех комнатах (в примере выше показал бы 3).

jitter_delay: добавляет случайную задержку (от 0 до указанного значения) перед отправкой уведомления. Это функция безопасности для защиты от «тайминговых атак», когда злоумышленник может определить, что происходит на сервере, по времени задержки ответа. Мне это не нужно.

Раздел matrix_rtc предназначен для настройки современной инфраструктуры звонков MatrixRTC. Этот раздел определяет какой сервер (SFU) использовать для передачи аудио/видео трафика в звонках и конференциях. Содержит подраздел transports: список типов транспорта и аргументов, используемых для подключений MatrixRTC. По умолчанию используется значение [ ]. Содержит поля:

type: тип транспорта, который следует использовать для подключения к блоку избирательной маршрутизации (SFU). Так как далее мы будем устанавливать и настраивать сервер LiveKit, то в этом поле указываем транспорт livekit.

livekit_service_url: базовый URL сервиса LiveKit. Должен использоваться только с транспортами на основе LiveKit.

Раздел experimental_features в конфигурации Synapse нужен для включения нестабильных, разрабатываемых или еще не утвержденных функций. Позволяет опробовать функции, которые еще не стали частью стабильного стандарта Matrix (например, фичи, описанные в еще не принятых MSC — Matrix Spec Changes). Дает разработчикам и продвинутым пользователям возможность протестировать сырые, потенциально «бажные» или неоптимизированные функции, не рискуя сломать работу всего сервера. Все функции в этом разделе по умолчанию отключены. Необходимо осознанно добавить их в homeserver.yaml и установить в true. Я добавил в свою конфигурацию Synapse несколько экспериментальных функций.

msc4140 — это Matrix Spec Change, которое вводит в протокол Matrix концепцию «отложенных событий» (delayed events). Проще говоря, это механизм, позволяющий клиенту (например, приложению Element) поручить Synapse отправить сообщение или изменить состояние комнаты не прямо сейчас, а через заданное время или при наступлении определенного условия. Основная мотивация для создания MSC4140 — решение проблемы надежности VoIP‑звонков, особенно групповых. Ключевые сценарии:

  • Стабильность звонков (MatrixRTC): Представьте, что ваш друг участвует в групповом звонке, и у него внезапно отключается интернет. Вместо того чтобы «зависнуть» в звонке навсегда, его клиент (Element X) может заранее отправить на сервер отложенное событие — «если через 10 секунд не получу подтверждение, что я онлайн, отправь в комнату событие о моем выходе из звонка». Клиент может периодически перезапускать этот таймер, пока звонок активен, а при обрыве связи сервер сам отправит событие о «завершении вызова».

  • Отложенные сообщения: Вы можете написать сообщение и запланировать его отправку в комнату на определенное время или с задержкой.

  • Самоуничтожающиеся сообщения: Можно отправить сообщение, а вместе с ним — отложенное событие на его удаление (редакцию) через определенное время.

msc4222 — это Matrix Spec Change, которое улучшает то, как клиенты (например, Element) получают информацию о состоянии комнаты. Проще говоря, оно делает процесс синхронизации более надежным и точным, что особенно важно для стабильности функций вроде групповых звонков. При обычной синхронизации клиент получает состояние комнаты на момент начала временной шкалы (state). MSC4222 добавляет возможность получать state_after — состояние комнаты на момент конца временной шкалы (то есть актуальное состояние). Это важно для Element Call (MatrixRTC), так как звонки активно используют события членства в комнате для отслеживания участников. state_after гарантирует, что клиент всегда видит правильный текущий статус участников, избегая путаницы, которая могла возникать при использовании старого метода.

msc4108 — это Matrix Spec Change, которое добавляет в Matrix возможность входа в аккаунт и настройки сквозного шифрования (E2EE) на новом устройстве через сканирование QR‑кода. Проще говоря, это функция «Войти по QR‑коду».

На этом описание параметров конфигурации Synapse заканчивается.

Делегирование ресурсов client и federation

Теперь нам нужно сделать делегирование для ресурсов client и federation, которые содержатся в подразделе resources раздела listeners. Делегирование — это функция matrix, позволяющая администратору домашнего сервера сохранять имя сервера равным example.com, чтобы идентификаторы пользователей, псевдонимы комнат и так далее продолжали выглядеть как *:example.com, в то время как трафик федерации перенаправляется на другой сервер и/или порт (например, synapse.example.com:443). По умолчанию другие серверы будут пытаться подключиться к нашему серверу через порт 8448 (порт федерации по умолчанию). И при условии, что https://<server_name>/ на порту 443 перенаправлен на Synapse, этот параметр настраивает Synapse для обслуживания файла по адресу https://<server_name>/.well‑known/matrix/server. Проще говоря, это позволяет вашим друзьям иметь идентификаторы вида @друг:ваш‑домен.ru, даже если сам сервер Matrix физически работает на другом адресе, например, matrix.ваш‑домен.ru., а также позволяет другим серверам отправлять трафик на порт 443 вместо 8448, соответственно не нужно открывать еще один порт наружу.

Создаем папки /.well‑known/matrix/

mkdir -p /var/www/html/.well-known/matrix

Устанавливаем права:

chmod 755 /var/www/html/.well-known

chmod 755 /var/www/html/.well-known/matrix

Создаем файл client:

nano /var/www/html/.well-known/matrix/client

Копируем в него вот это:

client
{  "m.homeserver": {    "base_url": "https://servername"  },  "org.matrix.msc2965.authentication": {    "issuer": "https://servername/",    "account": "https://servername/account/"  },  "org.matrix.msc4143.rtc_foci": [    {      "type": "livekit",      "livekit_service_url": "https://servername/livekit/jwt"    }  ]}

servername замените на имя своего домена

Даем права файлу client:

chmod 644 /var/www/html/.well-known/matrix/client

Проверяем права:

ls -l /var/www/html/.well-known/matrix/client

Должно быть:

‑rw‑r-‑r-‑ 1 root root … /var/www/html/.well‑known/matrix/client

Создаем файл server:

nano /var/www/html/.well-known/matrix/server

Копируем в него такой текст:

server
{  "m.server": "servername:443"}

servername замените на имя своего домена

Даем права файлу server:

chmod 644 /var/www/html/.well-known/matrix/server

Проверяем:

ls -l /var/www/html/.well-known/matrix/server

Должно быть:

‑rw‑r-‑r-‑ 1 root root … /var/www/html/.well‑known/matrix/server

Файл конфигурации Synapse настроен, файлы для делегации созданы и настроены, можно запускать службу:

systemctl start matrix-synapse

Включаем автозагрузку:

systemctl enable matrix-synapse

Проверяем статус:

systemctl status matrix-synapse

Должно быть:

Здесь ключевые строки:

Loaded: loaded (/usr/lib/systemd/system/matrix‑synapse.service; enabled

Active: active (running)

Если у вас также, то значит все хорошо и Synapse запустился и активен. На этом установка и настройка Synapse завершена.

Установка Matrix Authentication Service (MAS)

Последний стабильный релиз устанавливаем с github. Скачиваем архив в папку /tmp (или любую удобную для вас папку):

wget -P /tmp https://github.com/element-hq/matrix-authentication-service/releases/download/v1.19.0/mas-cli-x86_64-linux.tar.gz

вместо v1.19.0 пишите актуальную на данный момент версию

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

useradd --system --no-create-home --shell /usr/sbin/nologin mas

Создаем необходимые папки на сервере для MAS.

Для исполнительного файла:

mkdir -p /opt/mas

Для конфигурационного файла:

mkdir -p /etc/mas

Для данных:

mkdir -p /var/lib/mas

Выдаем права папкам:

chown -R root:root /opt/mas

chmod 755 /opt/mas

chown -R root:mas /etc/mas

chmod 750 /etc/mas

chown -R mas:mas /var/lib/mas

chmod 750 /var/lib/mas

Переходим в папку /tmp:

cd /tmp

Разархивируем архив mas‑cli‑x86_64-linux.tar.gz в /opt/mas:

tar -xvf -C mas-cli-x86_64-linux.tar.gz /opt/mas

Выдаем права этому файлу:

chown root:mas /opt/mas/mas-cli

chmod 750 /opt/mas/mas-cli

Проверяем права:

ls -l /opt/mas/mas-cli

Должно быть:

‑rwxr‑x-‑ 1 root mas … /opt/mas/mas‑cli

Конфиг. файл MAS генерируется через команду:

/opt/mas/mas-cli config generate > /etc/mas/config.yaml

Выдаем права конфиг файлу:

chown -R root:mas /etc/mas/config.yaml

chmod 640 /etc/mas/config.yaml

Проверяем права:

ls -l /etc/mas/config.yaml

Должно быть:

‑rw‑r-‑-- 1 mas mas … /etc/mas/config.yaml

Конфиг. файл сгенерировался и находится в папке /etc/mas и нам нужно его отредактировать и привести к такому виду:

config.yaml
---http:  listeners:    - name: web      resources:        - name: discovery        - name: human        - name: oauth        - name: compat        - name: graphql        - name: assets          path: /opt/mas/share/assets/        - name: adminapi      binds:        - address: "127.0.0.1:8082"      proxy_protocol: false    - name: internal      resources:        - name: health      binds:        - host: localhost          port: 8081      proxy_protocol: false  trusted_proxies:    - 127.0.0.1/8    - ::1/128  public_base: https://servername/  issuer: https://servername/database:  uri: postgresql://mas_user:пароль_для_mas@localhost:5432/mas?sslmode=disable  max_connections: 10  min_connections: 0  connect_timeout: 30  idle_timeout: 600  max_lifetime: 1800email:  from: '"Matrix Auth" <auth@servername>'  reply_to: '"No reply" <auth@servername>'  transport: blackhole#    mode: starttls#    hostname: servername#    port: 587#    username: ваше_имя@servername#    password: "ваш_пароль"secrets:  encryption: 32‑байтный ключ в формате hex, генерируется автоматически   keys:    - key: |        -----BEGIN RSA PRIVATE KEY-----        -----END RSA PRIVATE KEY-----    - key: |        -----BEGIN EC PRIVATE KEY-----        -----END EC PRIVATE KEY-----    - key: |        -----BEGIN EC PRIVATE KEY-----         -----END EC PRIVATE KEY-----    - key: |        -----BEGIN EC PRIVATE KEY-----         -----END EC PRIVATE KEY-----passwords:  enabled: true  schemes:    - version: 1      algorithm: argon2id  minimum_complexity: 3matrix:  kind: synapse  homeserver: servername  endpoint: http://localhost:8008/  secret: ваш_секрет_synapsepolicy:  wasm_module: /opt/mas/share/policy.wasm  data:    admin_users:      - ваше_имя_или_никrate_limiting:  login:    per_ip:      burst: 3      per_second: 0.05    per_account:      burst: 30      per_second: 0.5  registration:    burst: 2    per_second: 0.0008templates:  path: /opt/mas/share/templates  assets_manifest: /opt/mas/share/manifest.json  translations_path: /opt/mas/share/translationsaccount:  displayname_change_allowed: false  password_registration_enabled: true  password_registration_email_required: false  password_change_allowed: false  account_deactivation_allowed: true  login_with_email_allowed: false  registration_token_required: trueoauth:  device_code_grant_enabled: true  device_code_user_code_auto_fill_enabled: false

Измените servername на имя своего домена. Поле uri содержит имя пользователя и пароль — это имя пользователя и пароль, которые мы создавали выше для базы данных MAS, хост — localhost, порт 5432, имя базы данных — mas, дополнительный параметр — sslmode=disable. Значение поля secret в разделе matrix должно совпадать со значением поля secret в разделе matrix_authentication_service в конфиг. файле Synapse. То есть ваш_секрет_synapse = ваш_секрет_MAS. В поле binds в подразделе listeners указан address 127.0.0.1:8082, потому что MAS в моей конфигурации не слушает наружу, а все запросы к нему идут через nginx. По этой же причине в секции http.listeners не указано поле tls. Обратите внимание, что в разделе http.listeners в поле name прописано adminapi. Это включает Admin API в MAS и позволяет Ketesa взаимодействовать с этим API.

Конечно же, некоторые поля вы сами заполняете так, как вам удобно под ваши задачи и требования. Возможно у вас будут другие значения. Также можете изучить и добавить в свой config.yaml разделы, которые я в этом руководстве не рассматривал: clients, captcha, telemetry, upstream_oauth2, branding, experimental.

Полная конфигурация MAS.

Конфиг файл MAS также в формате yaml и нужно проверить его на ошибки перед запуском службы:

yamllint /etc/mas/config.yaml

Описание разделов и параметров конфиг. файла MAS

Раздел http это корневой раздел MAS. Он содержит список слушателей (listeners) и глобальные настройки (trusted_proxies, public_base, issuer)

trusted_proxies: список доверенных reverse‑proxy, MAS доверяет заголовку X‑Forwarded‑For только если запрос пришёл от IP из этого списка.

public_base: публичный URL MAS. Используется для: формирования ссылок в UI, email‑верификации, формирования redirect_uri, OIDC Discovery. Это обязательный параметр.

issuer: OIDC issuer URL. Это URL, который MAS объявляет как свой OIDC‑issuer. У нас он совпадает с public_base, так как MAS работает на одном домене.

Раздел http.listeners описывает какие ресурсы (OAuth, human UI, compat, GraphQL, assets и так далее) обслуживает этот listener, на каких адресах/портах он слушает (binds), использовать ли TLS, использовать ли PROXY protocol, какие reverse‑proxy считаются доверенными (trusted_proxies). Так как MAS установлен на одном сервере с nginx, то в секции trusted_proxies прописываем 127.0.0.1/8 и::1/128, этого будет достаточно.

Каждый resource содержит набор endpoints.

Resource: oauth — основной OAuth2/OIDC API:

  • /oauth2/authorize

  • /oauth2/token

  • /oauth2/device

  • /oauth2/device/complete

  • /oauth2/introspect

  • /oauth2/revoke

  • /oauth2/userinfo

  • /oauth2/registration

  • /oauth2/sessions/logout

  • /oauth2/sessions/logout/complete

  • /oauth2/keys/jwks (JWKS endpoint)

Resource: human — HTML‑интерфейс для пользователя (UI):

  • /login

  • /register

  • /consent

  • /link

  • /device

  • /complete

  • /error

  • /logout

  • /logout/complete

Это именно UI‑страницы, не API.

Resource: compat — Совместимость с Synapse (Matrix login API):

  • /_matrix/client/v3/login

  • /_matrix/client/v3/logout

  • /_matrix/client/v3/logout/all

  • /_matrix/client/v3/account/password

  • /_matrix/client/v3/register

  • /_matrix/client/v3/account/whoami

Resource: graphql — GraphQL API MAS:

  • /graphql (POST)

  • /graphql (GET, introspection)

  • /graphql/playground

Используется UI и админ‑панелью MAS.

Resource: assets — Статические файлы MAS:

  • /assets/* (CSS, JS, изображения, web‑bundle)

Resource: well_known — выдача.well‑known для Matrix и OIDC:

  • /.well‑known/matrix/client

  • /.well‑known/matrix/server

  • /.well‑known/openid‑configuration

Resource: health — health‑check:

  • /health

  • /health/live

  • /health/ready

Resource: discovery — OIDC Discovery:

  • /.well‑known/openid‑configuration

  • /oauth2/keys/jwks

Частично пересекается с другими ресурсами.

Resource: metrics — Prometheus‑совместимые метрики:

  • /metrics

Раздел database — это конфигурация подключения MAS к PostgreSQL. Раздел определяет куда подключаться (URL), как подключаться (TLS, параметры), как управлять пулом соединений, какие миграции применять. MAS хранит в PostgreSQL:

  • OAuth2 / OIDC данные: access tokens, refresh tokens, device codes, session state, consent records

  • Пользовательские данные MAS: учётные записи MAS (если MAS управляет пользователями), привязки Matrix‑аккаунтов, email‑верификации, пароли.

  • Конфигурационные данные: зарегистрированные OAuth‑клиенты, настройки политики, ключи подписи.

  • Логи и аудит: события входа, события регистрации, попытки авторизации.

uri: строка подключения к PostgreSQL, которую MAS передаёт драйверу PostgreSQL. Может указываться как одной строкой, так и с разделенными параметрами. В моем конфиге это поле указано одной строкой. Она включает в себя: протокол, пользователя, пароль, хост, порт, имя базы, дополнительные параметры. Параметр sslmode управляет тем, будет ли клиент (MAS) использовать TLS‑шифрование при подключении к базе. В дополнительных параметрах в моем файле указано sslmode=disable потому что MAS подключается к PostgreSQL, работающему на том же сервере (localhost / 127.0.0.1 / Unix‑socket) и трафик не выходит в сеть, он остаётся внутри ядра ОС, шифрование не нужно.

max_connections: максимальное количество соединений в пуле. MAS никогда не откроет больше одновременных соединений к PostgreSQL указанных в этом поле. Это ограничивает: нагрузку на PostgreSQL, количество параллельных запросов MAS, потребление памяти. Если поставить слишком мало — MAS может «тормозить» под нагрузкой. Если слишком много — PostgreSQL может начать «задыхаться».

min_connections: минимальное количество соединений, которые MAS держит открытыми постоянно. Если 0: MAS не держит соединения открытыми без необходимости, первое соединение создаётся при первом запросе, экономит ресурсы, если MAS редко используется.

connect_timeout: сколько секунд MAS ждёт установления соединения с PostgreSQL. Если PostgreSQL: не отвечает, перегружен, недоступен, то MAS будет ждать до 30 секунд, затем выдаст ошибку. Если поставить слишком мало (например, 1–3 сек) — возможны ложные ошибки при старте PostgreSQL.

idle_timeout: через сколько секунд простаивающее соединение закрывается. Если соединение не используется установленное время — MAS его закрывает. Это полезно: чтобы не держать лишние соединения, чтобы PostgreSQL не тратил ресурсы, чтобы пул «самоочищался». Если нагрузка постоянная — idle‑соединений почти не будет.

max_lifetime: максимальное время жизни соединения. После установленного времени соединение будет закрыто и создано заново. Зачем это нужно: предотвращает зависание старых соединений, помогает при ротации PostgreSQL, снижает риск утечек памяти, улучшает стабильность пула. Я оставил значения этих полей по умолчанию. Вы можете поиграться с ними в разумных пределах в зависимости от мощности вашего сервера и задач.

Раздел email управляет тем, как MAS отправляет письма пользователям. MAS использует e‑mail для: подтверждения регистрации (email verification), восстановления доступа (если включено), подтверждения привязки e‑mail, уведомлений MAS UI. Если e‑mail‑функции включены, MAS обязан иметь корректно настроенный email‑раздел. Если e‑mail не используется — можно оставить transport: blackhole.

from: адрес отправителя, который увидит пользователь. Формат: «Имя отправителя» email@domain Например, «„Matrix Auth“ Matrix_Auth@servername.com», где «Matrix Auth» — имя отправителя, servername.com — имя домена. Используется в: письмах подтверждения, письмах восстановления, любых e‑mail уведомлениях MAS. MAS не проверяет существование адреса — это чисто отображение.

reply_to: адрес, на который будут отправляться ответы пользователя. Обычно совпадает с from или no‑reply@domain, если не хотите получать ответы.

transport: определяет, как MAS отправляет письма. Варианты: blackhole, smtp, sendmail. Если установлен blackhole — MAS не отправляет письма вообще, используется по умолчанию. smtp — MAS отправляет письма через SMTP‑сервер.

sendmail: MAS вызывает локальную программу /usr/sbin/sendmail.

Для smtp доступны следующие параметры:

mode — режим шифрования SMTP, имеет варианты:

  • plain — без TLS

  • tls — SMTPS (465 порт)

  • starttls — STARTTLS (587 порт)

hostname: адрес SMTP‑сервера. Примеры: smtp.gmail.com, smtp.yandex.ru

port: порт SMTP. 465 — TLS. 587 — STARTTLS

username: имя пользователя SMTP. Обычно это: полный e‑mail или логин почтового ящика.

password: пароль SMTP‑аккаунта. MAS использует его для аутентификации на SMTP‑сервере.

Для transport: sendmail, используется command: /путь/к/бинарнику sendmail. Обычно /usr/sbin/sendmail MAS передаёт письмо в STDIN этой программе. Я не использую почту в MAS, поэтому в моем конфиге установлено значение transport: blackhole.

Раздел secrets это хранилище всех криптографических ключей MAS, необходимых для: подписи OAuth2/OIDC токенов, шифрования сессий, защиты cookie, генерации device‑codes, защиты CSRF, внутренней криптографии MAS.

encryption: ключ шифрования, который MAS использует для шифрования файлов cookie и полей базы данных. Он генерируется автоматически при генерации файла config.yaml Формат: 32‑байтный ключ в формате hex. Его также можно задать через файл, если добавить поле secrets.encryption_file и указать путь к файлу. Если он задан через файл, то секрет шифрования считывается только при запуске приложения. Секрет не обновляется при изменении содержимого файла. Не меняйте секрет шифрования после первоначального запуска! Последующее изменение секрета шифрования приведет к потере всей зашифрованной информации в базе данных.

keys: ключи подписи. Используются для:

  • подписи идентификаторов токенов (которые возвращаются в Token Endpoint по адресу /oauth2/token).

  • подписи ответа UserInfo Endpoint по адресу /oauth2/userinfo, если клиент запрашивает подписанный ответ.

  • подписание JWT для аутентификации вышестоящему поставщику OAuth, когда настроен метод аутентификации клиента private_key_jwt.

Как минимум, ключ RSA должен быть настроен таким образом, чтобы соответствовать спецификации OpenID Connect Core, которая определяет алгоритм RS256 как обязательный для реализации серверами по соображениям совместимости. Ключи могут быть указаны в виде пути к каталогу через secrets.keys_dir или, альтернативно, в виде встроенного списка настроек через secrets.keys.

secrets.keys_dir: путь к каталогу, содержащему файлы ключей подписи MAS. Поддерживаются только ключи, для которых не требуется пароль.

secrets.keys: каждая запись в списке соответствует одному ключу подписи, используемому MAS. Ключ может быть либо задан встроенно (с помощью свойства key), либо загружен из файла (со свойством key_file). Идентификатор ключа JWK автоматически выводится из каждого ключа. Чтобы переопределить это значение по умолчанию, установите для kid пользовательское значение. Дочерним значением может быть любое строковое значение с учетом регистра, если оно уникально для этого списка; дочернее значение ключа должно быть стабильным при перезапуске. Для ключей, закодированных в PKCS#8, для расшифровки ключа можно использовать свойства password или password_file. Если ключи меняются — все токены становятся недействительными. keys также генерируются автоматически. Генерируется один RSA ключ и три ключа ECDSA (P-256, P-384, secp256k1).

Сервис может использовать несколько типов ключей для подписи. Поддерживаются следующие типы ключей:

  • RSA

  • ECDSA с кривой P-256 (prime256v1)

  • ECDSA с кривой P-384 (secp384r1)

  • ECDSA с кривой K-256 (secp256k1)

Поддерживаются следующие форматы ключей:

  • PKCS#1 PEM or DER‑encoded RSA закрытый ключ

  • PKCS#8 PEM or DER‑encoded RSA or ECDSA закрытый ключ, зашифрованный или незашифрованный

  • SEC1 PEM or DER‑encoded ECDSA закрытый ключ

Раздел passwords отвечает за локальную аутентификацию пользователей по паролю и включает три ключевые функции: включение/отключение входа по паролю, выбор алгоритмов хеширования, требования к сложности пароля.

enabled: включает или отключает возможность входа по паролю. Если enabled: false — MAS не позволит пользователям логиниться по паролю, даже если пароль есть в базе, и пользователи смогут входить в систему только с помощью вышестоящих поставщиков OIDC.

schemes: список алгоритмов хеширования паролей. MAS поддерживает: Argon2id (рекомендуемый), bcrypt, PBKDF2-SHA256. MAS использует алгоритм с максимальным номером версии для хеширования новых паролей, а старые версии продолжает принимать (механизм миграции хешей). Изменяйте это только в том случае, если вы знаете, что делаете.

version: номер поколения схемы хеширования, который MAS использует для выбора актуального алгоритма и миграции старых хешей на новые.

minimum_complexity: минимальная сложность пароля по шкале zxcvbn (0–4). Это не классические требования вроде «минимум 8 символов», а оценка устойчивости пароля.

Раздел matrix отвечает за интеграцию и взаимодействие MAS с сервером Synapse. Служба аутентификации должна иметь возможность вызывать Synapse admin API для предоставления доступа пользователям через общий секрет, а Synapse должна иметь возможность вызывать службу для проверки токенов доступа с использованием конечной точки самоанализа токенов OAuth 2.0. Содержит следующие поля:

kind: тип домашнего сервера для подключения, в настоящее время поддерживается только synapse.

homeserver: должен соответствовать имени сервера в файле конфигурации Synapse.

secret: общий секрет, который служба будет использовать для вызова MAS API homeserver. Он должен совпадать с полем secret в разделе matrix_authentication_service в конфигурационном файле Synapse. Генерируется автоматически.

endpoint: URL, по которому из сервиса доступен домашний сервер.

Раздел policy предоставляет механизм для централизованного управления правилами безопасности и соответствия в MAS. Он позволяет:

  • Внедрять сложную логику через программируемые WASM‑модули.

  • Гибко настраивать правила для ключевых операций (регистрация, выдача прав, изменение данных) через точки входа.

  • Применять детальные статические правила для имен пользователей, email‑адресов, IP и User‑Agent с помощью различных типов проверок (точные, по шаблону, регулярные выражения).

  • Контролировать административный доступ для конкретных пользователей и клиентов.

В основе этой системы лежат WebAssembly (WASM) модули, которые выполняют пользовательскую логику проверки. Конфигурация определяет, какой WASM‑модуль использовать и какие точки входа в нем вызывать.

Для работы домашнего сервера (homeserver) нужны несколько секций из этого раздела:

wasm_module: путь к модулю WASM. В моей конфигурации путь /opt/mas/share/policy.wasm

data: содержит статические правила и списки, которые передаются в WASM‑модуль для принятия решений. Это основной способ настройки политик без изменения кода модуля.

admin_users: список идентификаторов пользователей, которым разрешено запрашивать права администратора. Понадобится для входа и управления в панели Ketesa.

admin_clients: список client_id OAuth клиентов, которым разрешено запрашивать административный доступ через грант client_credentials. В моем случае это поле не нужно.

Раздел rate_limiting предназначен для защиты сервиса от злоупотреблений и автоматических атак путем ограничения частоты выполнения определенных пользовательских действий. Он помогает предотвратить такие угрозы, как брутфорс‑атаки (подбор паролей), спам (например, множественные запросы на восстановление пароля) и массовую регистрацию аккаунтов. Каждый лимитер работает по модели «токенов ведра» (token bucket) и настраивается с помощью двух параметров:

burst: Максимальное количество действий, которое разрешено выполнить «за один раз» (начальная емкость ведра). Это позволяет обработать кратковременную вспышку активности.

per_second: Скорость, с которой «ведро» пополняется новыми токенами (количество разрешенных действий в секунду). Определяет устойчивую среднюю частоту запросов.

Подраздел account_recovery ограничивает попытки восстановления пароля. Это критично для защиты от спама на email‑ящики пользователей. Содержит параметры:

per_ip: лимит, основанный на IP‑адресе отправителя. Защищает от массовых автоматических запросов с одного хоста.

per_address: лимит, основанный на email‑адресе, на который отправляется восстановление. Предотвращает спам‑атаки на конкретный почтовый ящик.

Я не использую почту при регистрации пользователей поэтому этой секции нет в разделе rate_limiting.

Подраздел login ограничивает количество разрешенных попыток входа в систему. Эти ограничения также применяются к проверке пароля, когда пользователь пытается изменить свой собственный пароль. Содержит параметры:

per_ip: защита от брутфорса с одного IP‑адреса.

per_account: лимит, основанный на конкретном аккаунте, в который пытаются войти. Защищает от распределенных брутфорс‑атак, когда злоумышленники используют много разных IP. Должно быть установлено на достаточно высоком уровне, чтобы предотвратить случайную блокировку чьей‑либо учетной записи.

Подраздел registration ограничивает попытки создания новых аккаунтов, основанные на IP‑адресе. Помогает бороться со спам‑регистрациями и массовым созданием ботов. В моем конфиге разрешено 2 попытки регистрации подряд 1 регистрация в 20 минут.

Цифры в поле per_second переводятся в минуты по формуле 1/(per_second*60). Например, 1/(0,000860) = 20,83 мин или в обратную сторону per_second = 1/(мин*60)

Раздел templates предназначен для кастомизации и локализации интерфейса. Он позволяет службе аутентификации загружать пользовательские шаблоны страниц, файлы перевода и манифесты ресурсов вместо использования встроенных по умолчанию.Этот раздел необходим для брендирования страниц входа (login), регистрации, сброса пароля и писем, которые MAS отправляет пользователям. Этот раздел необходимо указать в конфиг. файле, потому что, как я понял, он необходим для работы MAS, так как в папке /opt/mas/share/templates хранятся также шаблоны используемые MAS по умолчанию. Содержит поля:

path: указывает на директорию, где хранятся пользовательские шаблоны страниц. MAS использует движок шаблонов (обычно на базе Tera/Jinja‑подобного синтаксиса в экосистеме Rust) для динамической генерации HTML‑страниц, отображаемых пользователю. Путь указывается относительно текущей рабочей директории, а не относительно файла конфигурации. Это значит, что если вы запускаете MAS из /opt/mas/, то путь будет искаться оттуда.

assets_manifest: путь к файлу manifest.json. Этот файл необходим для правильного связывания скомпилированных фронтенд‑ресурсов (JS‑скриптов, CSS‑стилей, картинок), если вы пересобираете клиентскую часть MAS под свои нужды. Он сопоставляет исходные названия файлов с их версиями, содержащими хэш, что помогает эффективно управлять кэшированием в браузере.

translations_path: путь к директории с файлами локализации, которая позволяет перевести интерфейс MAS на нужные языки или изменить стандартные текстовые формулировки. По умолчанию (если параметр не задан) MAS ищет переводы в стандартных путях в зависимости от способа установки.

Раздел account отвечает за управление учетными записями пользователей. Он определяет, какие действия пользователи могут выполнять самостоятельно со своим профилем через интерфейс аутентификации. По сути, этот блок задает политики безопасности и права доступа для пользователей. Содержит поля:

email_change_allowed: разрешено ли пользователям самостоятельно менять свой email.

displayname_change_allowed: разрешено ли пользователям менять свое отображаемое имя (Display Name). ВАЖНО: Эта настройка должна быть синхронизирована с аналогичной политикой в конфигурации Synapse.

email_change_allowed и displayname_change_allowed: контролируют базовые данные профиля. Если вы строите корпоративную среду, где данные пользователей жестко синхронизируются из внешней системы (например, LDAP/Active Directory или корпоративного Keycloak), эти параметры имеет смысл выставить в false, чтобы пользователи не могли вносить путаницу и менять свои реальные имена и адреса внутри Matrix.

password_registration_enabled: разрешена ли самостоятельная регистрация аккаунтов по паролю. Не имеет эффекта, если вход по паролям полностью отключен. Отвечает за так называемую «открытую регистрацию». Если выставить true, любой посетитель страницы авторизации сможет создать себе локальный аккаунт в вашей Matrix‑сети, задав логин и пароль. По умолчанию опция отключена (false), чтобы предотвратить бесконтрольную регистрацию ботов и посторонних лиц.

password_change_allowed: разрешено ли пользователям самостоятельно менять свой текущий пароль. Не имеет эффекта, если вход по паролям полностью отключен. Позволяет пользователю зайти в настройки своего аккаунта в MAS и обновить пароль. Если учетные записи управляются централизованно (через Upstream OIDC), локальные пароли обычно вообще не используются, и эту опцию можно не трогать.

password_recovery_enabled: включено ли восстановление пароля через электронную почту. Не имеет эффекта, если вход по паролям полностью отключен. Включает привычную кнопку «Забыл пароль» на форме входа. Чтобы эта функция реально работала, в MAS обязательно должен быть настроен и работать почтовый сервер (раздел matrix или email в зависимости от версии MAS), иначе сервис просто не сможет отправить пользователю ссылку для сброса.

account_deactivation_allowed: этот параметр определяет, может ли пользователь самостоятельно удалить (деактивировать) свою учетную запись через интерфейс самообслуживания MAS.

login_with_email_allowed: вход по Email. Разрешает или запрещает пользователям использовать свой адрес электронной почты вместо Matrix ID (локальной части юзернейма) в поле «Логин» при авторизации по паролю. Важно: Опция работает только в том случае, если в MAS включен вход по паролям.

registration_token_required: включает запрос токенов при регистрации. Регулирует режим регистрации по инвайтам (пригласительным токенам). Если включено, то при регистрации по паролю пользователь обязан предоставить валидный регистрационный токен. Это отличный «гибридный» режим для закрытых или приватных серверов. Вместо того чтобы полностью открывать регистрацию для всех желающих (password_registration_enabled: true) или полностью её закрывать, вы можете включить registration_token_required: true. В таком режиме зарегистрироваться на сервере смогут только те люди, которым администратор (или другие пользователи, если у них есть права) сгенерировал и выдал специальный пригласительный токен (ссылку‑приглашение). Для всех остальных регистрация будет закрыта. Важно: Параметр не имеет силы, если открытая регистрация по паролям (password_registration_enabled) отключена в принципе. В моем конфиге разрешено регистрироваться с паролем только по пригласительному токену.

Раздел oauth отвечает за управление специфическим сценарием авторизации, который называется Device Authorization Grant (OAuth 2.0 Device Flow, RFC 8628). В Matrix этот механизм используется для удобного входа в аккаунт на мобильных устройствах. Вместо ввода логина/пароля на самом устройстве, оно показывает вам QR‑код, который вы сканируете со смартфона, чтобы подтвердить вход. Содержит поля:

device_code_grant_enabled: это поле включает или полностью отключает поддержку авторизации устройств по коду. Если этот параметр отключен, конечная точка авторизации устройства будет отклонять запросы, метаданные обнаружения не будут указывать конечную точку авторизации устройства, а динамические регистрации клиентов, запрашивающие тип разрешения urn:ietf:params:oauth:grant‑type:device_code, будут отклонены.

device_code_user_code_auto_fill_enabled: управляет тем, будет ли MAS генерировать «умные» ссылки и QR‑коды для автоматического заполнения проверочного кода. Указывает ли конечная точка авторизации устройства на «verification_uri_complete», который автоматически заполняет код пользователя на странице «/link». По умолчанию используется значение true. Если этот параметр отключен, в ответе на авторизацию устройства не будет указано «verification_uri_complete», а маршрут «/link» будет игнорировать любой параметр запроса «code», заставляя пользователей вводить свой пользовательский код вручную.

Значение обоих полей по умолчанию true, но я добавил этот раздел в конфиг. файл, чтобы можно было отключать при необходимости авторизацию по QR коду.

В MAS есть встроенная команда проверки конфигурации. После всех настроек и изменений проверим конфиг. файл — нет ли нарушений в разметке файла, проверим соответствие параметров официальной схеме MAS, например, если случайно добавили несуществующее поле. Проверим обязательные параметры, например, если включен определенный тип авторизации, но для него не заполнены ключи шифрования, утилита выдаст предупреждение.

/opt/mas/mas-cli config check --config=/etc/mas/config.yaml

Если все хорошо, то результат должен быть такой:

.. INFO mas_cli::commands::config:91 Configuration file looks good

Создадим конфиг. файл для systemd‑unit. Открываем новый файл:

nano /etc/systemd/system/mas.service

и заполняем его таким образом:

mas.service
[Unit]Description=Matrix Authentication ServiceAfter=network.target network-online.targetWants=network-online.target[Service]User=masGroup=masWorkingDirectory=/opt/masExecStart=/opt/mas/mas-cli server -c /etc/mas/config.yamlRestart=on-failureRestartSec=5# Базовые меры безопасностиNoNewPrivileges=truePrivateTmp=trueProtectSystem=fullProtectHome=trueProtectKernelTunables=trueProtectKernelModules=trueProtectControlGroups=trueCapabilityBoundingSet=[Install]WantedBy=multi-user.target

Выдаем права на этот файл:

chown root:root /etc/systemd/system/mas.service

chmod 644 /etc/systemd/system/mas.service

Проверяем права:

ls -l /etc/systemd/system/mas.service

Должно быть:

‑rw‑r-‑r-‑ 1 root root … /etc/systemd/system/mas.service

Далее активируем службу и включаем автозагрузку:

systemctl daemon-reload

systemctl start mas

systemctl enable mas

Проверяем статус службы:

systemctl status mas

Если служба запустилась без ошибок, то терминал должен выдать:

Проверим также как MAS взаимодействует с endpoints и Synapse:

/opt/mas/mas-cli doctor --config=/etc/mas/config.yaml

Если конфигурация верная, то должно быть:

На этом установка, настройка и запуск MAS на сервере завершены.

Установка LiveKit

Последний стабильный релиз устанавливаем с github.

Скачиваем архив в папку /tmp (или любую удобную для вас папку):

wget -P /tmp https://github.com/livekit/livekit/releases/download/v1.13.3/livekit_1.13.3_linux_amd64.tar.gz

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

useradd --system --user-group --home /opt/livekit --shell /usr/sbin/nologin livekit_user

Создаем необходимые папки на сервере для LiveKit.

Для исполнительного файла:

mkdir -p /opt/livekit

Для конфигурационного файла:

mkdir -p /etc/livekit

Для данных:

mkdir -p /var/lib/livekit

Выдаем права этим папкам:

chown -R root:root /opt/livekit

chmod 755 /opt/livekit

chown -R root:livekit_user /etc/livekit

chmod 750 /etc/livekit

chown -R livekit_user:livekit_user /var/lib/livekit

chmod 750 /var/lib/livekit

Переходим в папку /tmp:

cd /tmp

Разархивируем архив livekit_1.13.3_linux_amd64.tar.gz в папку /opt/livekit:

tar -xvf -C livekit_1.13.3_linux_amd64.tar.gz /opt/livekit

У вас скорее всего название архива будет отличаться, поэтому вводите здесь название того архива, который вы скачали в папку /tmp (или в ту папку в которую скачали).

Выдаем права этому исполнительному файлу:

chown root:livekit_user /opt/livekit/livekit-server

chmod 750 /opt/livekit/livekit-server

Проверяем права:

ls -l /opt/livekit/livekit-server

Должно быть:

‑rwxr‑x-‑ 1 root livekit‑user … /opt/livekit/livekit‑server

Создаем файл конфигурации LiveKit:

nano /etc/livekit/config.yaml

Копируем в него такой текст:

config.yaml
port: 7880rtc:  port_range_start: 50000  port_range_end: 51000  tcp_port: 7881  use_external_ip: false  node_ip: xx.xxx.x.xxkeys:  devkey: ваш_секретroom:  auto_create: falseturn:  enabled: true  udp_port: 3478  tls_port: 5349  external_tls: true  domain: servername

В этом файле в поле node_ip вписываете IP своего сервера. servername заменяете на имя своего домена. В поле devkey вставляете свой секрет

Это не полная конфигурация LiveKit, но для работы на моем сервере этого будет достаточно. Если у вас есть желание, то можете ознакомиться или скачать полный конфиг. файл.

Описание параметров конфиг. файла LiveKit

port: это главный порт сервера. Через него LiveKit принимает управляющие сигналы (сигналинг), к нему же подключаются клиенты (например, Element X) для инициализации созвона. Этот порт обычно «прячут» за обратным прокси (Nginx, Traefik) для настройки SSL/TLS.

rtc: этот блок отвечает за непосредственную передачу аудио‑ и видеопотоков между участниками.

port_range_start и port_range_end: диапазон UDP‑портов, которые сервер будет динамически выделять для передачи медиаданных. Каждый новый поток (голос или видео) от участника занимает порт из этого диапазона. Используется диапазон 50 000 — 60000, но можно установить свой диапазон в этом пределе. Я установил значение 50 000 — 51000. Важно! Эти порты должны быть обязательно открыты в фаерволе (UFW/iptables) на сервере для входящего трафика по протоколу UDP. Я далее покажу как это сделать.

tcp_port: порт для передачи медиаданных по протоколу TCP. Он используется как резервный вариант (WebRTC over TCP), если у клиента жесткий корпоративный фаервол, который полностью блокирует исходящий UDP‑трафик.

use_external_ip: если установлено false, LiveKit будет автоматически пытаться определить свой публичный IP‑адрес через внешние STUN‑серверы. На арендованных VPS с прямым выделенным IP‑адресом эту опцию обычно оставляют в false или настраивают node_ip.

node_ip: сюда вписывается реальный публичный IPv4-адрес вашего VPS. Это указывает LiveKit, какой именно IP‑адрес нужно отправлять клиентам в качестве ICE‑кандидата, чтобы они знали, куда слать свои видео‑ и аудиопакеты.

keys: блок безопасности и авторизации.

devkey: это имя (идентификатор) ключа. Содержит строку‑пароль, которая используется для генерации и валидации JWT‑токенов. Когда связка Matrix Synapse + lk‑jwt‑service создает токен доступа для пользователя, входящего в комнату, он подписывает его этим секретом. LiveKit проверяет подпись и решает, пускать пользователя или нет.

room: блок управления комнатами.

auto_create: определяет, может ли клиент создать комнату на LiveKit‑сервере «на лету», просто запросив подключение к несуществующему имени комнаты. Этот параметр выставляется в false, так как созданием комнат должен строго «рулить» lk‑jwt‑service, а не клиенты сами по себе.

turn: встроенный TURN‑сервер. TURN‑сервер необходим, если два участника созвона находятся за строгими NAT и не могут отправлять медиапакеты напрямую на порты 50000–60000. В этом случае LiveKit начинает ретранслировать весь трафик через себя.

enabled: включает встроенный в LiveKit TURN/STUN сервер. Это избавляет от необходимости устанавливать и настраивать отдельно Сoturn.

udp_port: 3478 стандартный порт для работы TURN/STUN по протоколу UDP. Важно! Он должен быть открыт в фаерволе.

tls_port: 5349 стандартный защищенный порт для TURN по протоколу TLS (TURNS). Трафик внутри него маскируется под обычный HTTPS, что позволяет обходить самые строгие корпоративные блокировки. Важно! Он должен быть открыть в фаерволе.

external_tls: значение true указывает, что шифрованием TLS занимается внешний прокси‑сервер (например, Nginx снимает SSL‑флаг и передает трафик на LiveKit), либо сам LiveKit должен ожидать, что сертификаты настроены на уровне системы.

domain: имя вашего домена. Этот домен используется для генерации валидных SSL‑сертификатов, чтобы клиенты могли устанавливать безопасное соединение с TURN‑сервером по протоколу TURNS.

Создаем конфиг. файл для systemd‑unit:

nano /etc/systemd/system/livekit.service

Заполняем его таким образом:

livekit.service
[Unit]Description=LiveKit ServerAfter=network.targetStartLimitIntervalSec=0[Service]Type=simpleUser=livekit_userGroup=livekit_userWorkingDirectory=/var/lib/livekitExecStart=/opt/livekit/livekit-server --config /etc/livekit/config.yamlRestart=alwaysRestartSec=5LimitNOFILE=65535[Install]WantedBy=multi-user.target

Задаем права на этот файл:

chown root:root /etc/systemd/system/livekit.service

chmod 644 /etc/systemd/system/livekit.service

Проверяем права:

ls -l /etc/systemd/system/livekit.service

Должно быть:

‑rw‑r-‑r-‑ 1 root root … /etc/systemd/system/livekit.service

Перезагружаем systemd и запускаем сервис:

systemctl daemon-reload

systemctl start livekit

Включаем автозагрузку:

systemctl enable livekit

Проверяем статус:

systemctl status livekit

Должно быть:

Если так же, то все отлично, вы все сделали правильно. Настройка LiveKit завершена.

Установка MatrixRTC Authorization Service (lk‑jwt‑service)

Последний стабильный релиз устанавливаем с github. Ссылка на страницу проекта:

Скачиваем архив в папку /tmp (или любую удобную для вас папку):

wget -P /tmp https://github.com/element-hq/lk-jwt-service/releases/download/v0.5.0/lk-jwt-service_linux_amd64

У вас, скорее всего, будет другая версия lk‑jwt‑service, поэтому вместо 0.5.0 пишите актуальную на данный момент версию.

Создаём на сервере в системе пользователя lk‑jwt_user, чтобы дать ему права на использование каталогов и файлов:

useradd --system --user-group --home /opt/lk-jwt-service --shell /usr/sbin/nologin lk-jwt_user

Создаем необходимые папки на сервере для lk‑jwt‑service.

Для размещения исполнительного файла:

mkdir -p /opt/lk-jwt-service

Для конфигурационного файла:

mkdir -p /etc/lk-jwt-service

Выдаем права:

chown -R root:root /opt/lk-jwt-service

chmod 755 /opt/lk-jwt-service

chown root:lk-jwt_user /etc/lk-jwt-service

chmod 750 /etc/lk-jwt-service

Перемещаем и переименовываем исполнительный файл lk‑jwt‑service_linux_amd64 в папку /opt/lk‑jwt‑service:

mv /tmp/lk-jwt-service_linux_amd64 /opt/lk-jwt-service/lk-jwt-service

Теперь файл для удобства будет называться lk‑jwt‑service одноименно с папкой в которой он будет находиться.

Выдаем ему права:

chown root:lk-jwt_user /opt/lk-jwt-service/lk-jwt-service

chmod 750 /opt/lk-jwt-service/lk-jwt-service

Проверяем права:

ls -l /opt/lk-jwt-service/lk-jwt-service

Должно быть:

‑rwxr‑x-‑ 1 root lk‑jwt_user … /opt/lk‑jwt‑service/lk‑jwt‑service

Создаем файл для systemd‑unit:

nano /etc/systemd/system/lk-jwt-service.service

Копируем в него такой текст:

lk‑jwt‑service.service
[Unit]Description=LiveKit JWT ServiceAfter=network.target livekit.serviceRequires=livekit.service[Service]Type=simpleUser=lk-jwt_userGroup=lk-jwt_userRestart=alwaysRestartSec=5WorkingDirectory=/opt/lk-jwt-serviceEnvironment="LIVEKIT_URL=wss://servername/livekit/sfu"Environment="LIVEKIT_KEY=devkey"Environment="LIVEKIT_SECRET=ваш_секрет"Environment="LIVEKIT_JWT_BIND=localhost:8084"Environment="LIVEKIT_FULL_ACCESS_HOMESERVERS=servername"ExecStart=/opt/lk-jwt-service/lk-jwt-service[Install]WantedBy=multi-user.target

servername замените на имя вашего домена. В строках:
Environment=«LIVEKIT_KEY=devkey»
Environment=«LIVEKIT_SECRET=ваш_секрет»
devkey и ваш_секрет это параметры из конфиг. файла LiveKit, который мы создавали выше.

Описание параметров конфигурации lk‑jwt‑service

LIVEKIT_URL — это WebSocket‑адрес вашего LiveKit‑сервера. Сервис lk‑jwt‑service использует этот адрес, чтобы подключаться к LiveKit и создавать комнаты для «полноправных» пользователей.

LIVEKIT_KEY — API‑ключ для доступа к вашему LiveKit‑серверу. Это логин (идентификатор) для авторизации на LiveKit.

LIVEKIT_SECRET — API‑секрет (пароль) для доступа к LiveKit. Это пароль к ключу из пункта выше. Используется для подписи JWT‑токенов.

LIVEKIT_JWT_BIND — это адрес и порт, на котором сервис будет «слушать» запросы от клиентов.

LIVEKIT_FULL_ACCESS_HOMESERVERS — список домашних серверов (по именам), пользователи которых будут иметь полный доступ (могут создавать новые комнаты в LiveKit).

Задаем права на этот файл:

chown root:root /etc/systemd/system/lk-jwt-service.service

chmod 644 /etc/systemd/system/lk-jwt-service.service

Проверяем права:

ls -l /etc/systemd/system/lk-jwt-service.service

Должно быть:

‑rw‑r-‑r-‑ 1 root root … /etc/systemd/system/livekit.service

Перезагружаем systemd и запускаем сервис:

systemctl daemon-reload

systemctl start lk-jwt-service

Включаем автозагрузку:

systemctl enable lk-jwt-service

Проверяем статус:

systemctl status lk-jwt-service

Должно быть:

Если у вас так же, то всё хорошо, значит вы сделали всё правильно. На этом настройка lk‑jwt‑service завершена.

Открываем порты для звонков

Нам нужно открыть порты на сервере чтобы работали звонки через LiveKit.

Проверяем какие порты у нас открыты:

ufw status numbered

Если у вас установлена панель 3x‑ui на сервер, то вывод должен быть такой (если порты панели и сервера ssh не изменялись):

В этом выводе видно, что открыт порт 22 для протокола SSH, порт 443 для xray и порт 2053 для самой панели 3x‑ui. Порты 22 и 2053 стандартные и у вас они могут быть изменены на другие, а также могут быть открыты еще какие-то порты.

Нам нужно открыть порты 3478 и 50 000 — 51000:

ufw allow 3478/tcp

ufw allow 3478/udp

ufw allow 50000:51000/udp

Порт 5349 указан в моем конфиг. файле LiveKit, но в фаерволе я не стал открывать его. Открытого порта 3478 мне будет достаточно для звонков.

Перезапускаем фаервол:

ufw reload

Еще раз проверяем список открытых портов:

ufw status numbered

Должно быть:

Если у вас так же, то все хорошо, настройка фаервола для работы звонков завершена.

Установка Element‑web

Установим на сервер Element‑web, чтобы можно было пользоваться возможностями matrix через браузер. Десктопный клиент Element использовать на линукс не рекомендую, по причине его глючности (десктопная версия основана на Electron).

Последний стабильный релиз устанавливаем с github.

Скачиваем архив в папку /tmp (или любую удобную для вас папку):

wget -P /tmp https://github.com/element-hq/element-web/releases/download/v1.12.22/element-v1.12.22.tar.gz

Создаем папку для хранения «статики»:

mkdir -p /var/www/html/element-web

Распаковываем архив element‑v1.12.22.tar.gz в папку /war/www/html/element‑web:

tar -xf element-v1.12.22.tar.gz --strip-components=1 -C /var/www/html/element-web

Открываем файл config.sample.json:

nano /war/www/html/element-web/config.sample.json

Удаляем весь текст нажав Ctrl + K и вставляем вот такой:

config.json
{    "default_server_config": {        "m.homeserver": {            "base_url": "https://servername"        }    },    "disable_custom_urls": false,    "disable_guests": false,    "disable_login_language_selector": false,    "disable_3pid_login": false,    "force_verification": false,    "brand": "Element",    "default_widget_container_height": 280,    "default_country_code": "RU",    "show_labs_settings": false,    "features": {        "feature_video_rooms": true,        "feature_group_calls": true,        "feature_element_call_video_rooms": true    },    "element_call": {        "url": "https://call.element.io",        "use_exclusively": true    },    "default_federate": true,    "default_theme": "dark",    "room_directory": {        "servers": ["matrix.org"]    },    "enable_presence_by_hs_url": {        "https://matrix.org": false,        "https://matrix-client.matrix.org": false    },    "setting_defaults": {        "breadcrumbs": true    },    "element_call": {        "url": "https://call.element.io",        "brand": "Element Call"    },    "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"}

servername измените на имя своего домена.

Жмете ctrl + X, потом Y и изменяете имя файла на config.json, сохраняете файл.

Задаем права на папку:

chown -R root:www-data /var/www/html/element-web

chmod 750 /var/www/html/element-web

Переходим в папку /element‑web:

cd /var/www/html/element-web

Задаем права на вложенные файлы и папки:

find . -type d -exec chmod 750 {} +

find . -type f -exec chmod 640 {} +

На этом установка и настройка Element‑web завершена. Открыть страницу входа вы можете по адресу: https://servername/element‑web/#/welcome

Не забудьте заменить servername на имя вашего домена.

Установка панели управления Ketesa

Панель представляет собой форк оригинального проекта и предлагает полный редизайн интерфейса и имеет полноценную поддержку MAS.

С помощью панели можно осуществлять:

  1. Управление пользователями и сессиями (через MAS):

  • Токены регистрации: Прямо из интерфейса Ketesa можно генерировать регистрационные токены (Registration Tokens) для создания новых аккаунтов (без MAS эта вкладка в панели будет недоступна).

  • Аудит и отзыв сессий: Вы видите все активные сессии пользователя: сессии в браузерах, OAuth2-сессии (Element X), личные токены (Access Tokens) и «совместимые» сессии (старый Element Desktop). Любую подозрительную сессию можно сбросить одной кнопкой.

  • Управление OAuth‑связями: Если пользователи логинятся через внешние сервисы (например, GitHub/Google), Ketesa показывает связанные апстрим‑аккаунты.

  • Управление почтой: Просмотр и редактирование привязанных к аккаунтам Email‑адресов.

  • Заморозка и деактивация: Блокировка учетных записей нарушителей без удаления их истории.

2. Управление комнатами (через Synapse API):

  • Полнотекстовый поиск: Поиск по всем комнатам на сервере (включая приватные)

  • Модерация комнат: Возможность принудительно зайти в любую комнату (Join), назначить себя или другого пользователя администратором, либо полностью закрыть/удалить комнату (с отправкой заглушки заблокированным участникам).

  • Очистка и «захлопывание»: Удаление комнат, в которых не осталось локальных пользователей, для освобождения места в базе данных.

3. Очистка медиафайлов и федерация:

  • Находить пользователей и комнаты, которые потребляют больше всего дискового пространства под картинки/видео.

  • Удалять старый медиа‑кэш или конкретные файлы по их ID.

  • Просматривать список федеративных серверов, с которыми ваш домашний сервер обменивается данными, и блокировать «токсичные» или спамерские домены.

Есть два варианта установки панели по размещению рабочей папки: root path и subpath. Root path будет выглядеть https://admin.servername.com, а subpath будет выглядеть https://servername.com/admin. Если выбрать root path, то у вас должен быть создан поддомен и получены на него SSL‑сертификаты. Я не захотел создавать поддомен, поэтому выбрал вариант с subpath. Вы можете сделать по первому варианту.

Последний стабильный релиз устанавливаем с github. Ссылка на страницу проекта:

Скачиваем архив в папку /tmp (или любую удобную для вас папку):

wget -P /tmp https://github.com/etkecc/ketesa/releases/download/v1.3.0/ketesa-subpath-admin.tar.gz

Вместо v1.3.0 пишите актуальную на данный момент версию

Создаем папку admin:

mkdir -p /var/www/html/admin

Распаковываем архив в /var/www/html/admin:

tar -xf ketesa-subpath-admin.tar.gz --strip-components=1 -C /var/www/html/admin

Задаем права на папку:

chown -R root:www-data /var/www/html/admin

chmod 750 /var/www/html/admin

Заходим в папку /admin:

cd /var/www/html/admin

Задаем права на всю «статику»:

find . -type f -exec chmod 640 {} +

find . -type d -exec chmod 750 {} +

Права 640 означают, что root может править файлы, Nginx может их читать, а посторонние процессы даже не увидят их содержимое.

Настройка панели Ketesa на этом завершена. Зайти в панель вы можете по адресу: https://servername/admin/#/login

Главный недостаток tarball способа установки это необходимость периодически, например, раз в месяц, вручную скачивать архивы и обновлять бинарные файлы и папки со статикой для Element‑web и Ketesa. Конечно же если вы хотите чтобы на вашем сервере всегда были свежие версии этих файлов.

При обновлении бинарных файлов MAS, LiveKit, lk‑jwt‑service нужно сделать последовательно несколько шагов.

1.Остановить службу:

Для MAS:

systemctl stop mas

Для LiveKit:

systemctl stop livekit

Для lk‑jwt‑service:

systemctl stop lk-jwt-service

2.Удаление файла:

Для MAS:

rm /opt/mas/mas-cli

Для LiveKit:

rm /opt/livekit/livekit-server

Для lk‑jwt‑service:

rm /opt/lk-jwt-service/lk-jwt-service

Далее скачиваете свежий архив, извлекаете содержимое в папки /opt/…, то есть каждый бинарник в свою папку. При обновлении MAS, LiveKit, lk‑jwt‑service выдаете права только бинарным файлам (на папки выдавать не нужно). Запускаете службы командой:

systemctl start имя_службы

Проверьте статус

Версии файлов можно посмотреть так:

Для MAS:

/opt/mas/mas-cli --version

Для LiveKit:

/opt/livekit/livekit-server --version

Для обновления Element‑web и Ketesa нужно удалить все вложенные папки и файлы в папках /var/www/html/element‑web и /var/www/html/admin.

rm -rf /var/www/html/element-web/{*,.*}

rm -rf /var/www/html/admin/{*,.*}

Распаковать свежие архивы в эти папки и задать права, как я показывал выше.

ссылка на оригинал статьи https://habr.com/ru/articles/1057762/