readme
This commit is contained in:
parent
2e8c8ebdde
commit
41c2f9d07b
263
README.md
263
README.md
@ -0,0 +1,263 @@
|
|||||||
|
# Jabogram
|
||||||
|
|
||||||
|
XMPP-сервер для мессенджера с поддержкой голосовых/видеозвонков и хранением медиафайлов в S3.
|
||||||
|
|
||||||
|
**Стек:**
|
||||||
|
- [Snikket](https://snikket.org/) (Prosody) — XMPP-сервер
|
||||||
|
- PostgreSQL 17 — хранение данных Prosody
|
||||||
|
- rclone — монтирование S3-бакета как локальной директории
|
||||||
|
- Docker Compose — оркестрация сервисов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Структура репозитория
|
||||||
|
|
||||||
|
```
|
||||||
|
jabogram/
|
||||||
|
├── server/ # Docker Compose + конфиги Snikket/Prosody
|
||||||
|
│ ├── scripts/ # Скрипты управления пользователями
|
||||||
|
│ └── ...
|
||||||
|
└── s3-mount/ # Скрипты монтирования S3 через rclone
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Установка с нуля
|
||||||
|
|
||||||
|
### 1. Требования к серверу
|
||||||
|
|
||||||
|
- Ubuntu 22.04+ (или Debian 12+)
|
||||||
|
- Docker + Docker Compose plugin
|
||||||
|
- Публичный IP-адрес
|
||||||
|
- Домен, указывающий на этот IP
|
||||||
|
|
||||||
|
### 2. DNS-записи
|
||||||
|
|
||||||
|
Создайте три записи для вашего домена (замените `chat.example.org` на свой):
|
||||||
|
|
||||||
|
| Тип | Имя | Значение |
|
||||||
|
|-------|----------------------------|--------------------|
|
||||||
|
| A | `chat.example.org` | IP-адрес сервера |
|
||||||
|
| CNAME | `groups.chat.example.org` | `chat.example.org` |
|
||||||
|
| CNAME | `share.chat.example.org` | `chat.example.org` |
|
||||||
|
|
||||||
|
Записи должны быть активны до первого запуска — они нужны для получения TLS-сертификатов.
|
||||||
|
|
||||||
|
### 3. Настройка файрвола
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
ufw allow 5222/tcp # XMPP client-to-server
|
||||||
|
ufw allow 5269/tcp # XMPP server-to-server (федерация)
|
||||||
|
ufw allow 5000/tcp # Proxy65 (передача файлов)
|
||||||
|
ufw allow 3478/udp
|
||||||
|
ufw allow 3478/tcp # STUN/TURN
|
||||||
|
ufw allow 5349/tcp
|
||||||
|
ufw allow 5349/udp # TURNS (TURN over TLS)
|
||||||
|
ufw allow 49152:65535/udp # TURN relay (аудио/видео)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Монтирование S3 через rclone
|
||||||
|
|
||||||
|
S3-бакет монтируется в `/mnt/snikket-files` и пробрасывается в контейнер Snikket — именно туда сохраняются файлы, загруженные через XMPP (XEP-0363 HTTP File Upload).
|
||||||
|
|
||||||
|
#### 4.1. Установка rclone и fuse3
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd s3-mount
|
||||||
|
sudo bash install-rclone.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт установит `fuse3`, скачает и установит `rclone`, после чего запустит `rclone config` для интерактивной настройки удалённого хранилища.
|
||||||
|
|
||||||
|
При конфигурации создайте remote с именем `jabogram-vk` (или измените имя в `rclone-snikket.service`), выбрав тип `s3` и указав ключи доступа к вашему S3-совместимому хранилищу.
|
||||||
|
|
||||||
|
#### 4.2. Настройка systemd-сервиса
|
||||||
|
|
||||||
|
Отредактируйте `s3-mount/rclone-snikket.service` при необходимости — проверьте путь к бакету:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
ExecStart=/usr/bin/rclone mount \
|
||||||
|
jabogram-vk:jabogram/http_file_share \ # <remote>:<bucket>/<path>
|
||||||
|
/mnt/snikket-files \
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Установите сервис:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd s3-mount
|
||||||
|
sudo bash install-service.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Сервис запустится автоматически и будет стартовать при загрузке системы раньше Docker.
|
||||||
|
|
||||||
|
Проверьте монтирование:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status rclone-snikket
|
||||||
|
ls /mnt/snikket-files
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Настройка сервера
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd server
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.1. snikket.conf
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp snikket.conf.example snikket.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Обязательно задайте:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
SNIKKET_DOMAIN=chat.example.org # ваш домен (нельзя изменить после первого запуска!)
|
||||||
|
SNIKKET_ADMIN_EMAIL=you@example.org # email для Let's Encrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.2. prosody.cfg.lua
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp prosody.cfg.lua.example prosody.cfg.lua
|
||||||
|
```
|
||||||
|
|
||||||
|
Замените `chat.example.org` на свой домен в строке:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
http_upload_external_base_url = "http://chat.example.org:5050/upload/"
|
||||||
|
```
|
||||||
|
|
||||||
|
> Файл монтируется в контейнер Snikket как `/etc/prosody/conf.d/custom.cfg.lua` и задаёт PostgreSQL-бэкенд и внешний обработчик загрузки файлов.
|
||||||
|
|
||||||
|
#### 5.3. secrets.env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp secrets.env.example secrets.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Заполните реальными значениями:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
UPLOAD_SECRET=случайная-строка-32-символа
|
||||||
|
AWS_ACCESS_KEY_ID=ваш-ключ
|
||||||
|
AWS_SECRET_ACCESS_KEY=ваш-секретный-ключ
|
||||||
|
POSTGRES_PASSWORD=надёжный-пароль
|
||||||
|
```
|
||||||
|
|
||||||
|
> `UPLOAD_SECRET` должен совпадать с `http_upload_external_secret` в `prosody.cfg.lua` — они уже связаны через `os.getenv("UPLOAD_SECRET")`.
|
||||||
|
|
||||||
|
#### 5.4. docker-compose.yml — путь монтирования файлов
|
||||||
|
|
||||||
|
В `docker-compose.yml` найдите строку вида:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- /mnt/snikket-files:/snikket/prosody/share%2ejbr%2ebvn13%2eme/http_file_share
|
||||||
|
```
|
||||||
|
|
||||||
|
Часть `share%2ejbr%2ebvn13%2eme` — это URL-encoded путь вида `share.<домен>`. Замените на свой домен:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- /mnt/snikket-files:/snikket/prosody/share%2echat%2eexample%2eorg/http_file_share
|
||||||
|
```
|
||||||
|
|
||||||
|
Правило кодирования: каждая точка `.` заменяется на `%2e`.
|
||||||
|
|
||||||
|
### 6. Первый запуск
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd server
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Подождите ~30 секунд, пока Snikket получит TLS-сертификаты. Затем создайте администратора:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec snikket create-invite --admin --group default
|
||||||
|
```
|
||||||
|
|
||||||
|
Команда выведет инвайт-ссылку вида `https://chat.example.org/invite/...` — откройте её в браузере для регистрации первого администратора.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Управление пользователями
|
||||||
|
|
||||||
|
Все скрипты находятся в `server/scripts/` и читают `SNIKKET_DOMAIN` из `snikket.conf`.
|
||||||
|
|
||||||
|
| Скрипт | Действие |
|
||||||
|
|-----------------------|---------------------------------------|
|
||||||
|
| `invite-new.sh` | Создать инвайт для обычного пользователя |
|
||||||
|
| `invite-new-admin.sh` | Создать инвайт для администратора |
|
||||||
|
| `invite-list.sh` | Показать список инвайтов |
|
||||||
|
| `invite-revoke.sh` | Отозвать инвайт |
|
||||||
|
| `user-delete.sh` | Удалить пользователя |
|
||||||
|
| `cmd.sh` | Выполнить произвольную команду prosodyctl |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Обновление
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd server
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Бэкап
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd server
|
||||||
|
|
||||||
|
# Данные Snikket (аккаунты, сертификаты, настройки)
|
||||||
|
docker run --rm \
|
||||||
|
-v jabogram_snikket_data:/data \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar czf /backup/snikket-backup.tar.gz -C /data .
|
||||||
|
|
||||||
|
# База данных PostgreSQL
|
||||||
|
docker exec snikket-postgres pg_dump -U snikket snikket \
|
||||||
|
| gzip > snikket-pg-backup.sql.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Медиафайлы хранятся в S3-бакете и бэкапируются отдельно средствами вашего S3-провайдера.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Архитектура хранения файлов
|
||||||
|
|
||||||
|
```
|
||||||
|
XMPP-клиент
|
||||||
|
│
|
||||||
|
│ 1. Запрос слота (XEP-0363)
|
||||||
|
▼
|
||||||
|
Prosody (mod_http_upload_external)
|
||||||
|
│
|
||||||
|
│ 2. Выдаёт подписанный URL → http://chat.example.org:5050/upload/...
|
||||||
|
▼
|
||||||
|
s3_upload_handler (порт 5050)
|
||||||
|
│
|
||||||
|
│ 3. Проверяет HMAC, сохраняет файл в S3
|
||||||
|
│ (или через /mnt/snikket-files, смонтированный rclone)
|
||||||
|
▼
|
||||||
|
S3-бакет
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Открытые порты
|
||||||
|
|
||||||
|
| Порт | Протокол | Назначение |
|
||||||
|
|---------------|----------|--------------------------------|
|
||||||
|
| 80 | TCP | HTTP (ACME, редирект на HTTPS) |
|
||||||
|
| 443 | TCP | HTTPS (веб-портал, файлы) |
|
||||||
|
| 5222 | TCP | XMPP client-to-server |
|
||||||
|
| 5269 | TCP | XMPP server-to-server |
|
||||||
|
| 5000 | TCP | Proxy65 (передача файлов) |
|
||||||
|
| 5050 | TCP | S3 upload handler |
|
||||||
|
| 3478, 5349 | TCP+UDP | STUN/TURN (звонки) |
|
||||||
|
| 49152–65535 | UDP | TURN relay (аудио/видео) |
|
||||||
Loading…
x
Reference in New Issue
Block a user