Як розгорнути SimpleX SMP relay на VPS
Покрокове розгортання SimpleX SMP relay на VPS: pinned версія, fingerprint для клієнтів, порти, unprivileged user, backups, TLS і threat model.
Що робить self-hosted сервер SimpleX Chat
Щоб розгорнути self-hosted сервер SimpleX Chat, потрібно запустити на VPS один daemon: smp-server — relay для SMP (simplex messaging protocol). Він зберігає черги повідомлень, до яких ваші контакти записують повідомлення та з яких їх читають. Другий, необов’язковий daemon під назвою xftp-server ретранслює передавання файлів. Обидва компоненти походять з одного проєкту — simplexmq; кожен із них складається з одного бінарного файла, конфігураційного файла та журналу, доступного лише для додавання.
Цей матеріал призначений для оператора, а не для користувача застосунку. Relay не зберігає облікових записів, списків контактів або історії чатів. Він зберігає черги, деякі недоставлені ciphertext і сертифікат, який його ідентифікує. Від оператора потрібні доступність сервісу, невеликий обсяг дискового простору та обробка метаданих, що проходять через ваш сервер.
Усі команди, шляхи, порти та прапорці нижче взято з документації самого проєкту: сторінки про розміщення SMP server, сторінки XFTP server і документа про безпеку протоколу. Якщо певне число має значення, поруч із ним зазначено сторінку, з якої його взято.
Чому мережі без ідентифікаторів користувачів усе одно потрібні relay
У SimpleX немає імен користувачів, номерів телефонів і ідентифікаторів облікових записів. Контакт — це односпрямована черга: адреса на певному relay, куди одна сторона записує повідомлення, а інша їх зчитує. Два ваші контакти не мають спільного ідентифікатора, за яким сервер міг би встановити зв’язок між ними.
Однак ці черги мають десь зберігатися. Причина проста: два телефони рідко перебувають онлайн в одну й ту саму секунду. Щось має прийняти повідомлення зараз і зберігати його, доки інший пристрій не запитає його. У цьому полягає вся робота SMP relay. Це також означає, що два пристрої ніколи не підключаються один до одного, тому жоден із них не дізнається IP-адресу іншого. Натомість цей ризик бере на себе relay.
Ім’я хоста relay є частиною адреси черги, тому воно міститься в кожному посиланні-запрошенні, яке ви створюєте через цей relay. Пам’ятайте про це, коли читатимете модель загроз наприкінці.
Що relay може і чого не може бачити
Проєкт описує це як модель загроз у protocol/security.md. Її варто прочитати до встановлення, оскільки після виконання цього посібника relay буде під вашим контролем. Relay, зокрема повністю контрольований зловмисником, не може дізнатися вміст або тип повідомлень, непомітно додати, дублювати чи пошкодити окремі повідомлення або зламати наскрізне шифрування за допомогою активної атаки.
На цій самій сторінці перелічено, що relay може робити. Він може дізнатися, коли одержувач черги перебуває в мережі. Він може підрахувати кількість повідомлень, що проходять через чергу. Він може дізнатися IP-адресу одержувача. Він може видалити всі майбутні повідомлення з черги або повідомляти неправдивий стан цієї черги.
Отже, поділ чіткий. За конфіденційність відповідає клієнт, і self-hosting на неї не впливає. За метадані та доступність відповідає оператор relay, і self-hosting передає обидва ці аспекти під ваш контроль.
Що потрібно підготувати
- VPS з Ubuntu 22.04 або 24.04. Проєкт публікує release-бінарні файли, зібрані саме для цих двох версій, для x86-64 і aarch64.
- Доменне ім’я з A-записом, що вказує на VPS, а також AAAA-запис, якщо ви використовуєте IPv6. У документації як приклад наведено
smp1.example.com. - Доступ root або
sudoі відкритий другий сеанс SSH на час зміни налаштувань firewall. - Місце поза сервером для зберігання резервної копії, оскільки каталог конфігурації містить ідентифікаційні дані сервера.
На ARM-інстансі використовуйте asset aarch64 замість x86-64. Більше нічого в цьому посібнику змінювати не потрібно, а вибір між тарифами ARM і x86 VPS залежить від ціни та швидкості на одне ядро, а не від того, чи працює це програмне забезпечення.
Встановлюйте зафіксований реліз, а не "latest"
Проєкт надає скрипт встановлення, який завантажує поточний реліз і реєструє команду simplex-servers-update. Це працює. Але версію все одно слід зафіксувати: якщо бінарний файл relay змінюється без вашого контролю, під час збою неможливо точно визначити причину.
Станом на August 2026 поточний реліз simplexmq — v6.5.0, опублікований 29 April 2026. Перевірте сторінку релізів, щоб вибрати потрібний тег, і використовуйте цей тег у всіх наведених нижче командах.
sudo useradd -m smp
sudo install -d -o smp -g smp -m 755 /etc/opt/simplex /var/opt/simplexuseradd -m smp не встановлює пароль, тому ніхто не входить безпосередньо як smp. Створіть обидва каталоги самостійно перед виконанням будь-яких інших дій, оскільки /etc/opt належить root і має режим 755. Через це користувач smp не має місця для запису власного каталогу конфігурації.
VER=v6.5.0
curl -fL "https://github.com/simplex-chat/simplexmq/releases/download/$VER/smp-server-ubuntu-24_04-x86-64" -o /tmp/smp-server
sha256sum /tmp/smp-serverПорівняйте цей хеш із контрольними сумами SHA2-256, опублікованими в примітках до релізу для того самого тега. Проєкт також підписує контрольні суми релізів ключем SimpleX Chat FB44AF81A45BDE327319797C85107E357D4A17FC, описаним на сторінці сервера. Це дає змогу перевірити підпис, а не довіряти сторінці, з якої ви отримали хеш.
sudo install -m 755 -o root -g root /tmp/smp-server /usr/local/bin/smp-serverНавмисно встановіть цей файл із власником root. Сервіс працює від імені smp, тому компрометація сервісу не дасть змоги перезаписати бінарний файл, з якого він запускається.
Ініціалізуйте сервер і збережіть два секрети, які він виведе
sudo su smp -c "smp-server init --yes --store-log --daily-stats --no-password --fqdn=smp1.example.com"--store-log(-l) записує журнал черг у режимі append-only до/var/opt/simplex/smp-server-store.log, тому relay переживає перезапуск. Без нього перезапуск видаляє всі черги, через що кожен контакт, маршрутизований через ваш relay, перестає працювати.--daily-stats(-s) записує лічильники у форматі CSV до/var/opt/simplex/smp-server-stats.daily.log.--fqdnдодає ваш домен до згенерованого сертифіката. Якщо у вас немає домену, використовуйте--ip.--no-passwordдозволяє будь-кому створювати чергу на вашому relay. Щоб зробити relay приватним, після init задайтеcreate_passwordпід[AUTH]у/etc/opt/simplex/smp-server.iniзамість передавання--passwordтут, оскільки командний рядок відображається в історії shell і у списку процесів під час виконання команди.
Init генерує сертифікат і виводить два значення, які потрібно зберегти. Перше — fingerprint, рядок у форматі base64, який також записується до /etc/opt/simplex/fingerprint. Друге — повна адреса сервера, що складається з fingerprint і вашого hostname. Скопіюйте обидва значення зараз.
Init також створює /etc/opt/simplex/ca.key. У документації зазначено, що цей файл потрібно перемістити до offline-сховища. Причина важлива: клієнти фіксують fingerprint цього центру сертифікації, тому будь-хто, хто має ca.key, може випустити новий сертифікат сервера, який ваші клієнти приймуть як ваш. Цей файл знадобиться лише для подальшої ротації сертифіката сервера за допомогою smp-server cert.
Вважайте init одноразовим кроком. Fingerprint у вашій адресі походить від згенерованого центру сертифікації. Тому повторна генерація цього центру створить іншу адресу й зробить недійсною адресу, яку ви вже надали.
Запустіть його через systemd від імені непривілейованого користувача
Запишіть /etc/systemd/system/smp-server.service саме так, як наведено в документації:
[Unit]
Description=SMP server systemd service
[Service]
User=smp
Group=smp
Type=simple
ExecStart=/usr/local/bin/smp-server start +RTS -N -RTS
ExecStopPost=/usr/bin/env sh -c '[ -e "/var/opt/simplex/smp-server-store.log" ] && cp "/var/opt/simplex/smp-server-store.log" "/var/opt/simplex/smp-server-store.log.bak"'
LimitNOFILE=65535
KillSignal=SIGINT
TimeoutStopSec=infinity
[Install]
WantedBy=multi-user.targetУ штатному unit-файлі також є AmbientCapabilities=CAP_NET_BIND_SERVICE. Цей рядок потрібен тому, що процес працює від імені smp, а порти з номерами менше 1024 недоступні процесу без прав root. Без цього daemon не зможе прив’язатися до портів 80 або 443. Додайте цей параметр, якщо обслуговуєте ці порти. LimitNOFILE=65535 важливий, оскільки кожен підписаний клієнт утримує відкрите TCP-з’єднання, а стандартний ліміт значно нижчий за потреби завантаженого relay. ExecStopPost копіює журнал store у файл .bak під час кожної зупинки. Це дає одну безкоштовну точку для відкату.
sudo systemctl daemon-reload
sudo systemctl enable --now smp-server
sudo systemctl status smp-server
sudo journalctl -fu smp-serverПід час успішного запуску в журналі з’являється адреса сервера. Потім переконайтеся, що сокети справді відкриті:
sudo ss -tlnp | grep -E ':(443|5223)'В обох рядках має бути зазначено smp-server. Запуск daemon від імені окремого облікового запису без прав sudo — це та сама практика, що описана в розділі окремі облікові записи для кожного сервісу на VPS. Вона не дає помилці в одному мережевому daemon перетворитися на root shell.
Які порти відкрити, а один залишити закритим
У документації перелічено три порти: 5223/tcp, 443/tcp і 80/tcp. Порт 5223 — це транспорт SMP. У конфігурації, що постачається, port: 5223,443 задано в [TRANSPORT], тому той самий протокол також відповідає на 443. Це важливо, оскільки багато мереж із суворими обмеженнями дозволяють вихідний трафік через 443 і блокують усі інші порти. Порт 80 потрібен лише для додаткової інформаційної сторінки та її перенаправлення на HTTPS.
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 5223/tcp
sudo ufw enableНе відкривайте 5224. Це порт керування. Документація звертається до нього локально з самого сервера за допомогою nc 127.0.0.1 5224. Він виводить стан сервера та видаляє черги, тому має бути доступним лише через loopback. Паролі адміністратора та користувача задаються в [AUTH]. Якщо ви ще не працювали з цим інструментом, у матеріалі основи ufw на VPS описано порядок правил і способи не втратити доступ до сервера.
Є ще один елемент керування, про який часто забувають. Більшість провайдерів запускають мережевий firewall у панелі керування окремо від ufw на сервері. Порт може бути відкритим у ufw, але трафік до нього все одно буде відкинуто до того, як він досягне сервера.
Адреса сервера, яка потрібна вашим клієнтам
smp://<fingerprint>[:<password>]@<public_hostname>[,<onion_hostname>]Цей рядок містить усю конфігурацію на боці клієнта. Вставте його в налаштування сервера в застосунку або запропонуйте користувачеві відсканувати QR-код, який застосунок відображає для цього рядка. У документації зазначено, що QR-код містить пароль. Тому користувач, який його відсканує, також зможе отримувати повідомлення через ваш сервер.
Є одна документована особливість, яка дивує всіх. Додавання вашого сервера в застосунку впливає лише на контакти, створені після цього. Наявні контакти залишаються на ретрансляторах, на яких було створено їхні черги, і не переносяться. Саме тому не можна вимкнути ретранслятор наступного дня після його заміни.
Додавання файлового ретранслятора XFTP
XFTP (простий протокол передавання файлів SimpleX) відповідає за передавання файлів у мережі. Це окремий daemon із власною адресою. Згідно з анонсом XFTP від проєкту, ретранслятори взагалі не бачать метаданих файлів. Вони бачать лише окремі частини розміром 256kb, 1mb або 4mb. Доступ до них авторизується анонімними обліковими даними. Відправник може розподілити частини одного файлу між кількома ретрансляторами. Тому ваш сервер зберігає частини, а не файли.
sudo useradd -m xftp
sudo install -d -o xftp -g xftp -m 755 /etc/opt/simplex-xftp /var/opt/simplex-xftp /srv/xftp
curl -fL "https://github.com/simplex-chat/simplexmq/releases/download/$VER/xftp-server-ubuntu-24_04-x86-64" -o /tmp/xftp-server
sudo install -m 755 -o root -g root /tmp/xftp-server /usr/local/bin/xftp-server
sudo su xftp -c "xftp-server init -l --fqdn=xftp1.example.com -q '20gb' -p /srv/xftp/"Конфігурація зберігається в /etc/opt/simplex-xftp/, стан — у /var/opt/simplex-xftp/, а частини файлів — у каталозі, який визначає -p. Unit systemd має таку саму структуру з User=xftp і ExecStart=/usr/local/bin/xftp-server start +RTS -N -RTS. Під час ініціалізації виводиться адреса xftp:// у тому самому форматі, що й адреса SMP, але з власним fingerprint у /etc/opt/simplex-xftp/fingerprint.
Потрібно врахувати конфлікт портів. Документований порт XFTP-сервера — 443, і конфігурація SMP також містить 443. Два процеси не можуть прослуховувати один і той самий порт на одній адресі. Тому на одному VPS потрібно змінити одну з прив’язок. Найпростіше встановити port: 5223 у секції [TRANSPORT] конфігурації SMP і залишити порт 443 файловому ретранслятору. Недолік цього варіанта — клієнти з мереж з обмеженнями втратять fallback через порт 443. Альтернативи — додаткова IP-адреса на тому самому VPS або окремий VPS.
Реалістично визначте квоту. -q '20gb' — це обсяг дискового простору, який ви фактично можете надати. Файловий ретранслятор споживає дисковий простір і пропускну здатність. Ретранслятор повідомлень майже не використовує ні те, ні інше.
Що зберігається на диску та що відновлює резервна копія
Важливі два каталоги. /etc/opt/simplex/ — це ідентифікаційні дані: smp-server.ini, сертифікат і ключ сервера, ca.key та fingerprint. /var/opt/simplex/ — це стан: у smp-server-store.log зберігаються черги, а коли restore_messages: on — недоставлені повідомлення, разом із файлом щоденної статистики.
sudo systemctl stop smp-server
sudo tar czf /root/simplex-backup.tgz -C / etc/opt/simplex var/opt/simplex
sudo chmod 600 /root/simplex-backup.tgz
sudo systemctl start smp-serverЧітко визначте, що містить цей архів. Це не архів повідомлень: елементи в черзі є шифротекстом для ключів, яких relay ніколи не зберігав, а конфігурація [STORE_LOG], що постачається разом із ним, у будь-якому разі видаляє повідомлення через 21 днів. Це копія ідентифікаційних даних сервера, включно з ca.key, тому будь-хто, хто отримає цей файл, зможе видати себе за ваш relay перед вашими контактами. Зашифруйте його та зберігайте за межами цього сервера.
Перевага проявляється під час відновлення. Поверніть /etc/opt/simplex на новий VPS і вкажіть на нього те саме DNS-ім’я. Відбиток залишиться незмінним, тому всі видані вами адреси й надалі працюватимуть. Якщо втратити цей каталог, відновлення неможливе: нова інсталяція означає новий відбиток, а це означає нову адресу. Усі контакти, маршрутизовані через ваш relay, буде втрачено.
TLS: два сертифікати для різних завдань
Транспорт SMP не використовує загальнодоступний центр сертифікації. Init створює приватний центр сертифікації та сертифікат сервера, а відбиток цього центру передається в адресі сервера. Клієнт порівнює дані, які надає сервер, із цим зафіксованим відбитком. Саме це, за описом проєкту, захищає з’єднання між клієнтом і сервером від атак machine-in-the-middle. На цьому порту не потрібно запускати клієнт ACME (automatic certificate management environment), а ротація виконується вручну за допомогою smp-server cert з установленим SMP_SERVER_CFG_PATH.
Необов’язкова інформаційна сторінка використовує інший сертифікат. У її розділі [WEB] зазначено static_path, https: 443, cert: /etc/opt/simplex/web.crt і key: /etc/opt/simplex/web.key. Браузер не знає про ваш приватний центр сертифікації, тому саме тут потрібен сертифікат, довірений публічними центрами сертифікації. У швидкому запуску Docker з документації перед сервером саме для цього використовується Caddy, який автоматично отримує сертифікат.
Доступ до relay через Tor
Документація містить розділ про Tor. У ньому Tor встановлюється з репозиторію Tor Project, а в /etc/tor/torrc додається hidden service:
SOCKSPort 0
HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1
HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443Уважно прочитайте два рядки режимів. Single hop і non-anonymous означають, що розташування самого relay не приховується. Onion-адреса забезпечує швидкий доступ і дає клієнтам змогу підключатися так, щоб їхня IP-адреса ніколи не розкривалася вам. Водночас сервер залишається доступним для пошуку за своєю публічною IP-адресою. Onion hostname з /var/lib/tor/simplex-smp/hostname додається в кінці адреси сервера після коми. Якщо потрібно приховати також розташування сервера, потрібна інша конфігурація. Її компроміси описано в розділі про запуск справжнього onion service на VPS. Відмінності між даними, які приховує кожен інструмент, розглянуто в порівнянні Tor і VPN. Тут вони безпосередньо застосовні.
Модель загроз: що змінює self-hosting
Що це дає. Метадані (які черги існують, коли їх читають і які адреси підключаються) зберігаються на машині під вашим контролем, а ви визначаєте, як довго їх зберігати. Ви також не входите до великої групи, дані якої можна отримати одним запитом.
Чого це не дає, якщо сказати прямо:
- Шифрування не змінюється. Повідомлення були зашифровані end-to-end до розгортання цього рішення і залишаються зашифрованими end-to-end після нього. Self-hosting — це рішення щодо метаданих, а не криптографії.
- Ваш VPS-провайдер бачить трафік до вашої IP-адреси та зберігає платіжні дані. Ви перенесли довіру від оператора системи обміну повідомленнями до хостинг-оператора. Ви її не усунули.
- Ваш relay — це невелика група користувачів. Якщо він обслуговує одне домогосподарство, підключення до нього ідентифікує це домогосподарство, а його hostname міститься в кожному invitation link, який ви надсилаєте через нього. Завантажений public relay краще приховує вас саме в цьому аспекті, і це є справжнім компромісом. Приватний search server має таку саму властивість. Тому питання що саме SearXNG приховує на вашому VPS зводиться до того, скільки людей користуються instance разом із вами.
- Доступність тепер залежить від вас. Заповнений диск або вимкнений сервер означає, що повідомлення перестануть доставлятися, а ваші контакти не зможуть обійти вас іншим маршрутом.
Та сама логіка застосовується до будь-якого private service, який ви розміщуєте на власному сервері, незалежно від того, чи це цей relay, чи WireGuard VPN на власному VPS. Ви визначаєте, яка сторона бачить метадані. Ви не робите їх невидимими.
Коли це не працює
Сервіс запускається й одразу зупиняється. Перегляньте sudo journalctl -u smp-server -n 50. Помилка прив’язування вказує порт, який не вдалося зайняти. Потім виконайте sudo ss -tlnp | grep :443, щоб визначити, який процес уже використовує цей порт. На щойно налаштованому сервері це зазвичай nginx, Caddy або XFTP server, який ви встановили годину тому.
Init не може записати конфігурацію. Якщо виконати smp-server init від імені користувача smp до появи /etc/opt/simplex, виникне помилка доступу, оскільки /etc/opt належить root. Спочатку створіть каталог із правильним власником, а потім повторно запустіть init.
Клієнти не можуть підключитися до relay. Перевірте, що ім’я розпізнається в правильну адресу, за допомогою dig +short smp1.example.com. Потім перевірте порт зі свого ноутбука, а не із сервера: nc -vz smp1.example.com 5223. Якщо зовнішнє підключення не працює, а ss показує, що socket відкритий на сервері, проблема, імовірно, у мережевому firewall провайдера. Це окремий засіб керування, не пов’язаний з ufw.
Контакт не може підключитися через ваш relay. Fingerprint в адресі, якою ви поділилися, має відповідати поточному вмісту /etc/opt/simplex/fingerprint. Якщо ви встановили create_password у [AUTH], адреса також має містити цей пароль. Інакше клієнту заборонено створювати queue.
Після додавання сервера в застосунку нічого не перемістилося. Це очікувана поведінка. Новий relay використовують лише нові контакти. Наявні контакти продовжують використовувати вже створені для них queue.
FAQ
Чи робить self-hosting SimpleX server мої повідомлення безпечнішими?
Ні, і це зроблено навмисно. SimpleX шифрує повідомлення наскрізно між пристроями, тому relay ніколи не має ключів, незалежно від того, хто ним керує. Self-hosting змінює того, хто спостерігає за метаданими цих повідомлень: які черги існують, коли їх читають і з яких IP-адрес встановлюють з’єднання. Це рішення щодо метаданих. Якщо причина self-hosting — сильніше шифрування, воно вже було доступне.
Що насправді може бачити оператор SimpleX relay?
Це описано в protocol/security.md проєкту. Relay не може читати вміст або типи повідомлень, непомітно змінювати окремі повідомлення чи зламати наскрізне шифрування за допомогою активної атаки. Він може бачити, коли отримувач черги перебуває онлайн, підраховувати повідомлення, що проходять через чергу, дізнатися IP-адресу отримувача, видаляти майбутні повідомлення з черги або повідомляти неправдивий стан цієї черги. Це повноваження, які ви отримуєте, коли relay належить вам.
Чи потрібні мені доменне ім’я та TLS-сертифікат?
Для придатної до використання конфігурації потрібен домен, а smp-server init приймає --ip, якщо у вас справді немає домену. Для порту обміну повідомленнями не потрібен сертифікат від публічного центру сертифікації: init створює власний центр сертифікації, а клієнт фіксує fingerprint, указаний у вашій адресі smp://. Сертифікат, якому довіряють публічні системи, потрібен лише для додаткової вебсторінки з інформацією, яку налаштовують як cert і key у розділі [WEB] файлу smp-server.ini.
Що станеться, якщо я втрачу /etc/opt/simplex?
Усі адреси, які ви надали, перестануть працювати. У цьому каталозі зберігається центр сертифікації, fingerprint якого вбудовано в адресу вашого сервера, тому після відновлення буде створено інший fingerprint і, відповідно, інший сервер. Контакти, чиї черги розміщені на цьому relay, не можна відновити на стороні клієнта. Створюйте резервну копію каталогу в зашифрованому вигляді та зберігайте її поза сервером. Також зберігайте ca.key офлайн, як рекомендовано в документації, оскільки той, хто має цей файл, може видати себе за ваш relay.
Чи можна запустити SMP relay і XFTP file relay на одному VPS?
Так, але потрібно усунути один конфлікт. Документований порт XFTP server — 443, а стандартна конфігурація SMP містить port: 5223,443, тому обидва сервіси намагаються використовувати той самий socket. Призначте порт 443 одному з них: задайте port: 5223 для SMP server або перенесіть file relay на другу IP-адресу чи на другий VPS. Також встановіть квоту сховища відповідно до фактичного обсягу диска, оскільки саме file relay споживає диск і пропускну здатність.