Изменения
  • 13 авг. 2025

    • Добавлено: Установка TURN сервера (Coturn)

Введение

Это именно то о чем вы думаете. Вам не придется покупать дорогой VPS для хостинга Matrix. Достаточно простого VPS и средне-мощного ПК прямо у вас дома.

📝
Обратите внимание статья написана с инструкциями на примере Linux (Debian) и с использованием Docker.

О Matrix

Matrix – это открытый протокол для обмена сообщениями в реальном времени. Проект был запущен в 2014 году командой из компании Amdocs 1 . Протокол определяет модель событий, формат данных и API для обмена сообщениями между клиентами и серверами, а также для их федерации, то есть взаимодействия между собой.

Для передачи данных Matrix использует стандартные транспорты, такие как HTTP/HTTPS, WebSockets и WebRTC. События и сообщения представлены в формате JSON и передаются через REST-подобные интерфейсы.

Главная особенность Matrix – это его федеративная и децентрализованная архитектура 1 . Множество серверов могут объединяться в единую открытую федерацию, что устраняет зависимость от одного центрального узла и обеспечивает гибкость развертывания.

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

Для защиты данных Matrix использует сквозное шифрование (E2E). При включенном шифровании содержимое сообщений хранится на серверах в зашифрованном виде, и только участники чата с соответствующими ключами могут его расшифровать. При этом серверы видят служебную информацию, такую как метаданные и состав комнат.

Matrix используется как частными лицами, так и организациями, включая корпоративный и государственный сектор. Например, решения на базе Matrix применяются в вооруженных силах 3 и системе здравоохранения Германии 4 .

Matrix это Synapse?

Matrix это не программа, это протокол, набор правил, экосистема. Фактически чат работает на Synapse, но есть и другие, например Dendrite.

Подобно тому как электронная почта работает на основе протоколов IMAP/SMTP, Matrix определяет, как клиенты и сервера должны обмениваться данными. Это позволяет разным серверам и клиентам работать вместе.

Что будем делать?

Захостим Matrix мессенджер на домашнем ПК с динамическим IP, который будет доступен в интернете через VPS.

Synapse довольно требователен к железу (зависит от кол-ва юзеров), особенно в контексте дискового пространства (медиа файлы), и подходящий VPS/VDS будет не дешевым. Поэтому я покажу как поднять Matrix именно на домашнем ПК/сервере с конфигурацией заточенной под Pangolin.

Что понадобится:

  • Домашний сервер, >2 CPU & RAM, и побольше дискового пространства
  • Дешевый VPS, >=1 CPU & RAM, желательно с каналом пошире (>=1 Gbit)
  • Доменное имя

Ну и в идеале базовые знания Linux, Docker, настройки DNS и знание Pangolin.

Подразумевается что вы уже установили, настроили Pangolin и проверили что все работает, но если нет:

Установка Pangolin
Хотели мощный VPS/VDS, но нету денег? Проблемы с NAT? Есть решение!

В данной статье я покажу как поднять и Synapse и Element. Element нужен чтобы была некая страница (frontend, клиент) где юзеры прямо в браузере могли бы зарегистрировать аккаунт и/или войти в аккаунт, а так же чтобы была совместимость с клиентами Element и в целом Matrix можно было бы пользоваться прямо в браузере без программ.

Два отдельных сервиса, Synapse и Element. Их можно повесить на два разных домена/поддомена, но могут возникнуть проблемы, Element в некоторых сценариях будет обращаться к домену на котором он работает, но на нем НЕ работает Synapse, поэтому будет куча ошибок.

Чтобы элегантно это решить, мы будем использовать сеть внутри Docker, и использовать Nginx чтобы сделать reverse proxy на localhost, который уже будет пробрасываться через Pangolin.

Типо такого:

services:
  synapse and etc:
    networks:
      m_network:
        ipv4_address: 10.10.10.X

  reverse-proxy:
    ports:
      - "4100:80"
    networks:
      m_network:
        ipv4_address: 10.10.10.X

networks:
  m_network:
    ipam:
      driver: default
      config:
        - subnet: "10.10.10.0/24"
# Synapse API
location ~ ^(/_matrix|/_synapse/client) {
    ...
}

# Element
location / {
    ...
}

Контейнеры общаются между собой в своей Docker сети, весь внешний трафик входит через nginx, который работает на 4100 порту и хост которого пробрасывается через Pangolin.

Установка Matrix

📝
Synapse по умолчанию использует sqlite, (личное мнение) это совсем не очень хороший выбор базы данных, поэтому будем использовать PostgreSQL.
💡
Я подготовил все конфиги необходимые для базового старта Matrix. Если вы будете что-то менять, что не описано в тексте ниже, делайте это внимательно.

Установка Docker:

1
sudo sh -c 'curl -fsSL https://get.docker.com -o get-docker.sh && sh ./get-docker.sh && rm -f get-docker.sh'

Клонирование репозитория с приготовленными конфигами:

1
git clone https://github.com/nozsh/matrix-element-pangolin-conf matrix && cd matrix

Создание конфигурации Synapse (homeserver.yaml):

1
sudo docker compose run --rm -e SYNAPSE_SERVER_NAME=domain.org -e SYNAPSE_REPORT_STATS=no synapse generate

Где domain.org ваш домен или поддомен, на него должно/будет указывать DNS запись на ваш VPS сервер на котором установлен Pangolin.

Редактирование конфига, например через nano 5 :

1
nano synapse/homeserver.yaml

В самый конец нужно добавить:

1
2
enable_registration: true
enable_registration_without_verification: true
  • enable_registration - включает регистрацию.
  • enable_registration_without_verification - отключает предупреждения если нету никакой защиты типа капчи.

Установить пароль для базы данных:

1
cp example.env .env && nano .env

Если строка содержит спец. символы убедитесь что все нормально:

1
sudo docker compose config

Переменная POSTGRES_PASSWORD должна содержать ту же строку что вы туда и положили (в “.env”).

Дальше нужно поменять базу данных на PostgreSQL. Из “homeserver.yaml.example” скопируйте конфигурацию database и замените в вашем “homeserver.yaml”:

1
2
database:
  ...

Не забудьте установить “password” такой же, какой вы установили в “.env”.

Редактирование конфига Element:

1
nano element-config.json

В base_url ваш домен с протоколом и без “/” в конце. Используйте “https”, Pangolin сам работает с SSL сертификатами.

"disable_custom_urls": true - запрещает использовать НЕ ваш Matrix сервер, иначе можно будет использовать другой Matrix сервер через ваш Element instance.

Аналогично:

1
nano wellknown/matrix/client

И так же:

1
nano nginx/default.conf

Поменяйте server_name domain.org на ваш домен.

Далее нужно раскомментировать две строки в “docker-compose.yaml”:

1
nano docker-compose.yaml
1
2
3
4
5
#    depends_on:
#      - synapse_db
        
    depends_on:
      - synapse_db
💡
Некоторые вещи из “Дополнительно” желательно сделать до запуска.

Запуск:

1
sudo sh -c 'docker compose down && docker compose up -d --force-recreate && docker compose logs -f'

Element должен открываться по ip:port (в конфиге 4100) и домену если вы уже настроили Pangolin.

Дополнительно

🚧
Это доп. инструкции для людей которые чего-то хотят и понимают что именно и как именно хотят. Если вы не знаете надо ли оно вам, или не понимаете о чем речь – не делайте этого.

Отключение федерации

homeserver.yaml:

1
federation_domain_whitelist: []

Подключение Google reCaptcha

Создать ключи тут (v2, “I’m not a robot”).

homeserver.yaml:

1
2
3
4
5
enable_registration_without_verification: false

recaptcha_public_key: "x"
recaptcha_private_key: "x"
enable_registration_captcha: true

Разделение хранилища

Есть SSD и HDD, оба LVM, нужно сделать так, чтобы был отдельный логический том SSD диска для БД Synapse и отдельный логический том HDD для медиа файлов, а сам Docker контейнер работал в home/root.

Это рабочий пример, где “vg0” ваш Volume Group, где sda1 и nvme0n1 ваши диски:

1
2
3
4
5
6
7
sudo lvcreate -L 10G -n synapse-1-media vg0 /dev/sda1
sudo mkfs.ext4 /dev/vg0/synapse-1-media
sudo mkdir -p /mnt/synapse-1-media
sudo mount /dev/vg0/synapse-1-media /mnt/synapse-1-media
sudo su
echo "/dev/vg0/synapse-1-media /mnt/synapse-1-media ext4 defaults 0 2" >> /etc/fstab
exit
1
2
3
4
5
6
7
sudo lvcreate -L 10G -n synapse-1-db vg0 /dev/nvme0n1p3
sudo mkfs.ext4 /dev/vg0/synapse-1-db
sudo mkdir -p /mnt/synapse-1-db
sudo mount /dev/vg0/synapse-1-db /mnt/synapse-1-db
sudo su
echo "/dev/vg0/synapse-1-db /mnt/synapse-1-db ext4 defaults 0 2" >> /etc/fstab
exit
1
sudo sh -c 'mkdir -p /mnt/synapse-1-media/data && mkdir -p /mnt/synapse-1-db/data'

Права:

1
chown -R 1000:1000 /mnt/synapse-1-media

Потому что docker-compose.yaml:

1
2
3
4
synapse:
  environment:
    - UID=1000
    - GID=1000

На “synapse-1-db” тоже нужно будет установить владельца и группу, если:

1
sudo docker run --rm postgres id

покажет не:

1
uid=0(root) gid=0(root) groups=0(root)

docker-compose.yaml:

1
2
3
4
5
6
7
8
synapse:
  volumes:
    - ./synapse:/data
    - /mnt/synapse-1-media/data:/media

synapse_db:
  volumes:
    - /mnt/synapse-1-db/data:/var/lib/postgresql/data

homeserver.yaml:

1
2
media_store_path: /media/data
uploads_path: /media/data/uploads

Путь получится “/data/data/”, в корень файлы лучше не записывать, потому что корень зачастую не пустой из-за “lost+found” (зависит от файловой системы). А программа может требовать чтобы директория была пуста, так например требует PostgreSQL, к тому же зачем смешивать файлы.

Не красиво, но точно будет работать.

Максимальный размер загружаемых файлов (Max Upload Size)

homeserver.yaml:

1
max_upload_size: 500M

nginx:

1
client_max_body_size 500M;

Другие размеры миниатюр

Может работать некорректно, или не работать вовсе. Лично у меня не работало и сломало аватарки.

homeserver.yaml:

1
2
3
4
thumbnail_sizes:
  - width: 320
    height: 240
    method: scale # OR crop

В любом случае миниатюры обычно создаются сами.

Подробнее.

Удаление “старых” медиа файлов

Это может не работать:

homeserver.yaml:

1
2
3
media_retention:
  local_media_lifetime: 90d   # медиа от пользователей
  remote_media_lifetime: 14d  # медиа с других серверов (федерация)

100% рабочий вариант через API:

Создать админ аккаунт – см. Synapse Admin.

Получить токен:

1
URL="http://10.10.10.2:8008"; USER="@admin:domain.org"; PASS='abrakadabra'; curl -X POST "$URL/_matrix/client/v3/login" -H "Content-Type: application/json" -d "{\"type\":\"m.login.password\",\"user\":\"$USER\",\"password\":\"$PASS\"}"

Удалить все что старше 1 минуты (60000 в мс):

1
BEFORE_TS=$(($(date +%s%3N) - 60000)); URL="http://10.10.10.2:8008"; TOKEN="token"; curl -X POST -H "Authorization: Bearer $TOKEN" "$URL/_synapse/admin/v1/media/delete?before_ts=$BEFORE_TS"

Или в одну команду, получить токен, выполнить удаление, отозвать токен:

1
URL="http://10.10.10.2:8008"; USER="@admin:domain.org"; PASS='abrakadabra'; DELAFTERMS=60000; LOGIN_RESP=$(curl -s -X POST "$URL/_matrix/client/v3/login" -H "Content-Type: application/json" -d "{\"type\":\"m.login.password\",\"user\":\"$USER\",\"password\":\"$PASS\"}"); echo "Login response: $LOGIN_RESP"; TOKEN=$(echo "$LOGIN_RESP" | grep -oP '"access_token":"\K[^"]+'); BEFORE_TS=$(($(date +%s%3N) - DELAFTERMS)); curl -X POST -H "Authorization: Bearer $TOKEN" "$URL/_synapse/admin/v1/media/delete?before_ts=$BEFORE_TS"; curl -X POST "$URL/_matrix/client/v3/logout" -H "Authorization: Bearer $TOKEN"

Или скриптом. И сделать cron задачу, типо такого:

1
2
crontab -e
0 0 1 * * >.../matrix/utilities/media-cleanup.log; bash .../matrix/utilities/media-cleanup.sh >> .../matrix/utilities/media-cleanup.log 2>&1

Будет запускать скрипт каждые 30 дней в 00:00.

📝
Обратите внимание, способ через API не удаляет аватарки, только любой загруженный пользователями контент в чатах - фото, видео, архивы и прочие файлы.

Synapse Admin (админка)

Админку можно запускать где угодно, необязательно пробрасывать в Pangolin, более того, лично я не рекомендую этого делать для безопасности (и это невозможно с конфигурацией из этой статьи (из-за конфигурации nginx)).

Админка от Awesome-Technologies:

1
2
3
4
5
6
7
8
services:
  synapse-admin:
    container_name: synapse-admin
    hostname: synapse-admin
    image: awesometechnologies/synapse-admin:latest
    ports:
      - "4200:80"
    restart: unless-stopped

Админка от etkecc:

1
image: ghcr.io/etkecc/synapse-admin:latest

Создать админ аккаунт:

1
sudo docker exec matrix-synapse-1 register_new_matrix_user -u admin -p 'abrakadabra' -a -c /data/homeserver.yaml http://localhost:8008

SSH туннель:

1
ssh -p 22 -N -L 127.0.0.1:8008:10.10.10.2:8008 user@ip

“10.10.10.2” ip Synapse:

1
2
3
4
synapse:
  networks:
    m_network:
      ipv4_address: 10.10.10.2

Порт 8008 - это порт Synapse по умолчанию.

Мосты

Telegram

В существующем docker-compose.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
mautrix-telegram:
    image: dock.mau.dev/mautrix/telegram:latest
    container_name: mautrix-telegram
    restart: unless-stopped
    volumes:
      - ./mautrix-telegram:/data
    networks:
      m_network:
        ipv4_address: 10.10.10.6
    depends_on:
      - synapse
1
mkdir mautrix-telegram
1
sudo docker compose run --rm mautrix-telegram
1
sudo nano mautrix-telegram/config.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
address: http://synapse:8008
domain: domain.org
verify_ssl: false
appservice:
    address: http://mautrix-telegram:29317
    database: postgres://synapse:password@synapse_db/mautrix_telegram
#   postgres://username:password@hostname/dbname

...

telegram:
    # Get your own API keys at https://my.telegram.org/apps
    api_id: xyz
    api_hash: xyz

bridge:
    permissions:
        '*': relaybot
        domain.org: puppeting
#        domain.org: full
        '@admin:domain.org': admin
1
sudo docker compose exec synapse_db psql -U synapse -c "CREATE DATABASE mautrix_telegram WITH ENCODING='UTF8';"
1
sudo docker compose run --rm mautrix-telegram
1
cp mautrix-telegram/registration.yaml synapse/mautrix-telegram-registration.yaml
1
nano synapse/homeserver.yaml
1
2
app_service_config_files:
  - /data/mautrix-telegram-registration.yaml
1
sudo sh -c 'docker compose down && docker compose up -d --force-recreate && docker compose logs -f'

Подробнее.

Установка TURN сервера (Coturn)

TURN сервер лучше установить на VPS с публичным IP, можно рядом с Pangolin, все будет работать. В Pangolin для TURN сервера ничего добавлять и настраивать не нужно.

1
git clone https://github.com/nozsh/matrix-element-pangolin-conf coturn && cd coturn && mv extra/coturn . && find . -maxdepth 1 -not -name 'coturn' -not -name '.' -exec rm -rf {} + && mv coturn/* . && rm -rf coturn/

Открыть порты UFW (на всякий случай):

1
sudo sh -c 'ufw allow 3478/tcp && ufw allow 3478/udp && ufw allow 5349/tcp && ufw allow 5349/udp && ufw allow 59000:60100/udp && ufw status'
1
nano coturn.conf

Поменять external-ip, realm и server-name. А также данные user=test:test - логин:пароль.

Сертификаты можно получить через certbot, или в другом месте, например Cloudflare:

  • “cert.pem” - публичный ключ
  • “private.key” - приватный ключ
1
touch certs/cert.pem certs/private.key
1
docker compose up -d && docker compose logs -f --tail=200

homeserver.yaml:

1
2
3
4
5
6
7
8
9
turn_uris:
  - "turns:turn.domain.org:5349?transport=tcp"
  - "turns:turn.domain.org:5349?transport=udp"
  - "turn:turn.domain.org:3478?transport=tcp"
  - "turn:turn.domain.org:3478?transport=udp"

turn_username: "test"
turn_password: "test"
turn_allow_guests: true