Move to Volcanic VPS: domain crm-calls.volcanic.tes.gd, advertise 164.90.233.156, README rewrite
This commit is contained in:
106
README.md
106
README.md
@@ -1,8 +1,9 @@
|
||||
# crm-calls
|
||||
|
||||
Jitsi Meet для Tvorymo CRM: https://crm-calls.tes.gd
|
||||
Jitsi Meet для Tvorymo CRM: https://crm-calls.volcanic.tes.gd
|
||||
|
||||
Розгортання: Coolify (сервер `storage`, 192.168.50.73), застосунок `crm-calls`, build pack `dockercompose`,
|
||||
Розгортання: Coolify Вулканика (`http://coolify.volcanic.tes.gd:8000`), VPS `164.90.233.156`
|
||||
(DigitalOcean, `*.volcanic.tes.gd`), проєкт і застосунок `crm-calls`, build pack `dockercompose`,
|
||||
файл `docker-compose.yml`. Основа: офіційний [docker-jitsi-meet](https://github.com/jitsi/docker-jitsi-meet), образи `stable-11248`.
|
||||
|
||||
## Сервіси
|
||||
@@ -10,7 +11,7 @@ Jitsi Meet для Tvorymo CRM: https://crm-calls.tes.gd
|
||||
| Сервіс | Що робить | Як доступний ззовні |
|
||||
|---------|-----------------------------------|---------------------|
|
||||
| web | nginx + веб-застосунок Jitsi | HTTPS 443 через Traefik (Coolify) → `web:8000` |
|
||||
| prosody | XMPP-сервер | лише `wss://crm-calls.tes.gd/xmpp-websocket` (проксі через web) |
|
||||
| prosody | XMPP-сервер | лише `wss://crm-calls.volcanic.tes.gd/xmpp-websocket` (проксі через web) |
|
||||
| jicofo | фокус конференцій | ззовні не доступний |
|
||||
| jvb | відеоміст (медіа) | **UDP 10000 напряму**, повз Traefik |
|
||||
|
||||
@@ -24,92 +25,63 @@ Colibri-websocket у цій версії Jitsi не використовуєть
|
||||
- `JICOFO_AUTH_PASSWORD` — пароль jicofo у prosody
|
||||
- `JVB_AUTH_PASSWORD` — пароль jvb у prosody
|
||||
|
||||
Мережеві (задані в Coolify env, змінюються без правок у репозиторії):
|
||||
Мережеві (змінюються в env Coolify без правок у репозиторії, після зміни — Redeploy):
|
||||
|
||||
- `JVB_PORT` — UDP-порт JVB, публікується на хості storage (зараз `10000`)
|
||||
- `JVB_ADVERTISE_IPS` — адреси, які JVB повідомляє клієнтам, через кому (зараз `192.168.50.73`,
|
||||
тобто лише LAN — публічний UDP-шлях ще не вибрано)
|
||||
- `JVB_PORT` — UDP-порт JVB, публікується на хості (`10000`)
|
||||
- `JVB_ADVERTISE_IPS` — публічні адреси, які JVB повідомляє клієнтам, через кому (`164.90.233.156`)
|
||||
|
||||
Інші: `PUBLIC_URL` (`https://crm-calls.tes.gd`), `TZ` (`Europe/Kyiv`), `DEFAULT_LANGUAGE` (`uk`),
|
||||
Інші: `PUBLIC_URL` (`https://crm-calls.volcanic.tes.gd`), `TZ` (`Europe/Kyiv`), `DEFAULT_LANGUAGE` (`uk`),
|
||||
`JITSI_IMAGE_VERSION` (`stable-11248`).
|
||||
|
||||
Після зміни env — Redeploy застосунку в Coolify.
|
||||
Домен у Coolify (`docker_compose_domains`): `web` → `https://crm-calls.volcanic.tes.gd:8000`.
|
||||
`:8000` тут — порт контейнера `web`, куди Traefik веде трафік; публічна адреса — звичайний HTTPS 443.
|
||||
|
||||
## Мережа
|
||||
|
||||
- `46.101.119.200` — VPS у DigitalOcean (туди веде `*.tes.gd`), відкриті лише TCP 22/80/443,
|
||||
TCP 443 прозоро передається на Traefik на storage (сертифікати Let's Encrypt видає Traefik на storage).
|
||||
- `storage` — `192.168.50.73`, вихід в інтернет через Netia `195.128.172.198`, вхідні порти закриті.
|
||||
VPS має публічну адресу `164.90.233.156` безпосередньо на інтерфейсі (без NAT), тому
|
||||
`JVB_ADVERTISE_IPS=164.90.233.156`.
|
||||
|
||||
Веб і XMPP (TCP 443) уже працюють. Для медіа JVB потрібен **вхідний UDP** до `192.168.50.73:$JVB_PORT`.
|
||||
Без нього сторінка й кімната відкриваються, але звуку/відео в конференції через JVB не буде
|
||||
(дзвінок удвох іноді працює P2P напряму між браузерами).
|
||||
| Порт | Протокол | Куди | Навіщо |
|
||||
|--------------|----------|--------------------------|--------|
|
||||
| 443 (і 80) | TCP | Traefik → `web:8000` | веб, `/xmpp-websocket` |
|
||||
| 10000 | **UDP** | `jvb` (опублікований на хості) | медіа і SCTP-канал до JVB |
|
||||
|
||||
Варіант треба вибрати один (або A/B + C як запасний для корпоративних мереж).
|
||||
UDP 10000 має бути дозволений і в ufw/iptables на VPS, і в DigitalOcean Cloud Firewall (якщо він
|
||||
прив'язаний до droplet). Порт, опублікований Docker, зазвичай проходить повз ufw, але не повз Cloud Firewall.
|
||||
|
||||
### Варіант A — проброс на роутері Netia (найкраща якість)
|
||||
Без UDP 10000 сторінка й кімната відкриваються, але аудіо/відео через JVB не буде.
|
||||
|
||||
1. Переконатися, що `195.128.172.198` — статична «біла» адреса саме на WAN роутера
|
||||
(не CGNAT): WAN IP у панелі роутера має збігатися з `195.128.172.198`. Якщо ні — замовити в Netia статичну публічну IP.
|
||||
2. На роутері: port forwarding **UDP 10000** з WAN `195.128.172.198:10000` → `192.168.50.73:10000`.
|
||||
3. Якщо на storage є ufw/iptables — дозволити вхідний UDP 10000.
|
||||
4. У Coolify env: `JVB_ADVERTISE_IPS=195.128.172.198,192.168.50.73` → Redeploy.
|
||||
Перевірка: під час дзвінка в `chrome://webrtc-internals` вибрана ICE-пара має вести на
|
||||
`164.90.233.156:10000` (udp). Або на VPS: `sudo tcpdump -ni any udp port 10000` і ззовні
|
||||
`echo test | nc -u -w1 164.90.233.156 10000`.
|
||||
|
||||
### Варіант B — UDP через VPS 46.101.119.200 і WireGuard
|
||||
## TURN (на майбутнє, `turn.volcanic.tes.gd`)
|
||||
|
||||
Storage сам підключається до VPS (вихідне з'єднання, вхідні порти на Netia не потрібні).
|
||||
Потрібен клієнтам, у яких заблокований UDP (корпоративні мережі, частина мобільних операторів).
|
||||
DNS `turn.volcanic.tes.gd` уже веде на `164.90.233.156` (wildcard).
|
||||
|
||||
1. DigitalOcean Cloud Firewall + ufw на VPS: відкрити вхідні **UDP 10000** і **UDP 51820** (WireGuard).
|
||||
2. WireGuard: VPS `10.88.0.1/24` (ListenPort 51820), storage `10.88.0.2/24`, у storage
|
||||
`Endpoint = 46.101.119.200:51820`, `PersistentKeepalive = 25`, `AllowedIPs = 10.88.0.1/32`.
|
||||
3. На VPS:
|
||||
```sh
|
||||
sysctl -w net.ipv4.ip_forward=1 # і в /etc/sysctl.conf
|
||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 10000 -j DNAT --to-destination 10.88.0.2:10000
|
||||
iptables -t nat -A POSTROUTING -o wg0 -p udp -d 10.88.0.2 --dport 10000 -j MASQUERADE
|
||||
iptables -A FORWARD -i eth0 -o wg0 -p udp -d 10.88.0.2 --dport 10000 -j ACCEPT
|
||||
iptables -A FORWARD -i wg0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
```
|
||||
(MASQUERADE потрібен, щоб відповіді JVB поверталися тим самим тунелем, а не через Netia.)
|
||||
4. Storage: дозволити вхідний UDP 10000 з `wg0`.
|
||||
5. У Coolify env: `JVB_ADVERTISE_IPS=46.101.119.200,192.168.50.73` → Redeploy.
|
||||
**Варіант 1 — класичний coturn (найкраща якість).** Відкрити у файрволі VPS / DO:
|
||||
`3478` UDP+TCP, `5349` TCP (TURNS), relay-діапазон напр. `49160-49200` UDP.
|
||||
coturn: `use-auth-secret`, `static-auth-secret=<секрет у Coolify env>`, `realm=crm-calls.volcanic.tes.gd`,
|
||||
`external-ip=164.90.233.156`, `min-port`/`max-port` = relay-діапазон, TLS-сертифікат для
|
||||
`turn.volcanic.tes.gd` (5349), `denied-peer-ip` для приватних мереж.
|
||||
|
||||
Мінуси: весь медіатрафік іде через VPS (додаткова затримка і трафік DigitalOcean).
|
||||
**Варіант 2 — TURNS на 443 через Traefik (нових портів не треба).** coturn слухає TCP 3478 лише у
|
||||
внутрішній мережі; TCP-роутер Traefik `HostSNI(`turn.volcanic.tes.gd`)` на entrypoint `https` з TLS
|
||||
(letsencrypt) → `coturn:3478`. coturn ретранслює медіа на JVB усередині хоста. Працює там, де дозволений
|
||||
лише TCP 443; якість нижча (медіа по TCP).
|
||||
|
||||
### Варіант C — TURN на 443 (TURNS через Traefik, нових портів не треба)
|
||||
|
||||
Працює навіть там, де дозволено лише TCP 443 (корпоративні мережі). Якість гірша (медіа по TCP/TLS).
|
||||
|
||||
1. DNS: `turn.tes.gd` уже веде на `46.101.119.200` (wildcard) — нічого не робити.
|
||||
2. Додати сервіс `coturn` (образ `coturn/coturn`) у compose, слухає TCP 3478 лише у внутрішній мережі.
|
||||
Конфіг: `use-auth-secret`, `static-auth-secret=$TURN_CREDENTIALS`, `realm=crm-calls.tes.gd`,
|
||||
`no-tls`, `no-udp` на слухачі (клієнт ↔ coturn — TCP), `allowed-peer-ip=192.168.50.73`,
|
||||
`denied-peer-ip` для інших приватних діапазонів.
|
||||
3. Traefik (Coolify): TCP-роутер `HostSNI(`turn.tes.gd`)` на entrypoint `https` з TLS (certresolver
|
||||
letsencrypt) → `coturn:3478`. Тобто Traefik знімає TLS і передає TURN-потік у coturn.
|
||||
4. У Coolify env (секрет лише там): `TURN_CREDENTIALS=<випадковий рядок>`, `TURNS_HOST=turn.tes.gd`,
|
||||
`TURNS_PORT=443`, `TURN_TRANSPORT=tcp` → Redeploy. Prosody (`mod_external_services`) роздає клієнтам
|
||||
тимчасові TURN-облікові дані; coturn ретранслює медіа на JVB `192.168.50.73:10000` всередині LAN.
|
||||
5. На роутері/VPS нічого відкривати не потрібно.
|
||||
|
||||
Пізніше, за наявності вхідного UDP (A або B), можна додати класичний TURN: 3478 UDP/TCP, 5349 TLS
|
||||
і діапазон relay-портів (напр. 49160–49200 UDP) з `external-ip` = вибрана публічна адреса.
|
||||
|
||||
### Перевірка UDP після A або B
|
||||
|
||||
```sh
|
||||
sudo tcpdump -ni any udp port 10000 # на storage
|
||||
echo test | nc -u -w1 <публічна-IP> 10000 # ззовні
|
||||
```
|
||||
|
||||
Під час дзвінка в `chrome://webrtc-internals` вибрана ICE-пара має вести на `<публічна-IP>:10000`.
|
||||
В обох варіантах Jitsi (env prosody, через Coolify): `TURN_CREDENTIALS=<той самий секрет>`,
|
||||
`TURNS_HOST=turn.volcanic.tes.gd`, `TURNS_PORT=5349` або `443`, для варіанту 1 також
|
||||
`TURN_HOST=turn.volcanic.tes.gd`, `TURN_PORT=3478`, `TURN_TRANSPORT=udp,tcp`.
|
||||
Prosody (`mod_external_services`) роздає клієнтам тимчасові TURN-облікові дані.
|
||||
|
||||
## Вбудовування (iframe) у вікі / CRM
|
||||
|
||||
- Jitsi nginx не ставить `X-Frame-Options`; framing задається через
|
||||
`Content-Security-Policy: frame-ancestors 'self' https://*.tes.gd https://test.units.tvorymo.com`
|
||||
(змінна `CSP_HEADER` у compose, сервіс `web`). Щоб додати домен — дописати його туди.
|
||||
- Вбудовувати через `https://crm-calls.tes.gd/external_api.js` (`JitsiMeetExternalAPI`), iframe має
|
||||
- Вбудовувати через `https://crm-calls.volcanic.tes.gd/external_api.js` (`JitsiMeetExternalAPI`), iframe має
|
||||
мати `allow="camera; microphone; display-capture; autoplay; clipboard-write; fullscreen"`.
|
||||
- Авторизація (postMessage → JWT) поки не налаштована: кімнати відкриті для всіх, хто знає URL.
|
||||
Для CRM планується `ENABLE_AUTH=1`, `AUTH_TYPE=jwt`, `JWT_APP_ID`, `JWT_APP_SECRET` (секрет — лише в Coolify).
|
||||
|
||||
Reference in New Issue
Block a user