Развёртывание корпоративного мессенджера RAMBA MatrixПравить

Цель проектаПравить

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

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

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

Итоговая архитектураПравить

В проекте используется следующая схема:

Пользователь
  |
  | 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

Основные домены:

Назначение

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

@username:ramba-art.ru

Например:

@ivan_ivanov:ramba-art.ru

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

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

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

  • открытый протокол;
  • нет привязки к одному поставщику;
  • поддержка федерации между серверами;
  • поддержка сквозного шифрования;
  • есть готовые клиенты для Android, iOS, Web, Windows, Linux и macOS;
  • можно хранить данные на собственной инфраструктуре;
  • можно использовать собственный домен для пользователей.

Недостатки Matrix:

  • сложнее в администрировании, чем обычные SaaS-мессенджеры;
  • требуется следить за обновлениями;
  • требуется корректная настройка TURN/STUN для звонков;
  • требуется резервное копирование базы данных и медиафайлов;
  • при больших нагрузках нужно планировать ресурсы заранее.

Почему выбран DendriteПравить

В качестве homeserver выбран Dendrite.

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

Плюсы Dendrite:

  • низкое потребление памяти;
  • простая монолитная установка;
  • высокая скорость запуска;
  • удобная сборка из исходного кода;
  • хорошо подходит для собственного сервера организации;
  • использует PostgreSQL как основную базу данных.

Минусы Dendrite:

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

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

Почему выбран PostgreSQLПравить

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

Плюсы PostgreSQL:

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

Минусы PostgreSQL:

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

Вывод: PostgreSQL следует хранить на локальном диске VM, а не на NFS.

Почему выбран ElementПравить

Element выбран как основной клиент Matrix.

Используются:

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

Плюсы Element:

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

Минусы Element:

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

Почему выбран CoturnПравить

Coturn используется для аудио- и видеозвонков.

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

Плюсы Coturn:

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

Минусы Coturn:

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

В проекте используются порты:

3478/tcp
3478/udp
5349/tcp
49152-49252/udp

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

use-auth-secret
realm=ramba-art.ru
listening-ip=192.168.1.50
external-ip=195.138.232.82
fingerprint
lt-cred-mech

min-port=49152
max-port=49252

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

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

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

  • SSL-сертификаты управляются централизованно;
  • внешние домены обслуживаются в одном месте;
  • Dendrite и Element не публикуются напрямую;
  • проще управлять HTTPS;
  • можно разделить публичный фронт и внутренние сервисы.

Минусы:

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

Почему VM, а не LXCПравить

Для Matrix выбран вариант с отдельной VM в Proxmox.

Плюсы VM:

  • лучшая изоляция;
  • проще переносить между узлами Proxmox;
  • полноценная система с собственным ядром;
  • удобнее делать snapshot и backup;
  • меньше неожиданных ограничений, чем в LXC.

Минусы VM:

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

Вывод: для корпоративного мессенджера VM предпочтительнее, так как важнее надёжность и изоляция.

Развёртывание VMПравить

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

Ресурс

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

ramba-chat

IP VM:

192.168.1.50

Установка системных пакетовПравить

sudo apt update
sudo apt install -y git curl wget build-essential postgresql coturn nginx

Для сборки Dendrite также требуется Go.

Установка PostgreSQLПравить

Создаётся пользователь и база данных:

sudo -u postgres createuser dendrite
sudo -u postgres createdb -O dendrite dendrite
sudo -u postgres psql

Внутри psql задаётся пароль:

ALTER USER dendrite WITH PASSWORD 'strong_password';

Сборка DendriteПравить

cd /opt
sudo git clone https://github.com/matrix-org/dendrite.git
sudo chown -R $USER:$USER /opt/dendrite
cd /opt/dendrite

go build -o bin/dendrite ./cmd/dendrite
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

Генерация конфигурации DendriteПравить

cd /opt/dendrite

./bin/generate-keys --private-key matrix_key.pem

./bin/generate-config 
--server ramba-art.ru 
--db postgresql://dendrite:password@localhost/dendrite?sslmode=disable 
--private-key matrix_key.pem \

> dendrite.yaml
>
>

После генерации конфиг редактируется вручную.

Важные параметры:

global:
  server_name: ramba-art.ru

media_api:
base_path: media
max_file_size_bytes: 10485760

Systemd-сервис DendriteПравить

Создаётся файл:

sudo nano /etc/systemd/system/dendrite.service

Пример:

[Unit]
Description=Dendrite Matrix Server
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

Запуск:

sudo systemctl daemon-reload
sudo systemctl enable --now dendrite
sudo systemctl status dendrite

Настройка Reverse Proxy для DendriteПравить

На стороне BrainyCP/Nginx создаётся HTTPS-сайт:

chat.ramba-art.ru

Он проксирует запросы на:

http://192.168.1.50:8008

Важные заголовки:

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;

Настройка .well-knownПравить

Для красивых Matrix ID вида:

@user:ramba-art.ru

нужно настроить .well-known на основном домене.

Файл:

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

Содержимое:

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

Файл:

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

Содержимое:

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

Установка Element WebПравить

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

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:

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

Минусы:

  • нужен отдельный SSL-сертификат;
  • при проблемах с репутацией домена браузер может блокировать страницу.

Настройка CoturnПравить

Установка:

sudo apt install -y coturn

Включение сервиса:

sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn

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

listening-port=3478
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
static-auth-secret=SECRET
realm=ramba-art.ru

fingerprint
lt-cred-mech
no-multicast-peers
no-cli

min-port=49152
max-port=49252

Запуск:

sudo systemctl enable --now coturn
sudo systemctl status coturn

Настройка TURN в DendriteПравить

В dendrite.yaml указывается 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"

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

Проверка:

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

Если всё настроено правильно, сервер отдаёт временные TURN-креды.

Проброс портовПравить

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

Порт Протокол

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

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

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

  • регистрация закрыта;
  • пользователей создаёт администратор;
  • после первого входа пользователь меняет временный пароль.

Создание пользователя:

cd /opt/dendrite

./create-account 
--config dendrite.yaml 
--username username 
--password 'temporary_password'

Пример результата:

@username:ramba-art.ru

Плюсы закрытой регистрации:

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

Минусы:

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

МедиафайлыПравить

В Dendrite медиа хранятся в каталоге:

/opt/dendrite/media

В конфигурации:

media_api:
  base_path: media
  max_file_size_bytes: 10485760

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

10 MB

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

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

Рекомендации:

  • рабочие комнаты создавать с E2EE;
  • каталог media включить в резервное копирование;
  • при росте объёма вынести media на отдельное хранилище;
  • PostgreSQL не выносить на NFS.

Вариант выноса медиа на NFS/OMVПравить

Для роста системы можно вынести только медиафайлы на OMV NFS.

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

VM ramba-chat
  |-- PostgreSQL локально
  |-- Dendrite локально
  |-- JetStream локально
  |-- /opt/dendrite/media -> NFS OMV

Плюсы:

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

Минусы:

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

Резервное копированиеПравить

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

PostgreSQL database dendrite
/opt/dendrite
/opt/dendrite/media
/etc/turnserver.conf
/etc/systemd/system/dendrite.service
Element config.json
Nginx/BrainyCP vhost-конфиги

Пример резервного копирования конфигов:

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

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

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

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

Проверка .well-known:

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

Проверка Matrix API:

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

Проверка Dendrite:

sudo systemctl status dendrite --no-pager
sudo journalctl -u dendrite -n 80 --no-pager

Проверка Coturn:

sudo systemctl status coturn --no-pager
sudo ss -tulpn | grep turnserver

Проверка TURN-кредов:

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

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

Финальный тест:

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

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

  • Dendrite;
  • Element;
  • WebRTC;
  • STUN;
  • TURN;
  • NAT traversal;
  • reverse proxy;
  • SSL.

Плюсы выбранной архитектурыПравить

  • полный контроль над данными;
  • собственные Matrix ID на домене ramba-art.ru;
  • независимость от сторонних SaaS-мессенджеров;
  • поддержка Android, iOS и Web;
  • поддержка аудио- и видеосвязи;
  • поддержка E2EE;
  • простая архитектура на одной VM;
  • PostgreSQL локально для надёжности;
  • медиа можно вынести на отдельное хранилище;
  • reverse proxy и SSL централизованы через BrainyCP.

Минусы выбранной архитектурыПравить

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

Рекомендации по эксплуатацииПравить

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

ИтогПравить

Выбранная архитектура подходит для собственного корпоративного мессенджера RAMBA.

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

Для текущего этапа архитектура считается рабочей. Дальнейшие улучшения:

  • автоматизация создания пользователей;
  • настройка регулярного backup;
  • вынос media store на OMV/NFS;
  • брендирование Element;
  • мониторинг сервисов;
  • исправление репутации домена в Google Safe Browsing.
MediaWiki Appliance - Powered by TurnKey Linux