Files
Luma/Docs/PROSODY.md
wt 5c51bacc40
iOS CI / Build and Test SwiftUI App (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s
Update PROSODY.md
2026-08-10 17:55:37 +07:00

216 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Настройка Prosody для Luma
Ниже приведён ориентир для актуальных Prosody 0.12/13. Сохраните существующие
модули аутентификации, TLS и federation вашего сервера — пример показывает
только функции, необходимые клиенту.
```lua
VirtualHost "example.org"
modules_enabled = {
-- ваши базовые модули;
"roster"; -- RFC 6121: серверный список контактов
"pep"; -- PEP: OMEMO device lists/bundles и XEP-0084 аватары
"smacks"; -- XEP-0198
"carbons"; -- XEP-0280
"mam"; -- XEP-0313
"turn_external"; -- XEP-0215: STUN/TURN для Jingle-звонков
}
-- Тот же секрет укажите в coturn как static-auth-secret.
turn_external_secret = "ЗАМЕНИТЕ_ДЛИННЫМ_СЛУЧАЙНЫМ_СЕКРЕТОМ"
turn_external_host = "turn.example.org"
turn_external_port = 3478
-- Необязательно: если coturn принимает TURN/TLS на 5349.
turn_external_tls_port = 5349
default_archive_policy = true
archive_expires_after = "1mon"
max_archive_query_results = 100
-- Рекомендуется SQL-хранилище для архива.
storage = {
archive = "sql";
}
Component "upload.example.org" "http_file_share"
-- Luma не задаёт собственного предела; выберите серверный лимит под диск
-- и reverse proxy. Ниже пример на 1 ГиБ.
http_file_share_size_limit = 1024 * 1024 * 1024
http_file_share_expires_after = "1 month" -- Prosody 13
modules_disabled = { "s2s" }
-- XEP-0045: групповые комнаты Luma/Conversations/Monal
Component "conference.example.org" "muc"
name = "Групповые чаты"
restrict_room_creation = false -- либо "local" для локальных пользователей
modules_enabled = { "muc_mam" }
muc_log_by_default = true
muc_log_expires_after = "1mon"
```
## Аудио- и видеозвонки
Сам XMPP-сервер только согласовывает Jingle-сессию. Для двух клиентов с
доступными адресами этого достаточно, но за NAT/CGNAT нужен coturn. Начиная с
Prosody 0.12 проще всего использовать встроенный `mod_turn_external`, как в
примере выше: он публикует STUN/TURN и выдаёт клиенту временные учётные данные
через XEP-0215.
Минимальные соответствующие параметры coturn:
```ini
fingerprint
use-auth-secret
static-auth-secret=ЗАМЕНИТЕ_ТЕМ_ЖЕ_СЕКРЕТОМ
realm=example.org
listening-port=3478
tls-listening-port=5349
# Для TURN/TLS также задайте cert= и pkey=.
```
Откройте для coturn UDP/TCP 3478, при использовании TLS — TCP 5349, а также
настроенный UDP relay range. После перезапуска проверьте выдачу сервиса:
```bash
prosodyctl check turn
```
Без собственного TURN Luma использует публичный STUN только для обнаружения
адресов; STUN не может ретранслировать медиапоток, поэтому звонок между двумя
сложными NAT может не установиться.
Luma проверяет ответы XEP-0215 до создания WebRTC-соединения. Для `turn`/`turns`
Prosody должен выдать и `username`, и `password`; `stuns`/`turns` допускают TCP
(или отсутствие явного `transport`), а истёкшие временные credentials
игнорируются. Если одна серверная конфигурация всё же не принимается WebRTC,
клиент повторяет запуск с публичным STUN, затем с прямыми host candidates. В
Debug-консоли при таком fallback появляется строка `Luma WebRTC:` без URL и
учётных данных.
Для группового OMEMO комната должна быть неанонимной; рекомендуется также
members-only. При создании комнаты Luma сама отправляет owner configuration с
`muc#roomconfig_whois = anyone`, `muc#roomconfig_membersonly = true` и
`muc#roomconfig_persistentroom = true`, а также разрешает ролям moderator и
participant читать member list. Для уже существующей комнаты включите в
настройках владельца показ реальных JID всем участникам и доступ к списку
участников. Если вошедший
пользователь — владелец, Luma попробует изменить `whois` при первой зашифрованной
отправке; обычный участник не может менять эту настройку.
В Prosody 0.12.x срок хранения задаётся числом секунд, например
`http_file_share_expires_after = 31 * 24 * 60 * 60`; строковый интервал выше
используйте на Prosody 13.
Для `upload.example.org` нужен корректный HTTPS URL. Если компонент не является
прямым поддоменом VirtualHost, добавьте его в `disco_items`. При reverse proxy
задайте `http_host`/`http_external_url` согласно вашей топологии. Например, для
`example.com` за HTTPS reverse proxy:
```lua
Component "upload.example.com" "http_file_share"
http_file_share_size_limit = 1024 * 1024 * 1024
http_host = "upload.example.com"
http_external_url = "https://upload.example.com/"
trusted_proxies = { "127.0.0.1", "::1" }
modules_disabled = { "s2s" }
```
Reverse proxy должен передавать `Host: upload.example.com` и
`X-Forwarded-Proto: https`. Иначе Prosody может выдать клиенту `http://` URL или
маршрут, возвращающий 404; Luma намеренно не понижает upload до HTTP.
Проверьте также:
- валидный сертификат и STARTTLS на 5222 либо direct TLS на 5223;
- SRV-записи `_xmpp-client._tcp` и, если используется, `_xmpps-client._tcp`;
- доступность server disco и upload component disco;
- права пользователей на PEP/pubsub nodes;
- доставку PEP notifications `urn:xmpp:avatar:metadata+notify` контактам;
- что MAM действительно пишет в постоянное хранилище, а не fallback memory.
- доступность `conference.example.org` через service discovery и возможность
локального пользователя создать/войти в комнату.
- успешный `prosodyctl check turn` и доступность relay-портов coturn извне.
Полезные команды:
```bash
prosodyctl check config
prosodyctl check certs
prosodyctl shell module info http_file_share
prosodyctl shell http list upload.example.com
```
Начиная с 0.3.0 Luma различает ошибки discovery, получения upload slot,
транспортную ошибку PUT и HTTP status. Если приложение пишет, что XEP-0363 не
найден, проверьте `disco_items`; если показывает HTTP 404/413/5xx — проверяйте
`http_host`, proxy path и лимит файла соответственно.
## Push на iOS
`mod_cloud_notify` реализует серверную сторону XEP-0357, но одного включения
модуля недостаточно. Нужен доступный по XMPP push gateway разработчика Luma,
который принимает события Prosody и отправляет APNs. В текущем MVP клиент не
регистрирует такой endpoint, потому что его адрес, APNs topic и ключи зависят от
вашей Apple Developer учётной записи.
Когда gateway будет готов, включите `cloud_notify` вместе со `smacks`, `mam` и
`carbons`; не включайте передачу реального тела или sender в push без отдельного
решения по приватности.
### Совместимость с сервером Monal
Можно использовать открытый сервер
[`monal-im/fpush`](https://github.com/monal-im/fpush), но его нужно развернуть
для Luma либо договориться с владельцем уже работающего экземпляра о добавлении
отдельного push-модуля. Подключить Luma к production endpoint Monal как к
универсальному APNs relay нельзя: APNs device token относится к конкретному
приложению, а gateway должен подписывать запросы сертификатом этого приложения
и указывать его bundle ID (`app.luma.chat`) как topic.
`fpush` подключается к Prosody как XEP-0114 component и поддерживает несколько
приложений через `pushModule`. Минимальная конфигурация его APNs-модуля выглядит
так (секреты и сертификат не храните в репозитории):
```json
{
"component": {
"componentHostname": "push.example.org",
"componentKey": "CHANGE_ME",
"serverHostname": "127.0.0.1",
"serverPort": 5347
},
"pushModules": {
"lumaProdIOS": {
"type": "apple",
"is_default_module": true,
"apns": {
"certFilePath": "/run/secrets/luma-apns.p12",
"certPassword": "CHANGE_ME",
"topic": "app.luma.chat",
"environment": "production"
},
"ratelimit": {
"ratelimitTime": "20s",
"ratelimitCleanupInterval": "300s",
"enabled": true
}
}
},
"timeout": { "xmppconnectionError": "20s" }
}
```
Для полного подключения ещё нужны:
1. Push Notifications capability и подходящий provisioning profile для Luma.
2. Регистрация iOS-приложения в APNs и получение device token.
3. Отправка XEP-0357 `<enable/>` с `node` = APNs token, JID компонента и полем
`pushModule=lumaProdIOS`; `<disable/>` при выходе из аккаунта.
4. `smacks`, `mam`, `carbons`, `cloud_notify` в Prosody и доступ компонента
`push.example.org` по component-порту или s2s — в зависимости от схемы
развёртывания.
Без APNs credentials от Apple Developer аккаунта приложение продолжит
показывать только уже реализованные локальные уведомления, пока процесс жив.