initial commit

This commit is contained in:
wt committed 2026-10-20 15:59:55 +07:00
commit c260d7bab8
235 files changed
+49786

No files matched your search

+199
View File
@@ -0,0 +1,199 @@
# Rust XMPP 0.7.7
Сервер на Rust, разрабатываемый для замены **Prosody 13.0 nightly 100,
cafd74b9c5ea** с предоставленными модулями. Читает существующий Lua-конфиг,
а также JSON, YAML/YML и TOML. Использует внутреннее файловое хранилище
Prosody: конвертация аккаунтов и истории для проверенных сценариев не нужна.
Nginx не требуется: HTTPS, WebSocket, BOSH и загрузка файлов обслуживаются
самим сервером; coturn остаётся отдельным сервисом.
Это работающая экспериментальная реализация, **полная взаимозаменяемость
ещё не достигнута**. Уже реализованы вход, сообщения, контакты, MAM, MUC,
PEP/pubsub, закладки, offline, carbons, SM, push, TLS-федерация и HTTP.
Точные ограничения перечислены в [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md),
проверки — в [docs/VALIDATION.md](docs/VALIDATION.md).
Нестандартные HTTP-пути и TLS reverse proxy: [docs/HTTP-PROXY.md](docs/HTTP-PROXY.md).
Пример для слияния с действующим конфигом: `examples/reverse-proxy.fragment.yaml`.
MUC-расширения и условия восстановления участников: [docs/MUC-RECOVERY.md](docs/MUC-RECOVERY.md).
Встроенный http_altconnect: [docs/HTTP-ALTCONNECT.md](docs/HTTP-ALTCONNECT.md).
## Сборка и изолированный запуск
Нужны Rust 1.99.1 (rustup установит версию из `rust-toolchain.toml`),
C-компилятор и make. Для тестовых сертификатов и сетевых проверок нужны
OpenSSL CLI, Bash и Python 3; HTTP-тест дополнительно использует Python `websockets`.
Системные CA-сертификаты нужны для проверки удалённых серверов федерации.
Cargo.lock фиксирует зависимости; первая сборка требует их загрузки.
```bash
cd rust-xmpp
cargo build --release --locked
bash scripts/make-demo.sh
./target/release/rust-xmpp serve demo/config.toml --experimental
```
Demo слушает только `127.0.0.1:55222` и создаёт отдельное хранилище `demo/data`.
Аккаунты: `alice@localhost / alice-test-only` и
`bob@localhost / bob-test-only`. Для ручного клиента используйте STARTTLS
и доверьте сгенерированному `demo/cert.pem`. `make-demo.sh` не перезаписывает
существующий demo. Сертификаты и аккаунты в исходный архив не включены.
## Существующий конфиг без редактирования
```bash
./target/release/rust-xmpp check-config /etc/prosody/prosody.cfg.lua
./target/release/rust-xmpp serve /etc/prosody/prosody.cfg.lua --experimental
```
`check-config` проверяет разбор и базовые типы; ограничения runtime проверяются
при `serve`. Существующий Lua-файл читается непосредственно, преобразовывать
его в другой формат не требуется. Процессу нужны права на сертификат, ключ,
каталог данных и Unix admin socket. Используйте тот же UID/GID, что и Prosody,
чтобы сохранять доступ при возврате к нему.
Первую проверку выполняйте на копии данных с отдельными портами: сервер пишет
аккаунты, историю, комнаты и другие данные в обычном режиме. Одновременно
запускать Rust и Prosody с одним каталогом данных нельзя. Между экземплярами
Rust действует блокировка inode каталога данных, в том числе при разных портах
и путях-синонимах. Prosody в этой блокировке не участвует. Команда create-user
также отказывается писать в каталог работающего Rust-сервера; для изменения
аккаунтов во время работы используйте admin shell. Для переключения остановите один процесс и запустите
другой. Резервная копия нужна для проверки отката до переключения рабочего
сервера; тестирование формата не доказывает совместимость всех ваших записей.
## Ваш Docker Compose
Распакуйте каталог `rust-xmpp` рядом с исходным `docker-compose.yml`.
Дополнительный файл заменяет образ только сервиса `prosody`. Порты, тома,
healthcheck `prosodyctl check` и сервис coturn наследуются из исходного файла.
```bash
docker compose -f docker-compose.yml -f rust-xmpp/compose.override.yml config
docker compose -f docker-compose.yml -f rust-xmpp/compose.override.yml up -d --build prosody
```
Эта команда запускает сервер на томах из исходного Compose; применяйте её
после проверки на копии. Исходные `docker-compose.yml` и `prosody.cfg.lua`
редактировать не требуется. Образ содержит CA-сертификаты и команду
`prosodyctl`, совместимую с указанным healthcheck. Это проверка ответа
работающего процесса через admin socket, а не полный аналог диагностики
`prosodyctl check`.
Entrypoint определяет UID/GID владельца `/var/lib/prosody` и запускает процесс
с этими правами, не меняя рекурсивно владельцев существующих файлов. Если
каталог принадлежит root, а файлы внутри другому UID, задайте `XMPP_UID` и
`XMPP_GID` в окружении контейнера через дополнительный Compose-файл.
При другом пути данных задайте также `XMPP_DATA_DIR`. Выбранный пользователь
должен читать TLS-ключ и писать данные. Docker-образ в среде разработки
не собирался: здесь нет Docker; состав образа и override подготовлены,
но запуск на целевом Docker ещё предстоит проверить.
## Форматы конфигурации
Все форматы используют одну структуру: `global` и `hosts`; у хоста есть
`options` и, для компонента, `component`. Надёжнее получить её из Lua:
```bash
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua json config.json
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua yaml config.yml
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua toml config.toml
./target/release/rust-xmpp check-config config.yml
```
Конвертер сохраняет области настроек и Include, не меняет исходный файл,
не перезаписывает существующий выходной и создаёт его с правами `0600`.
Выходной файл содержит секреты конфигурации. Lua выполняется в ограниченной
VM без системных библиотек; произвольные Lua-плагины не исполняются.
Поддержка Lua в проекте также нужна для точного чтения файлов данных Prosody.
## Команды и проверки
Полный локальный прогон: `bash scripts/verify-local.sh`.
`XMPP_LOAD_CHECK=1` добавляет нагрузочный сценарий; настройки native Prosody
для дополнительных проверок описаны в `scripts/prosody_compat/README.md`.
```bash
cargo test --locked
cargo clippy --locked --all-targets -- -D warnings
cargo build --release --locked
python3 scripts/smoke.py # после make-demo.sh
python3 scripts/integration_xmpp.py
python3 tests/sasl_network.py --spawn --hash sha1
python3 tests/sasl_network.py --spawn --hash sha256
python3 tests/sasl2_bind.py target/release/rust-xmpp
python3 scripts/integration_http.py # требует websockets
python3 scripts/load_smoke.py --clients 500 --accounts 100 --rounds 10 --message-rounds 10 --archive
```
Все сетевые тесты создают отдельные тестовые данные; кроме smoke с портом
55222, выбирают свободные loopback-порты. Оригинальная Prosody отдельно
проверяет формат данных и пароли: инструкции в
[scripts/prosody_compat/README.md](scripts/prosody_compat/README.md).
```bash
./target/release/rust-xmpp create-user CONFIG USER --password-stdin
./target/release/rust-xmpp check [CONFIG]
./target/release/rust-xmpp shell CONFIG 'server:status()'
```
Пароль `create-user` принимает через stdin; существующий аккаунт не заменяет.
Admin shell реализует ограниченный набор команд управления сервером и
аккаунтами. Произвольный Lua-код и горячая перезагрузка модулей не поддержаны.
## Дополнительный SASL2 Bind2
Модуль `sasl2_bind2` (alias `bind2`) включает привязку ресурса внутри SASL2,
inline SM/CSI/Carbons и MAM metadata. Добавьте его в modules_enabled вместе
с `sasl2` только если эта функция нужна. Исходный конфиг по-прежнему работает
без включения нового модуля. Ресурс генерируется случайно; прежние соединения
того же аккаунта с тем же валидным UUIDv4 user-agent завершаются после успешного
входа. Inline возобновление SM через SASL2 пока не объявляется.
## PEP, push и pre-authenticated roster
В 0.5.0 исправлены ответы disco для bare JID аккаунта. При включённых
`pep` и `cloud_notify` (они уже есть в предоставленном конфиге) изменение
конфига не требуется. После обновления переподключите аккаунт в клиенте,
чтобы повторить service discovery. Push требует также настройки
клиентского push-сервиса; реальный APNs/FCM шлюз здесь не имитируется.
При включённом `roster` клиент может обнаружить и вызвать контактную
ad-hoc команду `urn:xmpp:invite#invite` на серверном JID. Она возвращает
`xmpp:…?roster;preauth=…` и срок действия. Регистрацию аккаунта такое
приглашение не разрешает. XEP-0379 presence tokens сохраняются даже
для неизвестных серверу приглашений, созданных самим клиентом.
## Переподключение в 0.6.0
Повторная привязка одного ресурса по умолчанию заменяет старое соединение,
как в Prosody. `conflict_resolve` поддерживает `kick_old`, `kick_new`,
`increment` и `random`. Если явно задан `kick_new`, занятый ресурс по-прежнему
получит protocol conflict — это выбранная политика.
SM восстанавливается при гонке со старым TCP и внутри SASL2. Исправлено
освобождение ресурсов при BOSH/WebSocket close. Подробности:
[CHANGELOG-0.6.0.md](CHANGELOG-0.6.0.md).
## Android SASL в 0.6.1
Добавлен `tls-server-end-point` для TLS1.2/1.3 и исправлена SSDP-проверка
соединений WebSocket без channel binding. Причина воспроизводимого
`not-authorized` в Conversations, область тестирования и ограничения
описаны в [CHANGELOG-0.6.1.md](CHANGELOG-0.6.1.md) и
[docs/ANDROID-SASL.md](docs/ANDROID-SASL.md).
## Логирование в 0.7.0
Добавлены журнал TLS/SASL/bind/SM с единым connection ID, точные причины
отказов, файлы/console, JSON/plain и SIGHUP rotation reopen. Для диагностики
Conversations/monocles используйте [docs/LOGGING.md](docs/LOGGING.md).
## Исправления 0.7.5
Cached SASL2 Bind2/SM requests допускают legacy fallback, XEP-0258/0077
объявляются для Gajim; policy/classifications схема может использоваться
как каталог labels. Дубликаты одинаковых log destinations устранены.
Подробности — [CHANGELOG-0.7.5.md](CHANGELOG-0.7.5.md).