11 KiB
Настройка Prosody для Luma
Ниже приведён ориентир для актуальных Prosody 0.12/13. Сохраните существующие модули аутентификации, TLS и federation вашего сервера — пример показывает только функции, необходимые клиенту.
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:
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. После перезапуска проверьте выдачу сервиса:
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:
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 извне.
Полезные команды:
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, но его нужно развернуть
для 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-модуля выглядит
так (секреты и сертификат не храните в репозитории):
{
"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" }
}
Для полного подключения ещё нужны:
- Push Notifications capability и подходящий provisioning profile для Luma.
- Регистрация iOS-приложения в APNs и получение device token.
- Отправка XEP-0357
<enable/>сnode= APNs token, JID компонента и полемpushModule=lumaProdIOS;<disable/>при выходе из аккаунта. smacks,mam,carbons,cloud_notifyв Prosody и доступ компонентаpush.example.orgпо component-порту или s2s — в зависимости от схемы развёртывания.
Без APNs credentials от Apple Developer аккаунта приложение продолжит показывать только уже реализованные локальные уведомления, пока процесс жив.