Делаем общение для семьи в сети matrix

И так, мы уже узнали про matrix, что мы хотим иметь Element, и чего это нам будет стоить в деньгах. Переходим к самой увлекательной и развлекательной части. А именно, настраиваем свой сервер общения для всей семьи.

Вообще, я считаю, что кто-то хоть как-то мало-мальски знакомый с IT-технологиями, способен «построить» для своей семьи уголок общения. А технология сети matrix позволит пообщаться и с другой семьёй. И никакого обременения в обязанностях хранить и обрабатывать персональные данные. Сами дальше всё придумаете. И так… «задание на выходные» — начинаем развёртывание Matrix Synapse.

По тексту указано YOU-DOMAIN, это как сами догадались заменить на имя вашего домена, который у вас есть или вы зарегистрируете. Делать на простых IP-адресах не так уж и красиво, но кому как.

Архитектура:

  • Сервер А (YOU-DOMAIN.ru): Только веб-сервер (Nginx) для .well-known и редиректов. SSL для основного домена.
  • Сервер Б (meet.YOU-DOMAIN.ru): Synapse, Postgres, Coturn, Nginx (Proxy). SSL для поддомена. Находится за NAT (требуется проброс портов).

1. Сервер А (YOU-DOMAIN.ru) — Делегирование

Задача: сказать миру, что матрица живёт на meet.YOU-DOMAIN.ru.

  1. Установите Nginx и Certbot:
    apt update && apt install -y nginx certbot python3-certbot-nginx
  2. Получите SSL сертификат:
    certbot --nginx -d YOU-DOMAIN.ru
  3. Настройте Nginx (/etc/nginx/sites-available/YOU-DOMAIN.ru):server {
    listen 80;
    listen 443 ssl;
    server_name YOU-DOMAIN.ru;
    ssl_certificate /etc/letsencrypt/live/YOU-DOMAIN.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/YOU-DOMAIN.ru/privkey.pem;

    location /.well-known/matrix/server {
    default_type application/json;
    return 200 '{"m.server": "meet.YOU-DOMAIN.ru:8448"}';
    }
    location /.well-known/matrix/client {
    default_type application/json;
    return 200 '{"m.homeserver": {"base_url": "https://meet.YOU-DOMAIN.ru"}}';
    }
    location / { return 404; }
    }
  4. Проверка: https://YOU-DOMAIN.ru/.well-known/matrix/server должен возвращать JSON.

2. Сервер Б (meet.YOU-DOMAIN.ru) — Основной сервер

Задача: Хостинг сервисов. Если за NAT, пробросьте порты на локальный IP сервера.

2.1. Подготовка и Docker

sudo -i
apt update && apt full-upgrade -y
apt install -y curl ufw nginx certbot python3-certbot-nginx
curl -fsSL https://get.docker.com | sh
usermod -aG docker root
apt install -y docker-compose-plugin

2.2. Структура и права

mkdir -p /opt/matrix/{synapse-data,coturn,nginx,well-known/matrix}
chown -R root:root /opt/matrix
chmod 755 /opt/matrix
chmod 700 /opt/matrix/synapse-data

2.3. Генерация конфига Synapse

cd /opt/matrix
docker run -it --rm \
-v /opt/matrix/synapse-data:/data \
-e SYNAPSE_SERVER_NAME=YOU-DOMAIN.ru \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate

2.4. Настройка homeserver.yaml

Отредактируйте /opt/matrix/synapse-data/homeserver.yaml. Права: 600. Критичные секции (найти и заменить):

server_name: "YOU-DOMAIN.ru"
public_baseurl: "https://meet.YOU-DOMAIN.ru"

# Включить слушание порта 8008 внутри контейнера (по умолчанию есть)
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false

# Настройка TURN (Coturn)
turn_uris:
- "turn:meet.YOU-DOMAIN.ru:3478?transport=udp"
- "turn:meet.YOU-DOMAIN.ru:3478?transport=tcp"
- "turns:meet.YOU-DOMAIN.ru:5349?transport=udp"
- "turns:meet.YOU-DOMAIN.ru:5349?transport=tcp"
turn_shared_secret: "VERY_LONG_RANDOM_SECRET_STRING" # Сгенерируйте (openssl rand -hex 32)
turn_user_lifetime: 1h

2.5. Docker Compose (/opt/matrix/docker-compose.yml)

Права: 600. Минимальный рабочий вариант.

version: '3.8'
services:
postgres:
  image: postgres:15-alpine
  container_name: postgres
  environment:
    POSTGRES_USER: synapse_user
    POSTGRES_PASSWORD: VERY_HARD_DB_PASSWORD
    POSTGRES_DB: synapse
  volumes:
    - ./postgres-data:/var/lib/postgresql/data
  networks:
    - matrix-net
  restart: unless-stopped

synapse:
  image: matrixdotorg/synapse:latest
  container_name: synapse
  depends_on:
    - postgres
  volumes:
    - ./synapse-data:/data
  networks:
    - matrix-net
  restart: unless-stopped

coturn:
  image: coturn/coturn
  container_name: coturn
  network_mode: "host" # Важно для UDP производительности
  volumes:
    - ./coturn/turnserver.conf:/etc/turnserver.conf:ro
    - /etc/letsencrypt:/etc/letsencrypt:ro
  restart: unless-stopped

networks:
matrix-net:
  driver: bridge

2.6. Настройка Coturn

Файл /opt/matrix/coturn/turnserver.conf. Права: 600.

listening-port=3478
tls-listening-port=5349
listening-ip=0.0.0.0
external-ip=ВАШ_ВНЕШНИЙ_IP_ИЛИ_DYN_DNS # Если за NAT, укажите внешний IP
realm=meet.YOU-DOMAIN.ru
server-name=meet.YOU-DOMAIN.ru
static-auth-secret=VERY_LONG_RANDOM_SECRET_STRING # Тот же, что в homeserver.yaml
cert=/etc/letsencrypt/live/meet.YOU-DOMAIN.ru/fullchain.pem
pkey=/etc/letsencrypt/live/meet.YOU-DOMAIN.ru/privkey.pem
no-cli
no-loopback-peers
no-multicast-peers

Проверка прав на сертификаты для Coturn:

# Certbot создаёт сертификаты с такими правами:
ls -la /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/

# privkey.pem должен быть 600 (читает только root)
# fullchain.pem должен быть 644

# Контейнер coturn запускается от root (из-за network_mode: host)
# поэтому он сможет читать privkey.pem
chmod 600 /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/privkey.pem
chmod 644 /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/fullchain.pem

2.7. SSL на Сервере Б

Так как сервер за NAT, порт 80 должен быть проброшен на этот сервер для Certbot.

# Получите сертификат
certbot --nginx -d meet.YOU-DOMAIN.ru

# Certbot автоматически обновит сертификаты через cron
# Проверьте автообновление:
certbot renew --dry-run

2.8. Nginx Proxy (Сервер Б)

Проксирует запросы на контейнер Synapse (порт 8008).

server {
listen 80;
server_name meet.YOU-DOMAIN.ru;
location /.well-known/matrix/ { return 200 '{"m.server": "meet.YOU-DOMAIN.ru:8448"}'; default_type application/json; }
location / { return 301 https://$host$request_uri; }
}

server {
listen 443 ssl;
server_name meet.YOU-DOMAIN.ru;
ssl_certificate /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/privkey.pem;

location / {
proxy_pass http://localhost:8008;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
}

2.9. Проброс портов на роутере (NAT)

Если сервер за NAT, настройте Port Forwarding на роутере:

Внешний портВнутренний портПротоколНазначение
8080TCPCertbot (только для получения SSL)
443443TCPHTTPS (API, клиенты, веб)
84488448TCPФедерация Matrix (межсерверное общение)
34783478TCPCoturn (TURN over TCP)
34783478UDPCoturn (TURN over UDP)
53495349TCPCoturn (TURNS over TCP)
53495349UDPCoturn (TURNS over UDP)
49152-6553549152-65535UDPCoturn (медиа-трафик звонков/видео)

Важно: В настройках роутера укажите локальный IP-адрес сервера Б (например, 192.168.1.100) как целевой для всех этих портов.

2.10. Фаэрвол и Запуск

# Порты (если фаэрвол на самом сервере)
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 8448/tcp
ufw allow 3478/tcp
ufw allow 3478/udp
ufw allow 5349/tcp
ufw allow 5349/udp
ufw allow 49152:65535/udp
ufw reload

# Запуск
cd /opt/matrix
docker compose up -d postgres
sleep 10
docker compose up -d synapse coturn
docker compose ps

# Админ
docker exec -it synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml -u admin -p PASSWORD --admin

3. Проверки и Тесты

  1. Федерация:
  2. TURN (Звонки):
    • В клиенте Element: Настройки -> Помощь и поддержка -> Информация для отладки.
    • Раздел TURN servers: должен быть статус OK.
    • Если FAIL: проверьте external-ip в turnserver.conf и проброс портов на роутере.
  3. Права доступа (Чек-лист):
    • /opt/matrix/synapse-data/homeserver.yaml: 600 (root:root).
    • /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/privkey.pem: 600 (root:root).
    • /etc/letsencrypt/live/meet.YOU-DOMAIN.ru/fullchain.pem: 644 (root:root).
    • /opt/matrix/docker-compose.yml: 600 (root:root).
    • /opt/matrix/coturn/turnserver.conf: 600 (root:root).
    • Папки данных: 700 или 755.
  4. Автообновление SSL:# Certbot установит cron-задачу автоматически
    # Проверка:
    systemctl list-timers | grep certbot
    # Принудительное обновление:
    certbot renew
    # После обновления перезапустите coturn:
    docker compose restart coturn
  5. Логи для отладки:docker compose logs -f synapse
    docker compose logs -f coturn

Важно: При смене внешнего IP (если не статический) обновите external-ip в Coturn и перезапустите контейнер. Для статического IP за NAT убедитесь, что проброс портов (Port Forwarding) настроен на роутере точно на локальный IP сервера Б.

Ссылки