====== Установка собственного matrix сервера ====== Данная статья описывает установку собственного сервера matrix, который будет работать в общей федеративной сети серверов матрикс, но к которому доступ клиентов будет только из сети yggdrasil. При этом все фишки типа "Персональных сообщений" и "Шифрованных комнат" также будут работать :!: **Если вам не нужна связность с другими серверами - ставьте сервер в режиме standalone и не мучайтесь** ===== Почему всё так сложно-то? ===== * Во первых **Matrix** является федеративной сетью. Т.е. подразумевается что каждый из серверов может напрямую общаться с другими, при этом никаких Relay серверов не предусмотрено. Т.е. сервер должен иметь "белый" адрес (заметка на полях - людей, у которых есть **только** "белый" IPv6 адрес, ждут примерно аналогичные страдания). * Во вторых **обязательно** используются SSL сертификаты. * Соответственно, в третьих, **обязательно** используются "белые" домены (т.е. домены, на который такой сертификат может быть выписан). То есть, если вы хотите поднять сервер, который будет иметь возможность общаться с другими серверами в сети - он должен соответствовать этим трём требованиям. К счастью, предусмотрена ситуация когда есть домен **example.com** но сервер разместить под этим именем возможности нет. Зато есть возможность разместить его под именем **server.example.com**. Вот, собственно, этой возможностью мы и воспользуемся. ===== Требуемые инструменты и материалы ===== И так, что нам потребуется: ==== Сервер ==== Ну, собственно, потребуется машина для установки самого сервера Matrix. У этой машины должен быть выход в клирнет. Доступ к этой машине нужен только со стороны прокси, т.е. она вполне может сидеть где-то внедрах сети за NAT. ==== Домен ==== Домен может быть любым, который Вам доступен. Главное - он должен быть "белым" (т.е. резолвиться из клирнета) и у Вас должна быть возможность вносить туда записи. Я использовал для этого **twinkle.ygg.at** Так же Вам потребуется имя для прокси сервера с белым адресом. Если вы использовали как основной домен **.ygg.at** вас ждёт неприятность - в этом домене нельзя указать какой либо IP кроме yggdrasil. Если вы используете что-то типа **mybestowndomain.com** - вам никто не мешает сделать для этого имя **server.mybestowndomain.com**. Я использовал **ygg.twinkle.lol** ==== "Серый" (ygg) адрес ==== Этот адрес дожен быть прописан на основном домене, который вы выбрали в прошлом пункте. У меня это **300:dada:feda:f443::12** ==== Белый IP адрес ==== Этот адрес должен быть назначен как "внешний" на прокси сервере. Никаких особенных требований, ну кроме того, что как минимум должен быть открыты порты 443 и 8448 на вход. У меня это **193.111.115.214** ==== SSL сертификат ==== Так как у нас на основном домене используется "серый" адрес, получить SSL по простому - не получится. Нужно будет получать через "DNS авторизацию". Я пользуюсь для этого вот этим [[https://github.com/joohoi/acme-dns-certbot-joohoi/|плагином для certbot]]. ^:!: ВАЖНО^ |Если вы будете пользоваться этим плагином - он вам выведет строчку, которую нужно прописать в DNS. Если, при этом, вы пользуетесь доменом **.ygg.at**, при прописывании его в Alfis от имени оставьте только **_acme-challenge** а в самом CNAME уберите последнюю точку (должно получиться **.auth.acme-dns.io** в конце). От этой точки alfis шизеет.| ===== Собираем всё в кучу ===== * Ставим сервер Matrix. Подробности я опущу - весь интернет завален описанием этой процедуры * Прописываем для основного домена "серый" IP адрес. * Прописываем для прокси "белый" IP адрес. * Получаем тем или иным способом SSL сертификат на основной домен. * :!: **Не обязательно, но лучше сделать** - получаем SSL сертификат на прокси сервер. Я ниже расскажу зачем. * Добавляем в основной домен такие строки (у Вас они, понятно, будут другие): _matrix._tcp SRV 1 1 8448 ygg.twinkle.lol _matrix-fed._tcp SRV 1 1 8448 ygg.twinkle.lol Обратите внимание, тут должно быть указанно именно имя а не адрес. Именно по этому у прокси сервера должно быть имя. Почему их две? Потому что первая - depricated. * Настраиваем прокси сервер. Нам нужно прописать конфиг для двух хостнеймов, основного и прокси. У меня это выглядит так (у меня nginx, если у Вас что-то другое - делайте по аналогии): Основной домен server { listen [300:dada:feda:f443::12]:443 ssl; listen [300:dada:feda:f443::12]:8448 ssl; server_name twinkle.ygg.at; ssl_certificate /etc/letsencrypt/live/twinkle.ygg.at/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/twinkle.ygg.at/privkey.pem; client_max_body_size 1000M; location /_matrix { proxy_pass http://127.0.0.1:8008; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; client_max_body_size 500M; } location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://twinkle.ygg.at"}}'; add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; } } server { listen 193.111.115.214:443 ssl; listen 193.111.115.214:8448 ssl; server_name twinkle.ygg.at; ssl_certificate /etc/letsencrypt/live/twinkle.ygg.at/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/twinkle.ygg.at/privkey.pem; client_max_body_size 1000M; location /_matrix/client { return 404; } location /_matrix { proxy_pass http://127.0.0.1:8008; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; client_max_body_size 500M; } location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://twinkle.ygg.at"}}'; add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; } } Прокси: server { listen 193.111.115.214:443 ssl; listen 193.111.115.214:8448 ssl; listen [300:dada:feda:f443::12]:443 ssl; listen [300:dada:feda:f443::12]:8448 ssl; server_name ygg.twinkle.lol; ssl_certificate /etc/letsencrypt/live/ygg.twinkle.lol/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ygg.twinkle.lol/privkey.pem; client_max_body_size 1000M; location /_matrix/client/ { return 404; } location /_matrix { proxy_pass http://[322:a76c:9a9e:5085:1::8]:8008; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; client_max_body_size 500M; } location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://twinkle.ygg.at"}}'; add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; } } Собственно - на этом можно было-бы ставить точку. **Правильно собранное устройство в дополнительной настройке не нуждается.** Но я обещал рассказать зачем SSL на имя прокси, да и вобще стоит описать происходящее. И так... ===== Как оно должно работать в идеальной стране розовых пони ===== Сервер приходит в домен twinkle.ygg.at за srv записью, получает её и идёт на прокси сервер ygg.twinkle.lol (с основным доменом в урле, кстати, а вовсе не с проксёвым). И дальше сервера спокойно между собой общаются. Соответственно на прокси не должен никто приходить с его именем. Клиент из белой сети приходит в домен twinkle.ygg.at, получает ygg адрес и плача уходит. Клиент из ygg приходит в домен twinkle.ygg.at, получает ygg адрес и радостно работает. ===== Как оно работает на самом деле ===== Сервер приходит в домен twinkle.ygg.at и сначала пытается получить **/.well-known/matrix/server**. Не может. Пытается получить новый вариант SRV. Если не может - пытается получить старый. Дальше он идёт на указанный прокси, и общается с ним, в основном, по правильному имени основного домена. Но иногда, некоторые серверы, некоторые запросы шлют на доменное имя прокси сервера. Именно по этому лучше получить SSL на это имя и обрабатывать запросы и на него. Но так как мы не хотим, что-бы клиенты из белой сети могли заходить на наш сервер - мы рубим на корню клиентское API. ---- Вот теперь - действительно всё. ~~DISCUSSION~~