Перейти к содержанию

RAMBA Matrix: различия между версиями

Материал из RAMBA Wiki
Нет описания правки
Нет описания правки
 
Строка 1: Строка 1:
= Развёртывание корпоративного мессенджера RAMBA Matrix =
<div class="portal-header">
<div class="portal-title">RAMBA Matrix</div>
<div class="portal-subtitle">
Корпоративный мессенджер RAMBA ART на базе открытого протокола Matrix
</div>
</div>


== Цель проекта ==
<div class="portal-card">
'''RAMBA Matrix''' — собственная коммуникационная платформа RAMBA ART на базе открытого протокола Matrix.


Цель проекта — развернуть собственный корпоративный мессенджер для организации RAMBA на базе открытого протокола Matrix.
Система предоставляет обмен сообщениями, групповые комнаты, сквозное шифрование, веб- и мобильные клиенты, а также аудио- и видеозвонки.


Основные требования:
Основная задача проекта — получить независимый корпоративный мессенджер, полностью размещённый на собственной инфраструктуре.
</div>


* собственный сервер сообщений;
__TOC__
* поддержка мобильных клиентов Android и iOS;
* поддержка веб-клиента;
* аудио- и видеозвонки;
* сквозное шифрование;
* контроль над данными;
* возможность работы примерно до 1000 пользователей;
* возможность дальнейшего резервного копирования и масштабирования.


== Итоговая архитектура ==
== Назначение проекта ==


В проекте используется следующая схема:
RAMBA Matrix создавался как собственная альтернатива внешним корпоративным мессенджерам.


<syntaxhighlight lang="text">
Основные требования:
Пользователь
  |
  | Element Web / Element Mobile
  |
Интернет
  |
  | HTTPS
  |
Reverse Proxy / SSL
BrainyCP: 192.168.1.12
  |
  | proxy_pass
  |
VM ramba-chat
Ubuntu Server 26.04
  |
  |-- Dendrite
  |-- PostgreSQL
  |-- Coturn
  |-- Media Store
</syntaxhighlight>


Основные домены:
* собственный сервер сообщений;
* хранение данных на инфраструктуре RAMBA ART;
* Android и iOS;
* веб-клиент;
* сквозное шифрование;
* личные и групповые комнаты;
* аудио- и видеозвонки;
* собственные Matrix ID;
* закрытая регистрация;
* возможность резервного копирования;
* возможность дальнейшего масштабирования;
* ориентация примерно на 1000 зарегистрированных пользователей.


{| class="wikitable"
Matrix ID пользователей имеют вид:
! Назначение
 
| ! Домен              |
| -------------------- |
| Matrix Homeserver    |
| chat.ramba-art.ru    |
| -                    |
| Element Web          |
| element.ramba-art.ru |
| -                    |
| Matrix Server Name  |
| ramba-art.ru        |
| }                    |
 
Matrix ID пользователей имеет вид:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
Строка 72: Строка 47:
</syntaxhighlight>
</syntaxhighlight>


== Почему выбран Matrix ==
== Архитектура RAMBA Matrix ==


Matrix — открытый протокол для обмена сообщениями, голосовой и видеосвязи.
Общая схема:


Преимущества Matrix:
<syntaxhighlight lang="text">
                        INTERNET
                            │
                            │ HTTPS
                            ▼
                  ┌──────────────────┐
                  │    BrainyCP    │
                  │      Nginx      │
                  │  Reverse Proxy  │
                  │      SSL        │
                  └────────┬─────────┘
                          │
                          │ HTTP
                          ▼
                ┌─────────────────────┐
                │      ramba-chat    │
                │                    │
                │      Dendrite      │
                │    PostgreSQL      │
                │      Coturn        │
                └─────────┬───────────┘
                          │
                          │
                ┌─────────┴───────────┐
                │                    │
                ▼                    ▼
          Media Store          TURN Relay
                │
                ▼
              OMV/NFS
</syntaxhighlight>


* открытый протокол;
Публичный веб-клиент Element работает отдельно и подключается к Matrix homeserver через HTTPS.
* нет привязки к одному поставщику;
* поддержка федерации между серверами;
* поддержка сквозного шифрования;
* есть готовые клиенты для Android, iOS, Web, Windows, Linux и macOS;
* можно хранить данные на собственной инфраструктуре;
* можно использовать собственный домен для пользователей.


Недостатки Matrix:
== Домены ==


* сложнее в администрировании, чем обычные SaaS-мессенджеры;
{| class="wikitable"
* требуется следить за обновлениями;
! Назначение
* требуется корректная настройка TURN/STUN для звонков;
! Адрес
* требуется резервное копирование базы данных и медиафайлов;
|-
* при больших нагрузках нужно планировать ресурсы заранее.
| Matrix Server Name
| <code>ramba-art.ru</code>
|-
| Homeserver
| <code>chat.ramba-art.ru</code>
|-
| Element Web
| <code>element.ramba-art.ru</code>
|}


== Почему выбран Dendrite ==
При этом серверное имя Matrix остаётся:


В качестве homeserver выбран Dendrite.
<syntaxhighlight lang="text">
ramba-art.ru
</syntaxhighlight>


Dendrite — сервер Matrix, написанный на Go. Он легче по ресурсам, чем классический Synapse, и подходит для компактного развёртывания.
Благодаря этому пользовательские ID не содержат технический поддомен `chat`.


Плюсы Dendrite:
== Компоненты системы ==


* низкое потребление памяти;
{| class="wikitable"
* простая монолитная установка;
! Компонент
* высокая скорость запуска;
! Назначение
* удобная сборка из исходного кода;
|-
* хорошо подходит для собственного сервера организации;
| '''Dendrite'''
* использует PostgreSQL как основную базу данных.
| Matrix homeserver
|-
| '''PostgreSQL'''
| Основная база данных
|-
| '''Element Web'''
| Веб-клиент Matrix
|-
| '''Element Mobile'''
| Клиенты Android и iOS
|-
| '''Coturn'''
| STUN/TURN для WebRTC
|-
| '''BrainyCP / Nginx'''
| Reverse proxy и SSL
|-
| '''OMV / NFS'''
| Хранилище медиафайлов
|-
| '''Proxmox VE'''
| Виртуализация и резервное копирование VM
|}


Минусы Dendrite:
== Почему выбран Matrix ==


* менее зрелый проект по сравнению с Synapse;
Matrix — открытый федеративный протокол для обмена сообщениями в реальном времени.
* часть экосистемы Matrix исторически лучше тестировалась на Synapse;
* меньше готовых инструкций и примеров;
* при нестандартных интеграциях может потребоваться ручная отладка.


Вывод: для RAMBA выбран Dendrite, потому что он проще и легче для собственного сервера, при этом покрывает основные требования проекта: сообщения, Element, федерация, E2EE и звонки.
Основные преимущества:


== Почему выбран PostgreSQL ==
* открытая спецификация;
* отсутствие привязки к одному поставщику;
* собственный сервер;
* собственный домен;
* поддержка E2EE;
* федерация;
* множество клиентских приложений;
* интеграции и боты;
* возможность работы полностью на собственной инфраструктуре.


PostgreSQL используется как основная база данных Dendrite.
Недостатки:


Плюсы PostgreSQL:
* инфраструктура сложнее обычного SaaS-мессенджера;
* необходимо обслуживать серверную часть;
* требуется отдельная настройка TURN для звонков;
* необходимо резервировать БД и media store;
* клиенты Matrix требуют корректного управления ключами шифрования.


* надёжная промышленная СУБД;
== Почему Dendrite ==
* хорошо подходит для постоянного хранения событий Matrix;
* поддерживается Dendrite;
* удобно резервировать через pg_dump;
* проще восстановить отдельно от файловой системы.


Минусы PostgreSQL:
В качестве Matrix homeserver используется '''Dendrite'''.


* требует отдельного контроля резервных копий;
Dendrite написан на Go и может работать в компактной монолитной конфигурации.
* нельзя полагаться только на snapshot VM;
* желательно не размещать базу на медленном сетевом хранилище.


Вывод: PostgreSQL следует хранить на локальном диске VM, а не на NFS.
Для RAMBA ART это позволило разместить Matrix homeserver на одной виртуальной машине без большого количества отдельных сервисов.


== Почему выбран Element ==
Преимущества:


Element выбран как основной клиент Matrix.
* компактная архитектура;
* написан на Go;
* сравнительно небольшое потребление ресурсов;
* поддержка PostgreSQL;
* поддержка Matrix Client API;
* федерация;
* E2EE;
* media API;
* интеграция с TURN.


Используются:
Особенность выбранной архитектуры — Dendrite работает как единый монолитный процесс.


* Element Web — через element.ramba-art.ru;
== PostgreSQL ==
* Element Mobile — для Android и iOS.


Плюсы Element:
PostgreSQL используется для постоянного хранения данных Matrix.


* официальный и наиболее развитый клиент Matrix;
В базе находятся:
* поддержка E2EE;
* поддержка аудио- и видеозвонков;
* есть веб-версия;
* есть мобильные приложения;
* можно заранее указать свой homeserver в config.json.


Минусы Element:
* события комнат;
* пользователи;
* состояния комнат;
* устройства;
* ключи;
* данные федерации;
* служебные данные homeserver.


* пользователю нужно привыкнуть к интерфейсу Matrix;
PostgreSQL должен размещаться на локальном быстром диске VM.
* при первом входе важно правильно настроить безопасное восстановление ключей;
* при работе через браузер возможны предупреждения Safe Browsing, если домен имеет плохую репутацию.


== Почему выбран Coturn ==
<syntaxhighlight lang="text">
 
Dendrite
Coturn используется для аудио- и видеозвонков.
    │
    ▼
PostgreSQL
    │
    ▼
Local SSD / VM Disk
</syntaxhighlight>


Для звонков Matrix/Element использует WebRTC. Если два клиента не могут соединиться напрямую через NAT, используется TURN-сервер.
Размещать активную БД PostgreSQL на NFS не рекомендуется.


Плюсы Coturn:
== Element ==


* стандартное решение для STUN/TURN;
'''Element''' используется как основной клиент RAMBA Matrix.
* совместим с WebRTC;
* поддерживает временные креды через shared secret;
* можно использовать с Matrix;
* можно ограничить диапазон relay-портов.


Минусы Coturn:
Поддерживаются:


* требует проброса портов на маршрутизаторе;
* Element Web;
* требует правильной настройки external-ip;
* Element для Android;
* при неправильном firewall звонок может подключаться без аудио или видео;
* Element для iOS;
* relay-трафик может создавать нагрузку на канал.
* desktop-клиенты.


В проекте используются порты:
Веб-клиент доступен через:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
3478/tcp
https://element.ramba-art.ru
3478/udp
5349/tcp
49152-49252/udp
</syntaxhighlight>
</syntaxhighlight>


Пример ключевых настроек Coturn:
Он заранее настроен на homeserver:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="text">
use-auth-secret
https://chat.ramba-art.ru
realm=ramba-art.ru
</syntaxhighlight>
listening-ip=192.168.1.50
external-ip=195.138.232.82
fingerprint
lt-cred-mech


min-port=49152
Поэтому обычному пользователю не требуется вручную указывать сервер.
max-port=49252 </syntaxhighlight>


== Почему используется Reverse Proxy BrainyCP ==
== Reverse Proxy ==


BrainyCP используется как внешний reverse proxy и точка управления SSL-сертификатами.
Публичный HTTPS-трафик проходит через BrainyCP.


Плюсы такого решения:
Схема:


* SSL-сертификаты управляются централизованно;
<syntaxhighlight lang="text">
* внешние домены обслуживаются в одном месте;
Client
* Dendrite и Element не публикуются напрямую;
  │
* проще управлять HTTPS;
  │ HTTPS
* можно разделить публичный фронт и внутренние сервисы.
  ▼
BrainyCP / Nginx
  │
  │ proxy_pass
  ▼
Dendrite
</syntaxhighlight>


Минусы:
Это позволяет:


* появляется дополнительная точка отказа;
* централизованно управлять SSL;
* ошибки в Nginx-конфигурации могут повлиять на Matrix;
* не публиковать Dendrite напрямую;
* нужно следить за корректной передачей заголовков;
* использовать единый внешний веб-уровень;
* при проблемах с HTTP/2 или TLS диагностика становится сложнее.
* независимо переносить backend между VM или узлами Proxmox.


== Почему VM, а не LXC ==
Основные proxy-заголовки:


Для Matrix выбран вариант с отдельной VM в Proxmox.
<syntaxhighlight lang="nginx">
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 https;
</syntaxhighlight>


Плюсы VM:
После изменения конфигурации Nginx:


* лучшая изоляция;
<syntaxhighlight lang="bash">
* проще переносить между узлами Proxmox;
nginx -t
* полноценная система с собственным ядром;
systemctl reload nginx
* удобнее делать snapshot и backup;
</syntaxhighlight>
* меньше неожиданных ограничений, чем в LXC.


Минусы VM:
== Matrix .well-known ==


* потребляет больше ресурсов, чем LXC;
Чтобы пользователи имели ID:
* нужно отдельно следить за обновлениями ОС;
* требуется больше дискового пространства.


Вывод: для корпоративного мессенджера VM предпочтительнее, так как важнее надёжность и изоляция.
<syntaxhighlight lang="text">
@user:ramba-art.ru
</syntaxhighlight>


== Развёртывание VM ==
а физический homeserver находился на `chat.ramba-art.ru`, используется Matrix delegation.


Рекомендуемые параметры VM для старта:
=== Server discovery ===


{| class="wikitable"
Адрес:
! Ресурс


| ! Значение          |
<syntaxhighlight lang="text">
| ------------------- |
https://ramba-art.ru/.well-known/matrix/server
| CPU                |
</syntaxhighlight>
| 4 vCPU              |
| -                  |
| RAM                |
| 8-16 GB            |
| -                  |
| Disk                |
| 100 GB              |
| -                  |
| OS                  |
| Ubuntu Server 26.04 |
| -                   |
| Network            |
| Static IP          |
| }                  |


В проекте используется VM:
Ответ:


<syntaxhighlight lang="text">
<syntaxhighlight lang="json">
ramba-chat
{
  "m.server": "chat.ramba-art.ru:443"
}
</syntaxhighlight>
</syntaxhighlight>


IP VM:
=== Client discovery ===
 
Адрес:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
192.168.1.50
https://ramba-art.ru/.well-known/matrix/client
</syntaxhighlight>
</syntaxhighlight>


== Установка системных пакетов ==
Ответ:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="json">
sudo apt update
{
sudo apt install -y git curl wget build-essential postgresql coturn nginx
  "m.homeserver": {
    "base_url": "https://chat.ramba-art.ru"
  }
}
</syntaxhighlight>
</syntaxhighlight>


Для сборки Dendrite также требуется Go.
Проверка:
 
== Установка PostgreSQL ==
 
Создаётся пользователь и база данных:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo -u postgres createuser dendrite
curl -s https://ramba-art.ru/.well-known/matrix/server
sudo -u postgres createdb -O dendrite dendrite
curl -s https://ramba-art.ru/.well-known/matrix/client
sudo -u postgres psql
</syntaxhighlight>
</syntaxhighlight>


Внутри psql задаётся пароль:
== Проверка Matrix API ==


<syntaxhighlight lang="sql">
Основная проверка homeserver:
ALTER USER dendrite WITH PASSWORD 'strong_password';
</syntaxhighlight>
 
== Сборка Dendrite ==


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cd /opt
curl -s \
sudo git clone https://github.com/matrix-org/dendrite.git
https://chat.ramba-art.ru/_matrix/client/versions
sudo chown -R $USER:$USER /opt/dendrite
</syntaxhighlight>
cd /opt/dendrite


go build -o bin/dendrite ./cmd/dendrite
При исправной конфигурации сервер возвращает JSON со списком поддерживаемых версий Matrix Client API.
go build -o bin/create-account ./cmd/create-account
go build -o bin/generate-config ./cmd/generate-config
go build -o bin/generate-keys ./cmd/generate-keys </syntaxhighlight>


== Генерация конфигурации Dendrite ==
== Dendrite ==


<syntaxhighlight lang="bash">
Рабочая конфигурация находится в:
cd /opt/dendrite


./bin/generate-keys --private-key matrix_key.pem
<syntaxhighlight lang="text">
/opt/dendrite/dendrite.yaml
</syntaxhighlight>


./bin/generate-config
Основные файлы:
--server ramba-art.ru
--db postgresql://dendrite:password@localhost/dendrite?sslmode=disable
--private-key matrix_key.pem \


> dendrite.yaml
<syntaxhighlight lang="text">
>
/opt/dendrite/
> </syntaxhighlight>
├── dendrite
├── dendrite.yaml
├── matrix_key.pem
└── media/
</syntaxhighlight>


После генерации конфиг редактируется вручную.
Ключевой параметр:
 
Важные параметры:


<syntaxhighlight lang="yaml">
<syntaxhighlight lang="yaml">
global:
global:
   server_name: ramba-art.ru
   server_name: ramba-art.ru
</syntaxhighlight>


media_api:
`server_name` после ввода системы в эксплуатацию менять не следует.
base_path: media
max_file_size_bytes: 10485760 </syntaxhighlight>


== Systemd-сервис Dendrite ==
Он является частью Matrix ID пользователей и идентичности homeserver.


Создаётся файл:
== Systemd ==
 
Dendrite запускается как системная служба.
 
Управление:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo nano /etc/systemd/system/dendrite.service
systemctl start dendrite
systemctl stop dendrite
systemctl restart dendrite
systemctl status dendrite
</syntaxhighlight>
</syntaxhighlight>


Пример:
Просмотр журнала:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="bash">
[Unit]
journalctl -u dendrite -f
Description=Dendrite Matrix Server
</syntaxhighlight>
After=network.target postgresql.service


[Service]
Последние записи:
Type=simple
WorkingDirectory=/opt/dendrite
ExecStart=/opt/dendrite/dendrite -config /opt/dendrite/dendrite.yaml
Restart=always
RestartSec=5
User=artem
Group=artem
 
[Install]
WantedBy=multi-user.target </syntaxhighlight>
 
Запуск:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo systemctl daemon-reload
journalctl -u dendrite -n 100 --no-pager
sudo systemctl enable --now dendrite
sudo systemctl status dendrite
</syntaxhighlight>
</syntaxhighlight>


== Настройка Reverse Proxy для Dendrite ==
== Регистрация пользователей ==


На стороне BrainyCP/Nginx создаётся HTTPS-сайт:
RAMBA Matrix работает как закрытая корпоративная система.


<syntaxhighlight lang="text">
Публичная регистрация пользователей отключена.
chat.ramba-art.ru
 
</syntaxhighlight>
Пользовательские записи создаются администратором.


Он проксирует запросы на:
Общая схема:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
http://192.168.1.50:8008
Администратор
      │
      ▼
Создание аккаунта
      │
      ▼
@username:ramba-art.ru
      │
      ▼
Первый вход пользователя
</syntaxhighlight>
</syntaxhighlight>


Важные заголовки:
Такой вариант позволяет контролировать доступ к системе и предотвращает автоматическую регистрацию посторонних пользователей.


<syntaxhighlight lang="nginx">
== Сквозное шифрование ==
proxy_set_header Host $host;
 
proxy_set_header X-Real-IP $remote_addr;
Matrix поддерживает End-to-End Encryption.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
</syntaxhighlight>


== Настройка .well-known ==
В зашифрованной комнате сообщение шифруется на клиенте отправителя и расшифровывается на устройстве получателя.


Для красивых Matrix ID вида:
Упрощённая схема:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
@user:ramba-art.ru
Client A
  │
  │ encrypted event
  ▼
Matrix Server
  │
  │ encrypted event
  ▼
Client B
</syntaxhighlight>
</syntaxhighlight>


нужно настроить .well-known на основном домене.
Homeserver хранит зашифрованное содержимое и не должен обладать ключами для расшифровки сообщений пользователей.


Файл:
Для пользователей особенно важно настроить восстановление ключей и не терять данные безопасного хранилища.


<syntaxhighlight lang="text">
== Media Store ==
https://ramba-art.ru/.well-known/matrix/server
</syntaxhighlight>


Содержимое:
Matrix хранит загружаемые изображения, документы, видео и другие вложения отдельно от основной PostgreSQL БД.


<syntaxhighlight lang="json">
Для RAMBA Matrix media store вынесен на отдельное хранилище.
{
  "m.server": "chat.ramba-art.ru:443"
}
</syntaxhighlight>


Файл:
Схема:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
https://ramba-art.ru/.well-known/matrix/client
Dendrite VM
    │
    ▼
Media directory
    │
    ▼
NFS
    │
    ▼
OMV Storage
</syntaxhighlight>
</syntaxhighlight>


Содержимое:
Это позволяет не увеличивать системный диск VM по мере роста количества вложений.
 
PostgreSQL при этом остаётся на локальном диске.


<syntaxhighlight lang="json">
== Права на NFS ==
{
  "m.homeserver": {
    "base_url": "https://chat.ramba-art.ru"
  }
}
</syntaxhighlight>


== Установка Element Web ==
При использовании NFS необходимо обеспечить правильные UID/GID пользователя, под которым работает Dendrite.


Element Web размещается на отдельном поддомене:
После монтирования следует проверить:


<syntaxhighlight lang="text">
<syntaxhighlight lang="bash">
element.ramba-art.ru
mount | grep matrix
ls -ld /matrix-media
</syntaxhighlight>
</syntaxhighlight>


Пример config.json:
И тест записи:


<syntaxhighlight lang="json">
<syntaxhighlight lang="bash">
{
touch /matrix-media/test
  "default_server_config": {
rm /matrix-media/test
    "m.homeserver": {
      "base_url": "https://chat.ramba-art.ru",
      "server_name": "ramba-art.ru"
    }
  },
  "disable_custom_urls": true,
  "disable_guests": true,
  "brand": "RAMBA Chat",
  "default_theme": "dark"
}
</syntaxhighlight>
</syntaxhighlight>


Плюсы отдельного поддомена для Element:
Тест необходимо выполнять от имени пользователя Dendrite.


* проще обслуживать веб-клиент;
== Coturn ==
* можно независимо обновлять Element;
* можно брендировать интерфейс;
* пользователю не нужно вручную вводить homeserver.


Минусы:
Coturn используется для STUN/TURN и обеспечивает работу звонков в сложных NAT-сценариях.


* нужен отдельный SSL-сертификат;
Без TURN два клиента могут успешно обмениваться сообщениями, но не иметь возможности установить аудио- или видеосоединение.
* при проблемах с репутацией домена браузер может блокировать страницу.


== Настройка Coturn ==
Архитектура звонка:


Установка:
<syntaxhighlight lang="text">
Element A
    │
    │ WebRTC
    ▼
STUN / TURN
    │
    ▼
Coturn
    │
    │ Relay
    ▼
Element B
</syntaxhighlight>


<syntaxhighlight lang="bash">
== TURN-порты ==
sudo apt install -y coturn
</syntaxhighlight>


Включение сервиса:
В инфраструктуре используется ограниченный диапазон relay-портов:


<syntaxhighlight lang="bash">
{| class="wikitable"
sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn
! Порт
</syntaxhighlight>
! Протокол
! Назначение
|-
| 3478
| TCP / UDP
| STUN / TURN
|-
| 5349
| TCP
| TURN over TLS
|-
| 49152–49252
| UDP
| TURN Relay
|}
 
Этот диапазон должен быть разрешён firewall и корректно проброшен через NAT.


Пример конфигурации:
== Пример конфигурации Coturn ==


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
listening-port=3478
listening-port=3478
tls-listening-port=5349
tls-listening-port=5349
listening-ip=192.168.1.50
relay-ip=192.168.1.50
external-ip=195.138.232.82


use-auth-secret
use-auth-secret
static-auth-secret=SECRET
realm=ramba-art.ru
realm=ramba-art.ru


fingerprint
fingerprint
lt-cred-mech
lt-cred-mech
min-port=49152
max-port=49252
no-multicast-peers
no-multicast-peers
no-cli
no-cli
</syntaxhighlight>


min-port=49152
Также должны быть корректно настроены:
max-port=49252 </syntaxhighlight>


Запуск:
<syntaxhighlight lang="ini">
listening-ip=
relay-ip=
external-ip=
</syntaxhighlight>


<syntaxhighlight lang="bash">
Конкретные значения зависят от текущей сетевой архитектуры.
sudo systemctl enable --now coturn
sudo systemctl status coturn
</syntaxhighlight>


== Настройка TURN в Dendrite ==
== TURN в Dendrite ==


В dendrite.yaml указывается TURN-сервер:
В конфигурации Dendrite указываются URI TURN-сервера:


<syntaxhighlight lang="yaml">
<syntaxhighlight lang="yaml">
Строка 533: Строка 574:
   turn:
   turn:
     turn_user_lifetime: "5m"
     turn_user_lifetime: "5m"
     turn_uris:
     turn_uris:
       - "turn:turn.ramba-art.ru:3478?transport=udp"
       - "turn:turn.ramba-art.ru:3478?transport=udp"
       - "turn:turn.ramba-art.ru:3478?transport=tcp"
       - "turn:turn.ramba-art.ru:3478?transport=tcp"
       - "turns:turn.ramba-art.ru:5349?transport=tcp"
       - "turns:turn.ramba-art.ru:5349?transport=tcp"
     turn_shared_secret: "SECRET"
     turn_shared_secret: "SECRET"
</syntaxhighlight>
</syntaxhighlight>


Секрет в Dendrite должен совпадать со значением static-auth-secret в Coturn.
`turn_shared_secret` должен совпадать с `static-auth-secret` Coturn.


Проверка:
Секреты не следует публиковать в Wiki.
 
== Проверка TURN ==
 
Проверка выдачи временных TURN credentials:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
curl -s https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer
curl -s \
https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer
</syntaxhighlight>
</syntaxhighlight>


Если всё настроено правильно, сервер отдаёт временные TURN-креды.
В рабочем состоянии сервер возвращает:


== Проброс портов ==
* username;
* password;
* TTL;
* список TURN URI.


На внешнем маршрутизаторе или firewall нужно пробросить на VM ramba-chat:
== Тестирование звонков ==


{| class="wikitable"
Для корректной проверки необходимо использовать два независимых устройства.
! Порт
! Протокол


| ! Назначение |
Желательно:
| ------------ |
| 3478        |
| TCP/UDP      |
| STUN/TURN    |
| -            |
| 5349        |
| TCP          |
| TURNS        |
| -            |
| 49152-49252  |
| UDP          |
| TURN relay  |
| }            |


== Регистрация пользователей ==
* одно устройство через Wi-Fi;
* второе через мобильную сеть.


Для корпоративного сервера не рекомендуется открывать публичную регистрацию.
Это заставляет WebRTC проходить через реальные NAT-сценарии.


Рекомендуемая схема:
Проверяем:


* регистрация закрыта;
# текстовые сообщения;
* пользователей создаёт администратор;
# зашифрованный личный чат;
* после первого входа пользователь меняет временный пароль.
# аудиозвонок;
# видеозвонок;
# входящий вызов;
# работу после переключения сети.


Создание пользователя:
Успешный звонок через разные сети подтверждает работу:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="text">
cd /opt/dendrite
Element
  +
Dendrite
  +
WebRTC
  +
STUN
  +
TURN
  +
NAT
  +
Firewall
</syntaxhighlight>


./create-account
== Element Web ==
--config dendrite.yaml
--username username
--password 'temporary_password' </syntaxhighlight>


Пример результата:
Element Web работает на отдельном домене:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
@username:ramba-art.ru
https://element.ramba-art.ru
</syntaxhighlight>
 
Пример основных параметров `config.json`:
 
<syntaxhighlight lang="json">
{
  "default_server_config": {
    "m.homeserver": {
      "base_url": "https://chat.ramba-art.ru",
      "server_name": "ramba-art.ru"
    }
  },
 
  "disable_custom_urls": true,
  "disable_guests": true,
  "brand": "RAMBA Chat",
  "default_theme": "dark"
}
</syntaxhighlight>
</syntaxhighlight>


Плюсы закрытой регистрации:
Благодаря этому пользователю достаточно открыть Element и войти под своим RAMBA Matrix аккаунтом.


* нет спама;
== Мобильные клиенты ==
* нет случайных пользователей;
* проще управлять безопасностью;
* подходит для корпоративного мессенджера.


Минусы:
На мобильных устройствах используются Matrix-совместимые клиенты.


* пользователей нужно создавать вручную или через скрипт;
Для подключения используется homeserver:
* нужен регламент выдачи доступов;
* нужно продумать удаление или блокировку уволенных сотрудников.


== Медиафайлы ==
<syntaxhighlight lang="text">
https://chat.ramba-art.ru
</syntaxhighlight>


В Dendrite медиа хранятся в каталоге:
Либо автоматическое обнаружение через:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
/opt/dendrite/media
ramba-art.ru
</syntaxhighlight>
</syntaxhighlight>


В конфигурации:
После входа рекомендуется сразу настроить:


<syntaxhighlight lang="yaml">
* подтверждение устройства;
media_api:
* безопасное хранилище;
  base_path: media
* восстановление ключей;
  max_file_size_bytes: 10485760
* PIN/Face ID клиента;
* push-уведомления.
 
== Федерация ==
 
Matrix поддерживает обмен событиями между независимыми homeserver.
 
Для федерации используется server name:
 
<syntaxhighlight lang="text">
ramba-art.ru
</syntaxhighlight>
</syntaxhighlight>


Лимит одного файла:
и delegation на:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
10 MB
chat.ramba-art.ru
</syntaxhighlight>
</syntaxhighlight>


Если комната зашифрована, Element шифрует вложения на клиенте перед загрузкой. Сервер хранит зашифрованный blob и не имеет ключей расшифровки.
Базовая проверка:


Если комната не зашифрована, сервер хранит обычные медиафайлы.
<syntaxhighlight lang="bash">
curl -s \
https://ramba-art.ru/.well-known/matrix/server
</syntaxhighlight>


Рекомендации:
При проблемах с федерацией необходимо проверять:


* рабочие комнаты создавать с E2EE;
* DNS;
* каталог media включить в резервное копирование;
* TLS;
* при росте объёма вынести media на отдельное хранилище;
* `.well-known`;
* PostgreSQL не выносить на NFS.
* доступность `chat.ramba-art.ru`;
* Nginx;
* журнал Dendrite.


== Вариант выноса медиа на NFS/OMV ==
== Резервное копирование ==
 
Matrix нельзя считать защищённым только потому, что существует snapshot VM.
 
Необходимо резервировать отдельно:


Для роста системы можно вынести только медиафайлы на OMV NFS.
{| class="wikitable"
! Компонент
! Требуется backup
|-
| PostgreSQL
| Да
|-
| dendrite.yaml
| Да
|-
| matrix_key.pem
| '''Обязательно'''
|-
| Media Store
| Да
|-
| Coturn config
| Да
|-
| Element config.json
| Да
|-
| BrainyCP / Nginx vhost
| Да
|}


Рекомендуемая схема:
Особенно критичен:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
VM ramba-chat
matrix_key.pem
  |-- PostgreSQL локально
  |-- Dendrite локально
  |-- JetStream локально
  |-- /opt/dendrite/media -> NFS OMV
</syntaxhighlight>
</syntaxhighlight>


Плюсы:
Это identity key Matrix homeserver. Его потеря может привести к серьёзным проблемам с федерацией и идентичностью сервера.
 
== PostgreSQL backup ==


* медиа не раздувают диск VM;
Пример:
* проще расширять хранилище;
* удобно делать отдельные бэкапы;
* можно использовать шифрование дисков на OMV.


Минусы:
<syntaxhighlight lang="bash">
sudo -u postgres \
pg_dump dendrite \
> /root/dendrite-$(date +%F).sql
</syntaxhighlight>


* появляется зависимость от сети и OMV;
Проверяем:
* при недоступности NFS будут проблемы с загрузкой и скачиванием файлов;
* нужна аккуратная настройка прав доступа;
* база данных и JetStream должны оставаться локально.


== Резервное копирование ==
<syntaxhighlight lang="bash">
ls -lh /root/dendrite-*.sql
</syntaxhighlight>
 
Для production рекомендуется автоматизировать резервное копирование и периодически тестировать восстановление.
 
== Backup конфигурации ==
 
Пример:
 
<syntaxhighlight lang="bash">
tar -czf /root/ramba-matrix-config-$(date +%F).tar.gz \
    /opt/dendrite/dendrite.yaml \
    /opt/dendrite/matrix_key.pem \
    /etc/turnserver.conf \
    /etc/systemd/system/dendrite.service
</syntaxhighlight>
 
Файл с `matrix_key.pem` должен храниться в защищённом месте.
 
== Proxmox Backup ==
 
Виртуальная машина RAMBA Matrix также резервируется средствами Proxmox.


Обязательно резервировать:
Схема:


<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
PostgreSQL database dendrite
RAMBA Matrix VM
/opt/dendrite
      │
/opt/dendrite/media
      ▼
/etc/turnserver.conf
Proxmox VE
/etc/systemd/system/dendrite.service
      │
Element config.json
      ▼
Nginx/BrainyCP vhost-конфиги
Proxmox Backup Server
</syntaxhighlight>
</syntaxhighlight>


Пример резервного копирования конфигов:
Backup VM полезен для быстрого полного восстановления, но не заменяет логический dump PostgreSQL.
 
== Мониторинг ==
 
Минимальный набор проверок:
 
=== Dendrite ===


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo tar czf /root/ramba-matrix-configs-$(date +%F).tar.gz \
systemctl status dendrite
/opt/dendrite \
/etc/turnserver.conf \
/etc/systemd/system/dendrite.service
</syntaxhighlight>
</syntaxhighlight>


Пример дампа PostgreSQL:
=== PostgreSQL ===


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo -u postgres pg_dump dendrite > /root/dendrite-$(date +%F).sql
systemctl status postgresql
</syntaxhighlight>
</syntaxhighlight>


== Проверка работоспособности ==
=== Coturn ===


Проверка .well-known:
<syntaxhighlight lang="bash">
systemctl status coturn
</syntaxhighlight>
 
=== Matrix API ===


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
curl -s https://ramba-art.ru/.well-known/matrix/server
curl -s \
curl -s https://ramba-art.ru/.well-known/matrix/client
https://chat.ramba-art.ru/_matrix/client/versions
</syntaxhighlight>
 
=== TURN ===
 
<syntaxhighlight lang="bash">
curl -s \
https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer
</syntaxhighlight>
 
=== Media storage ===
 
<syntaxhighlight lang="bash">
df -h
mount | grep matrix
</syntaxhighlight>
 
== Диагностика ==
 
=== Dendrite не запускается ===
 
<syntaxhighlight lang="bash">
systemctl status dendrite
journalctl -u dendrite -n 100 --no-pager
</syntaxhighlight>
 
=== Matrix API недоступен ===
 
Проверяем цепочку:
 
<syntaxhighlight lang="text">
Client
  │
  ▼
DNS
  │
  ▼
BrainyCP
  │
  ▼
Nginx
  │
  ▼
Dendrite
</syntaxhighlight>
</syntaxhighlight>


Проверка Matrix API:
Проверяем внешний адрес:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
curl -s https://chat.ramba-art.ru/_matrix/client/versions
curl -Iv https://chat.ramba-art.ru/
</syntaxhighlight>
</syntaxhighlight>


Проверка Dendrite:
И backend непосредственно из LAN:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo systemctl status dendrite --no-pager
curl -I http://MATRIX_BACKEND_IP:8008/
sudo journalctl -u dendrite -n 80 --no-pager
</syntaxhighlight>
</syntaxhighlight>


Проверка Coturn:
=== Звонок соединяется без аудио ===
 
В первую очередь проверяем:
 
* Coturn;
* relay UDP range;
* NAT;
* `external-ip`;
* firewall;
* TURN credentials.
 
Проверяем:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo systemctl status coturn --no-pager
ss -tulpn | grep turnserver
sudo ss -tulpn | grep turnserver
</syntaxhighlight>
</syntaxhighlight>


Проверка TURN-кредов:
=== Не загружаются медиа ===
 
Проверяем:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
curl -s https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer
mount | grep matrix
df -h
ls -ld /matrix-media
</syntaxhighlight>
 
Также необходимо проверить права пользователя Dendrite на NFS.
 
== Производительность ==
 
Основная нагрузка Matrix распределяется между:
 
<syntaxhighlight lang="text">
CPU
│
├── Dendrite
├── PostgreSQL
└── Federation
 
RAM
│
├── Dendrite
└── PostgreSQL
 
Disk
│
├── PostgreSQL
└── Media
 
Network
│
├── Federation
├── Media
└── TURN
</syntaxhighlight>
</syntaxhighlight>


== Тестирование звонков ==
Для небольшого и среднего deployment особенно важны:


Финальный тест:
* быстрый локальный диск PostgreSQL;
* достаточный объём RAM;
* стабильное сетевое подключение;
* отдельное пространство для media store.


* создать двух пользователей;
== Масштабирование ==
* войти в Element с двух разных устройств;
* желательно использовать мобильную сеть, а не один Wi-Fi;
* проверить личный чат;
* проверить аудиозвонок;
* проверить видеозвонок.


Успешный звонок через мобильного оператора подтверждает, что работают:
Текущая архитектура намеренно проста:


* Dendrite;
<syntaxhighlight lang="text">
* Element;
1 VM
* WebRTC;
│
* STUN;
├── Dendrite
├── PostgreSQL
└── Coturn
</syntaxhighlight>
 
По мере роста можно отдельно масштабировать:
 
* PostgreSQL;
* media store;
* TURN;
* TURN;
* NAT traversal;
* reverse proxy;
* reverse proxy;
* SSL.
* мониторинг;
* резервное копирование.


== Плюсы выбранной архитектуры ==
Media Store уже удобно отделять от системного диска через NFS.


* полный контроль над данными;
== Безопасность ==
* собственные Matrix ID на домене ramba-art.ru;
 
* независимость от сторонних SaaS-мессенджеров;
Для RAMBA Matrix рекомендуется:
* поддержка Android, iOS и Web;
 
* поддержка аудио- и видеосвязи;
* держать публичную регистрацию отключённой;
* поддержка E2EE;
* использовать E2EE;
* простая архитектура на одной VM;
* не публиковать PostgreSQL;
* PostgreSQL локально для надёжности;
* не публиковать внутренний порт Dendrite;
* медиа можно вынести на отдельное хранилище;
* не хранить секреты в Wiki;
* reverse proxy и SSL централизованы через BrainyCP.
* регулярно менять административные пароли;
* ограничивать SSH;
* резервировать `matrix_key.pem`;
* хранить backup вне основной VM;
* обновлять Dendrite, PostgreSQL, Element и Coturn;
* проверять журналы после обновлений.
 
== Полезные команды ==
 
{| class="wikitable"
! Задача
! Команда
|-
| Статус Dendrite
| <code>systemctl status dendrite</code>
|-
| Перезапуск Dendrite
| <code>systemctl restart dendrite</code>
|-
| Логи Dendrite
| <code>journalctl -u dendrite -f</code>
|-
| Статус PostgreSQL
| <code>systemctl status postgresql</code>
|-
| Статус Coturn
| <code>systemctl status coturn</code>
|-
| Проверить Matrix API
| <code>curl -s https://chat.ramba-art.ru/_matrix/client/versions</code>
|-
| Проверить TURN
| <code>curl -s https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer</code>
|-
| Проверить NFS
| <code>mount | grep matrix</code>
|-
| Проверить диск
| <code>df -h</code>
|}
 
== Итоговая схема ==
 
<syntaxhighlight lang="text">
                        USERS
                          │
            ┌────────────┴────────────┐
            │                        │
            ▼                        ▼
      Element Web              Element Mobile
            │                        │
            └────────────┬────────────┘
                          │
                          │ HTTPS
                          ▼
                ┌─────────────────┐
                │    BrainyCP    │
                │      Nginx      │
                │      SSL       │
                └────────┬────────┘
                          │
                          ▼
                ┌─────────────────┐
                │    Dendrite    │
                └──────┬─────┬────┘
                        │    │
                        │    └──────────────┐
                        ▼                    ▼
                  PostgreSQL              Coturn
                        │                    │
                        │                    ▼
                        │              TURN Relay
                        │
                        ▼
                  Local Disk
 
                    Media API
                        │
                        ▼
                    OMV / NFS
</syntaxhighlight>
 
== Результат ==


== Минусы выбранной архитектуры ==
RAMBA Matrix представляет собой полностью самостоятельную коммуникационную платформу, работающую на инфраструктуре RAMBA ART.


* требуется администрирование сервера;
Система обеспечивает:
* нужно следить за Dendrite, PostgreSQL, Coturn и Element;
* требуется регулярный backup;
* требуется ручное создание пользователей или отдельный скрипт;
* Dendrite менее зрелый, чем Synapse;
* звонки зависят от правильной настройки TURN;
* при проблемах с доменной репутацией браузер может блокировать Element;
* при росте нагрузки может потребоваться отдельное масштабирование.


== Рекомендации по эксплуатации ==
* собственные Matrix ID;
* личные и групповые чаты;
* E2EE;
* Android и iOS;
* Element Web;
* голосовые звонки;
* видеозвонки;
* собственное хранение данных;
* резервное копирование;
* федерацию;
* возможность дальнейшего масштабирования.


* держать регистрацию закрытой;
При этом публичный веб-уровень, Matrix backend, база данных и media store разделены между отдельными компонентами инфраструктуры.
* создавать пользователей централизованно;
* использовать E2EE для рабочих комнат;
* регулярно проверять резервные копии;
* не хранить PostgreSQL на NFS;
* следить за размером /opt/dendrite/media;
* обновлять Element Web отдельно от Dendrite;
* фиксировать изменения конфигов в отдельной Wiki-странице;
* после стабильного запуска создать snapshot VM в Proxmox.


== Итог ==
== См. также ==


Выбранная архитектура подходит для собственного корпоративного мессенджера RAMBA.
* [[BrainyCP]]
* [[Proxmox VE]]
* [[Proxmox Backup Server]]
* [[OpenMediaVault]]
* [[RAMBA Wiki]]
* [[Мониторинг]]


Она даёт контроль над пользователями, сообщениями, медиафайлами и доменом, при этом остаётся достаточно простой для сопровождения: одна VM, один Matrix homeserver, PostgreSQL, Coturn и Element Web.
== Внешние ссылки ==


Для текущего этапа архитектура считается рабочей. Дальнейшие улучшения:
* [https://matrix.org/ Matrix.org]
* [https://spec.matrix.org/ Matrix Specification]
* [https://github.com/element-hq/dendrite Dendrite]
* [https://element.io/ Element]
* [https://github.com/coturn/coturn Coturn]


* автоматизация создания пользователей;
[[Категория:Matrix]]
* настройка регулярного backup;
[[Категория:RAMBA Matrix]]
* вынос media store на OMV/NFS;
[[Категория:Мессенджеры]]
* брендирование Element;
[[Категория:Linux]]
* мониторинг сервисов;
[[Категория:Proxmox]]
* исправление репутации домена в Google Safe Browsing.
[[Категория:Сетевая инфраструктура]]
[[Категория:RAMBA ART]]

Текущая версия от 13:37, 2 сентября 2026

RAMBA Matrix

Корпоративный мессенджер RAMBA ART на базе открытого протокола Matrix

RAMBA Matrix — собственная коммуникационная платформа RAMBA ART на базе открытого протокола Matrix.

Система предоставляет обмен сообщениями, групповые комнаты, сквозное шифрование, веб- и мобильные клиенты, а также аудио- и видеозвонки.

Основная задача проекта — получить независимый корпоративный мессенджер, полностью размещённый на собственной инфраструктуре.

Назначение проекта

RAMBA Matrix создавался как собственная альтернатива внешним корпоративным мессенджерам.

Основные требования:

  • собственный сервер сообщений;
  • хранение данных на инфраструктуре RAMBA ART;
  • Android и iOS;
  • веб-клиент;
  • сквозное шифрование;
  • личные и групповые комнаты;
  • аудио- и видеозвонки;
  • собственные Matrix ID;
  • закрытая регистрация;
  • возможность резервного копирования;
  • возможность дальнейшего масштабирования;
  • ориентация примерно на 1000 зарегистрированных пользователей.

Matrix ID пользователей имеют вид:

@username:ramba-art.ru

Например:

@ivan_ivanov:ramba-art.ru

Архитектура RAMBA Matrix

Общая схема:

                         INTERNET
                            │
                            │ HTTPS
                            ▼
                  ┌──────────────────┐
                  │     BrainyCP     │
                  │      Nginx       │
                  │  Reverse Proxy   │
                  │       SSL        │
                  └────────┬─────────┘
                           │
                           │ HTTP
                           ▼
                ┌─────────────────────┐
                │      ramba-chat     │
                │                     │
                │      Dendrite       │
                │     PostgreSQL      │
                │       Coturn        │
                └─────────┬───────────┘
                          │
                          │
                ┌─────────┴───────────┐
                │                     │
                ▼                     ▼
           Media Store          TURN Relay
                │
                ▼
              OMV/NFS

Публичный веб-клиент Element работает отдельно и подключается к Matrix homeserver через HTTPS.

Домены

Назначение Адрес
Matrix Server Name ramba-art.ru
Homeserver chat.ramba-art.ru
Element Web element.ramba-art.ru

При этом серверное имя Matrix остаётся:

ramba-art.ru

Благодаря этому пользовательские ID не содержат технический поддомен `chat`.

Компоненты системы

Компонент Назначение
Dendrite Matrix homeserver
PostgreSQL Основная база данных
Element Web Веб-клиент Matrix
Element Mobile Клиенты Android и iOS
Coturn STUN/TURN для WebRTC
BrainyCP / Nginx Reverse proxy и SSL
OMV / NFS Хранилище медиафайлов
Proxmox VE Виртуализация и резервное копирование VM

Почему выбран Matrix

Matrix — открытый федеративный протокол для обмена сообщениями в реальном времени.

Основные преимущества:

  • открытая спецификация;
  • отсутствие привязки к одному поставщику;
  • собственный сервер;
  • собственный домен;
  • поддержка E2EE;
  • федерация;
  • множество клиентских приложений;
  • интеграции и боты;
  • возможность работы полностью на собственной инфраструктуре.

Недостатки:

  • инфраструктура сложнее обычного SaaS-мессенджера;
  • необходимо обслуживать серверную часть;
  • требуется отдельная настройка TURN для звонков;
  • необходимо резервировать БД и media store;
  • клиенты Matrix требуют корректного управления ключами шифрования.

Почему Dendrite

В качестве Matrix homeserver используется Dendrite.

Dendrite написан на Go и может работать в компактной монолитной конфигурации.

Для RAMBA ART это позволило разместить Matrix homeserver на одной виртуальной машине без большого количества отдельных сервисов.

Преимущества:

  • компактная архитектура;
  • написан на Go;
  • сравнительно небольшое потребление ресурсов;
  • поддержка PostgreSQL;
  • поддержка Matrix Client API;
  • федерация;
  • E2EE;
  • media API;
  • интеграция с TURN.

Особенность выбранной архитектуры — Dendrite работает как единый монолитный процесс.

PostgreSQL

PostgreSQL используется для постоянного хранения данных Matrix.

В базе находятся:

  • события комнат;
  • пользователи;
  • состояния комнат;
  • устройства;
  • ключи;
  • данные федерации;
  • служебные данные homeserver.

PostgreSQL должен размещаться на локальном быстром диске VM.

Dendrite
    │
    ▼
PostgreSQL
    │
    ▼
Local SSD / VM Disk

Размещать активную БД PostgreSQL на NFS не рекомендуется.

Element

Element используется как основной клиент RAMBA Matrix.

Поддерживаются:

  • Element Web;
  • Element для Android;
  • Element для iOS;
  • desktop-клиенты.

Веб-клиент доступен через:

https://element.ramba-art.ru

Он заранее настроен на homeserver:

https://chat.ramba-art.ru

Поэтому обычному пользователю не требуется вручную указывать сервер.

Reverse Proxy

Публичный HTTPS-трафик проходит через BrainyCP.

Схема:

Client
  │
  │ HTTPS
  ▼
BrainyCP / Nginx
  │
  │ proxy_pass
  ▼
Dendrite

Это позволяет:

  • централизованно управлять SSL;
  • не публиковать Dendrite напрямую;
  • использовать единый внешний веб-уровень;
  • независимо переносить backend между VM или узлами Proxmox.

Основные proxy-заголовки:

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 https;

После изменения конфигурации Nginx:

nginx -t
systemctl reload nginx

Matrix .well-known

Чтобы пользователи имели ID:

@user:ramba-art.ru

а физический homeserver находился на `chat.ramba-art.ru`, используется Matrix delegation.

Server discovery

Адрес:

https://ramba-art.ru/.well-known/matrix/server

Ответ:

{
  "m.server": "chat.ramba-art.ru:443"
}

Client discovery

Адрес:

https://ramba-art.ru/.well-known/matrix/client

Ответ:

{
  "m.homeserver": {
    "base_url": "https://chat.ramba-art.ru"
  }
}

Проверка:

curl -s https://ramba-art.ru/.well-known/matrix/server
curl -s https://ramba-art.ru/.well-known/matrix/client

Проверка Matrix API

Основная проверка homeserver:

curl -s \
https://chat.ramba-art.ru/_matrix/client/versions

При исправной конфигурации сервер возвращает JSON со списком поддерживаемых версий Matrix Client API.

Dendrite

Рабочая конфигурация находится в:

/opt/dendrite/dendrite.yaml

Основные файлы:

/opt/dendrite/
├── dendrite
├── dendrite.yaml
├── matrix_key.pem
└── media/

Ключевой параметр:

global:
  server_name: ramba-art.ru

`server_name` после ввода системы в эксплуатацию менять не следует.

Он является частью Matrix ID пользователей и идентичности homeserver.

Systemd

Dendrite запускается как системная служба.

Управление:

systemctl start dendrite
systemctl stop dendrite
systemctl restart dendrite
systemctl status dendrite

Просмотр журнала:

journalctl -u dendrite -f

Последние записи:

journalctl -u dendrite -n 100 --no-pager

Регистрация пользователей

RAMBA Matrix работает как закрытая корпоративная система.

Публичная регистрация пользователей отключена.

Пользовательские записи создаются администратором.

Общая схема:

Администратор
      │
      ▼
Создание аккаунта
      │
      ▼
@username:ramba-art.ru
      │
      ▼
Первый вход пользователя

Такой вариант позволяет контролировать доступ к системе и предотвращает автоматическую регистрацию посторонних пользователей.

Сквозное шифрование

Matrix поддерживает End-to-End Encryption.

В зашифрованной комнате сообщение шифруется на клиенте отправителя и расшифровывается на устройстве получателя.

Упрощённая схема:

Client A
   │
   │ encrypted event
   ▼
Matrix Server
   │
   │ encrypted event
   ▼
Client B

Homeserver хранит зашифрованное содержимое и не должен обладать ключами для расшифровки сообщений пользователей.

Для пользователей особенно важно настроить восстановление ключей и не терять данные безопасного хранилища.

Media Store

Matrix хранит загружаемые изображения, документы, видео и другие вложения отдельно от основной PostgreSQL БД.

Для RAMBA Matrix media store вынесен на отдельное хранилище.

Схема:

Dendrite VM
     │
     ▼
Media directory
     │
     ▼
NFS
     │
     ▼
OMV Storage

Это позволяет не увеличивать системный диск VM по мере роста количества вложений.

PostgreSQL при этом остаётся на локальном диске.

Права на NFS

При использовании NFS необходимо обеспечить правильные UID/GID пользователя, под которым работает Dendrite.

После монтирования следует проверить:

mount | grep matrix
ls -ld /matrix-media

И тест записи:

touch /matrix-media/test
rm /matrix-media/test

Тест необходимо выполнять от имени пользователя Dendrite.

Coturn

Coturn используется для STUN/TURN и обеспечивает работу звонков в сложных NAT-сценариях.

Без TURN два клиента могут успешно обмениваться сообщениями, но не иметь возможности установить аудио- или видеосоединение.

Архитектура звонка:

Element A
    │
    │ WebRTC
    ▼
STUN / TURN
    │
    ▼
 Coturn
    │
    │ Relay
    ▼
Element B

TURN-порты

В инфраструктуре используется ограниченный диапазон relay-портов:

Порт Протокол Назначение
3478 TCP / UDP STUN / TURN
5349 TCP TURN over TLS
49152–49252 UDP TURN Relay

Этот диапазон должен быть разрешён firewall и корректно проброшен через NAT.

Пример конфигурации Coturn

listening-port=3478
tls-listening-port=5349

use-auth-secret
realm=ramba-art.ru

fingerprint
lt-cred-mech

min-port=49152
max-port=49252

no-multicast-peers
no-cli

Также должны быть корректно настроены:

listening-ip=
relay-ip=
external-ip=

Конкретные значения зависят от текущей сетевой архитектуры.

TURN в Dendrite

В конфигурации Dendrite указываются URI TURN-сервера:

client_api:
  turn:
    turn_user_lifetime: "5m"

    turn_uris:
      - "turn:turn.ramba-art.ru:3478?transport=udp"
      - "turn:turn.ramba-art.ru:3478?transport=tcp"
      - "turns:turn.ramba-art.ru:5349?transport=tcp"

    turn_shared_secret: "SECRET"

`turn_shared_secret` должен совпадать с `static-auth-secret` Coturn.

Секреты не следует публиковать в Wiki.

Проверка TURN

Проверка выдачи временных TURN credentials:

curl -s \
https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer

В рабочем состоянии сервер возвращает:

  • username;
  • password;
  • TTL;
  • список TURN URI.

Тестирование звонков

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

Желательно:

  • одно устройство через Wi-Fi;
  • второе через мобильную сеть.

Это заставляет WebRTC проходить через реальные NAT-сценарии.

Проверяем:

  1. текстовые сообщения;
  2. зашифрованный личный чат;
  3. аудиозвонок;
  4. видеозвонок;
  5. входящий вызов;
  6. работу после переключения сети.

Успешный звонок через разные сети подтверждает работу:

Element
   +
Dendrite
   +
WebRTC
   +
STUN
   +
TURN
   +
NAT
   +
Firewall

Element Web

Element Web работает на отдельном домене:

https://element.ramba-art.ru

Пример основных параметров `config.json`:

{
  "default_server_config": {
    "m.homeserver": {
      "base_url": "https://chat.ramba-art.ru",
      "server_name": "ramba-art.ru"
    }
  },

  "disable_custom_urls": true,
  "disable_guests": true,
  "brand": "RAMBA Chat",
  "default_theme": "dark"
}

Благодаря этому пользователю достаточно открыть Element и войти под своим RAMBA Matrix аккаунтом.

Мобильные клиенты

На мобильных устройствах используются Matrix-совместимые клиенты.

Для подключения используется homeserver:

https://chat.ramba-art.ru

Либо автоматическое обнаружение через:

ramba-art.ru

После входа рекомендуется сразу настроить:

  • подтверждение устройства;
  • безопасное хранилище;
  • восстановление ключей;
  • PIN/Face ID клиента;
  • push-уведомления.

Федерация

Matrix поддерживает обмен событиями между независимыми homeserver.

Для федерации используется server name:

ramba-art.ru

и delegation на:

chat.ramba-art.ru

Базовая проверка:

curl -s \
https://ramba-art.ru/.well-known/matrix/server

При проблемах с федерацией необходимо проверять:

  • DNS;
  • TLS;
  • `.well-known`;
  • доступность `chat.ramba-art.ru`;
  • Nginx;
  • журнал Dendrite.

Резервное копирование

Matrix нельзя считать защищённым только потому, что существует snapshot VM.

Необходимо резервировать отдельно:

Компонент Требуется backup
PostgreSQL Да
dendrite.yaml Да
matrix_key.pem Обязательно
Media Store Да
Coturn config Да
Element config.json Да
BrainyCP / Nginx vhost Да

Особенно критичен:

matrix_key.pem

Это identity key Matrix homeserver. Его потеря может привести к серьёзным проблемам с федерацией и идентичностью сервера.

PostgreSQL backup

Пример:

sudo -u postgres \
pg_dump dendrite \
> /root/dendrite-$(date +%F).sql

Проверяем:

ls -lh /root/dendrite-*.sql

Для production рекомендуется автоматизировать резервное копирование и периодически тестировать восстановление.

Backup конфигурации

Пример:

tar -czf /root/ramba-matrix-config-$(date +%F).tar.gz \
    /opt/dendrite/dendrite.yaml \
    /opt/dendrite/matrix_key.pem \
    /etc/turnserver.conf \
    /etc/systemd/system/dendrite.service

Файл с `matrix_key.pem` должен храниться в защищённом месте.

Proxmox Backup

Виртуальная машина RAMBA Matrix также резервируется средствами Proxmox.

Схема:

RAMBA Matrix VM
      │
      ▼
Proxmox VE
      │
      ▼
Proxmox Backup Server

Backup VM полезен для быстрого полного восстановления, но не заменяет логический dump PostgreSQL.

Мониторинг

Минимальный набор проверок:

Dendrite

systemctl status dendrite

PostgreSQL

systemctl status postgresql

Coturn

systemctl status coturn

Matrix API

curl -s \
https://chat.ramba-art.ru/_matrix/client/versions

TURN

curl -s \
https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer

Media storage

df -h
mount | grep matrix

Диагностика

Dendrite не запускается

systemctl status dendrite
journalctl -u dendrite -n 100 --no-pager

Matrix API недоступен

Проверяем цепочку:

Client
  │
  ▼
DNS
  │
  ▼
BrainyCP
  │
  ▼
Nginx
  │
  ▼
Dendrite

Проверяем внешний адрес:

curl -Iv https://chat.ramba-art.ru/

И backend непосредственно из LAN:

curl -I http://MATRIX_BACKEND_IP:8008/

Звонок соединяется без аудио

В первую очередь проверяем:

  • Coturn;
  • relay UDP range;
  • NAT;
  • `external-ip`;
  • firewall;
  • TURN credentials.

Проверяем:

ss -tulpn | grep turnserver

Не загружаются медиа

Проверяем:

mount | grep matrix
df -h
ls -ld /matrix-media

Также необходимо проверить права пользователя Dendrite на NFS.

Производительность

Основная нагрузка Matrix распределяется между:

CPU
 │
 ├── Dendrite
 ├── PostgreSQL
 └── Federation

RAM
 │
 ├── Dendrite
 └── PostgreSQL

Disk
 │
 ├── PostgreSQL
 └── Media

Network
 │
 ├── Federation
 ├── Media
 └── TURN

Для небольшого и среднего deployment особенно важны:

  • быстрый локальный диск PostgreSQL;
  • достаточный объём RAM;
  • стабильное сетевое подключение;
  • отдельное пространство для media store.

Масштабирование

Текущая архитектура намеренно проста:

1 VM
 │
 ├── Dendrite
 ├── PostgreSQL
 └── Coturn

По мере роста можно отдельно масштабировать:

  • PostgreSQL;
  • media store;
  • TURN;
  • reverse proxy;
  • мониторинг;
  • резервное копирование.

Media Store уже удобно отделять от системного диска через NFS.

Безопасность

Для RAMBA Matrix рекомендуется:

  • держать публичную регистрацию отключённой;
  • использовать E2EE;
  • не публиковать PostgreSQL;
  • не публиковать внутренний порт Dendrite;
  • не хранить секреты в Wiki;
  • регулярно менять административные пароли;
  • ограничивать SSH;
  • резервировать `matrix_key.pem`;
  • хранить backup вне основной VM;
  • обновлять Dendrite, PostgreSQL, Element и Coturn;
  • проверять журналы после обновлений.

Полезные команды

Задача Команда
Статус Dendrite systemctl status dendrite
Перезапуск Dendrite systemctl restart dendrite
Логи Dendrite journalctl -u dendrite -f
Статус PostgreSQL systemctl status postgresql
Статус Coturn systemctl status coturn
Проверить Matrix API curl -s https://chat.ramba-art.ru/_matrix/client/versions
Проверить TURN curl -s https://chat.ramba-art.ru/_matrix/client/v3/voip/turnServer
Проверить NFS grep matrix
Проверить диск df -h

Итоговая схема

                        USERS
                          │
             ┌────────────┴────────────┐
             │                         │
             ▼                         ▼
       Element Web               Element Mobile
             │                         │
             └────────────┬────────────┘
                          │
                          │ HTTPS
                          ▼
                 ┌─────────────────┐
                 │     BrainyCP    │
                 │      Nginx      │
                 │       SSL       │
                 └────────┬────────┘
                          │
                          ▼
                 ┌─────────────────┐
                 │    Dendrite     │
                 └──────┬─────┬────┘
                        │     │
                        │     └──────────────┐
                        ▼                    ▼
                  PostgreSQL              Coturn
                        │                    │
                        │                    ▼
                        │               TURN Relay
                        │
                        ▼
                   Local Disk

                    Media API
                        │
                        ▼
                    OMV / NFS

Результат

RAMBA Matrix представляет собой полностью самостоятельную коммуникационную платформу, работающую на инфраструктуре RAMBA ART.

Система обеспечивает:

  • собственные Matrix ID;
  • личные и групповые чаты;
  • E2EE;
  • Android и iOS;
  • Element Web;
  • голосовые звонки;
  • видеозвонки;
  • собственное хранение данных;
  • резервное копирование;
  • федерацию;
  • возможность дальнейшего масштабирования.

При этом публичный веб-уровень, Matrix backend, база данных и media store разделены между отдельными компонентами инфраструктуры.

См. также

Внешние ссылки