Установленный стек ещё никому не звонит: в системе нет ни одного телефона. Эта страница доводит свежую инсталляцию до звонка с телефона на телефон и (если у вас есть свой транк) звонка наружу и снаружи. Каждый шаг заканчивается строкой «что должно быть видно»: если её нет, дальше идти бессмысленно — причина будет накапливаться.
Как поставить платформу, описано на главной странице витрины
и в INSTALL.md, который лежит рядом с инсталляцией на диске. Здесь установка не повторяется.
Из чего платформа состоит и как проходит звонок — общие сведения; частые
проблемы, в том числе блокировка собственного адреса, — отдельная страница.
Почему именно звонок. Платформа обрабатывает обращения не только по телефону: текстовые каналы — мессенджеры и чаты — работают в том же ядре и видны в той же панели, доустанавливать для них нечего (аккаунт провайдера подключается в разделе «Чаты → Провайдеры чатов»). Но сквозную проверку быстрее всего даёт звонок: он разом поднимает SIP-фронт, медиа-тракт, оркестрацию, запись и историю обращений — то есть почти весь стек, на котором потом работают остальные каналы.
| Что | Подробности |
|---|---|
| Сервер | VM с публичным IP и установленной платформой. Требования к CPU/RAM/диску — раздел «Перед установкой» на главной витрины |
| Панель | компонент ui (юнит web) — через неё смотрится результат. Что поднято — ./omniflow-ctl ps: в таблице должен быть юнит web |
| Софтфон | Windows — MicroSIP; Linux, macOS, телефон — Linphone. Подойдёт любой SIP-клиент, поддерживающий UDP-регистрацию |
| Открытые порты | Их открывает не платформа, а ваше облако или роутер |
Минимум портов именно для этой страницы (полный список с пояснениями — в панели, раздел «Телефония → Подключение и система», блок «Что открыть снаружи»):
| Порт | Протокол | Зачем |
|---|---|---|
5060 |
udp + tcp | регистрация и звонки телефонов |
30000-30500 |
udp | голос. Без диапазона звонок соединяется, но звука нет |
443 |
tcp | панель управления |
5080 |
udp + tcp | транки провайдеров — только для шага 3 |
Порт 5080 не публикуется автоматически на уровне облака: в списке firewall он стоит отдельной
строкой именно потому, что его чаще всего забывают.
Что должно быть видно. ./omniflow-ctl verify — семь проверок подряд без [ FAIL ]:
./omniflow-ctl verify
[ OK ] контейнеры — N, одноразовые завершены с кодом 0
[ OK ] образы из реестра — все из registry.omniflow.ru
[ OK ] схема базы данных — актуальна
[ OK ] конфигурация SIP-фронта — …
[ OK ] панель — https://<ваш-домен>/ → 200
[ OK ] вход администратора — admin@system
[ OK ] здоровье сервисов — 6 сервисов, все живы
[ OK ] verify: выполнено
→ Платформа установлена. Дальше: ./omniflow-ctl sipuser add <логин> --tenant <тенант> — завести первую SIP-точку (тенанты: ./omniflow-ctl tenant list)
traceId: …
Число контейнеров зависит от набора установленных компонентов — сверять его с чужой инсталляцией
не нужно. Красная строка здесь — это причина, а не симптом: чините её до первого звонка.
Подробности даёт ./omniflow-ctl doctor, логи конкретного сервиса —
./omniflow-ctl logs <сервис> --since 10m.
Вход в панель: https://<ваш-домен>/, поля «Логин» — admin, «Пароль» — из установки, «Tenant» —
оставьте system (подсказка под полем говорит то же самое).
Самая полезная проверка: один звонок разом поднимает SIP-фронт, медиа, оркестрацию и запись.
./omniflow-ctl sipuser add 101 --tenant system --comment "рабочее место 1"
./omniflow-ctl sipuser add 102 --tenant system --comment "рабочее место 2"
--tenant — обязателен: это организация, которой принадлежит линия, и одновременно её SIP-домен.
На одиночной инсталляции организация одна — system. Чтобы не повторять флаг в каждой команде:
export OMNIFLOW_CTL_TENANT=system.
Что должно быть видно (пароль печатается один раз — сохраните его):
тенант: system (из --tenant)
точка 101 создана (домен system)
[ OK ] sipuser add: выполнено
→ Софтфон: сервер 203.0.113.10:5060 (UDP), домен system, логин 101, пароль ••••••••
→ Регистрация: ./omniflow-ctl sipuser list --online
traceId: …
На месте •••••••• команда печатает настоящий пароль — здесь он скрыт, потому что страница
публичная. Адрес и порт у вас будут свои: подставляется EXTERNAL_IP из .env инсталляции.
Если пароль потерян — не заводите точку заново: ./omniflow-ctl sipuser password 101 выдаёт новый,
а в панели («Телефония → SIP-пользователи», карандаш в строке) поле «Пароль» показывает текущий.
Без панели текущий пароль печатает ./omniflow-ctl sipuser show 101 --tenant system --reveal.
То же самое делается в панели: «Телефония → SIP-пользователи» → «Добавить», поля «Логин (username)», «Номер телефона», «Пароль». Цель точки по умолчанию — «Все контуры», менять её на одиночной инсталляции не нужно.
В софтфоне заполняются три вещи из подсказки выше:
| Поле софтфона | Что вписывать |
|---|---|
| Сервер / SIP Server / Domain Proxy | внешний IP платформы и порт 5060, транспорт UDP |
| Домен / Domain / Realm | код организации — при установке по умолчанию system |
| Логин и пароль | 101 и выданный пароль |
Домен — не адрес сервера. Платформа проверяет подлинность пароля по паре «логин + домен», и
домен здесь равен коду организации, которой принадлежит линия. Вписали туда IP или значение
SIP_DOMAIN из .env — пароль перестанет сходиться, и телефон получит 403 при верном пароле.
Домен каждой линии виден в панели в таблице «Телефония → SIP-пользователи» — отдельной колонкой
рядом с логином.
Что должно быть видно. Оба софтфона показывают успешную регистрацию, и платформа это подтверждает:
./omniflow-ctl sipuser list --online
101 system online рабочее место 1
102 system online рабочее место 2
В панели то же самое — колонка «Регистрация» у обеих строк показывает контур, на котором телефон зарегистрирован. Серая метка «Offline» (телефон не дошёл или не прошёл проверку пароля) и прочерк «—» (настройка линии ещё не применена ни на одном контуре) — переходите к разделу 3.1, звонить пока нечему.
Наберите 102 с первого софтфона. Маршрут для этого заводить не нужно: номер, совпадающий с
логином зарегистрированной линии, платформа набирает напрямую.
Что должно быть видно — в панели, раздел «История звонков»:
ANSWERED, на экране оно не
показывается), направлением «Внут», «Откуда» 101, «Куда» 102;Состояние самих сервисов — раздел «Здоровье сервисов» или ./omniflow-ctl status: у каждого
сервиса должен быть хотя бы один живой экземпляр.
Этот шаг нужен, только если у вас есть свой SIP-транк у оператора связи. Без транка платформа полностью работоспособна внутри — шаг можно пропустить и вернуться к нему позже.
Панель: «Телефония → Транки» → «Добавить». «Тип подключения» — то, как провайдер вас узнаёт:
| Тип | Когда | Что заполняется |
|---|---|---|
| Регистрация (uac_reg) | провайдер выдал логин и пароль | «Сервер», «SIP-домен», «Логин», «Пароль»; при необходимости «Дополнительно → Realm» |
| По IP (без пароля) | провайдер узнаёт вас по адресу сервера | «IP провайдера» (только адрес, не имя) и при необходимости «Порт (для исходящих, nexthop)» |
Транк с регистрацией заводится только в панели. В справке ./omniflow-ctl help есть форма
trunk add --type registration … — не пользуйтесь ею: она передаёт только реквизиты авторизации и
не заполняет локальные логин и домен, без которых платформа не проецирует транк в таблицу
регистраций. Транк при этом создастся, ошибки не будет, а статус навсегда останется UNKNOWN —
REGISTER просто не уйдёт. Для транка «по IP» консольная команда подходит полностью:
./omniflow-ctl trunk add --type ip --name "Провайдер" --code provider --host 203.0.113.50
Поле «Realm» нужно, когда провайдер запрашивает авторизацию не тем доменом, который вы указали
(так делают, например, крупные операторские платформы). Неверный realm — гарантированный 403,
сколько бы раз вы ни проверяли пароль.
./omniflow-ctl trunk status provider
| Статус в консоли | Как подписан в панели | Что означает |
|---|---|---|
AUTH_DONE |
«OK» в таблице транков, «Зарегистрирован» в карточке | провайдер принял регистрацию |
AUTH_SENT |
«Регистрация…» / «Ожидание ответа» | запрос отправлен, ответа пока нет — подождите |
FAILED |
«FAIL» / «Ошибка регистрации» | отказ: realm, пароль, DNS или недоступность провайдера. Текст причины — в поле err |
UNKNOWN |
«N/A» / «Неизвестно» | данных о регистрации нет. Нормально для транка «по IP»; для транка с регистрацией — признак того, что REGISTER не отправляется |
Команда возвращает код выхода 1, если транк в FAILED или не готов принимать входящие, — это
удобно в скриптах. В панели это та же величина, но подписана она короче — соответствие в таблице
выше. Искать на экране слова AUTH_DONE или UNKNOWN бесполезно.
Зелёный статус ещё не значит «до вас дозвонятся». AUTH_DONE говорит только то, что
провайдер принял регистрацию; какой адрес он при этом запомнил, видно лишь по реальному входящему
звонку. Проверка одна — позвонить в обе стороны.
Панель: «Телефония → Маршрутизация» → «Добавить», направление «Исходящие», действие «Транк», «Цель действия» — код транка. При действии «Транк» появляется обязательное поле «SBC-контур» — выберите контур, на котором живёт транк.
Паттерны описывают ваш план набора: «To-паттерн (набранный номер)» 8XXXXXXXXXX означает «восьмёрка
и десять любых цифр» (X = любая цифра). Если провайдер ждёт номер в другом формате, приведите его
полем «Модификация To»: T в нём — исходный номер, то есть 8T добавит восьмёрку спереди.
Что должно быть видно. Звонок с 101 на внешний номер проходит, а в «Истории звонков»
появляется строка с направлением «Исх», заполненной колонкой «Транк» и ненулевым «Разговор».
./omniflow-ctl route add --did 74950000000 --to sipuser:101
Что должно быть видно:
маршрут 74950000000 → sipuser:101 создан (id …, контур …)
[ OK ] route add: выполнено
→ Проверить резолв: ./omniflow-ctl bus req q.callroute.test '{"direction":"inbound","fromNumber":"79990000000","toNumber":"74950000000"}'
traceId: …
Номер в --did должен совпадать с тем, что провайдер реально присылает в вызове, — цифра в цифру.
Если он шлёт номер в другом формате (с +, без кода города, с префиксом), правило не совпадёт, и
в журнале звонка появится факт «Маршрут не найден». Команда bus req q.callroute.test из подсказки
проверяет это без реального звонка.
Позвоните на свой номер снаружи — должен зазвонить софтфон 101, а в «Истории звонков» появиться
строка с направлением «Вх».
Порядок разбора всегда один: ./omniflow-ctl doctor (полная диагностика установки) → ./omniflow-ctl status
(что поднято и живо) → ./omniflow-ctl logs <сервис> --since 10m → панель. Не начинайте с логов:
большинство отказов первого дня — это закрытый порт или неверный домен, и они видны раньше.
Блокировка адреса защитой от перебора паролей — признаки, точная проверка в панели и консоли, снятие — разобрана на странице частые проблемы.
| Симптом | Причина | Проверка | Что должно быть видно |
|---|---|---|---|
«Registration failed» или таймаут, в панели точка offline |
Закрыт 5060 на периметре — в облаке или на роутере |
Панель: «Подключение и система» → «Что открыть снаружи», а ниже — блок «Проверки». Пометка «снаружи» у проверок периметра не ошибка: сервер физически не может проверить, доходит ли до него трафик | После открытия порта ./omniflow-ctl sipuser list --online показывает точку как online |
403 при заведомо верном пароле |
В софтфоне в поле домена/realm вписан адрес сервера вместо кода организации | Панель: «Телефония → SIP-пользователи», колонка с доменом точки | В софтфоне домен = код организации (по умолчанию system), после чего регистрация проходит |
| Регистрация то появляется, то пропадает; звонки рвутся | EXTERNAL_IP в .env не тот адрес, по которому вас видят снаружи |
./omniflow-ctl doctor — шаг сверки внешнего адреса с фактическим |
Значение совпадает с фактическим внешним адресом; расхождение доктор называет прямо |
| Телефон «умер» молча: запросы уходят, ответа нет вовсе — и у соседних телефонов той же сети тоже | Сработала защита от перебора паролей: пять неверных паролей с одного адреса — и он блокируется без ответа. Классический источник — один забытый аппарат со старым паролем | ./omniflow-ctl logs kamailio --since 10m; панель: «Телефония → Безопасность» |
В панели видна блокировка вашего адреса и кнопка её снятия; в логе — строки о неверном пароле и о бане адреса. Блокировка снимается и сама — через 5 минут после её установки, и повторные попытки софтфона её не продлевают; вернулась снова — ищите аппарат со старым паролем, снимать её вручную бессмысленно: повторяющиеся серии платформа отдаёт сетевому фильтру, и он закрывает адрес уже на час |
| Симптом | Причина | Проверка | Что должно быть видно |
|---|---|---|---|
| Ответили, тишина в обе стороны, обрыв примерно через 30 секунд | Закрыт диапазон 30000-30500/udp |
Панель: «Подключение и система» → «Что открыть снаружи» | Диапазон открыт в облаке; после этого «Разговор» в истории звонков перестаёт быть нулевым |
| Сигнализация в порядке, «Разговор» 0–1 с при статусе «Отвечен» | Медиа-прокси держит устаревший внешний адрес: он фиксируется в момент запуска контейнера и не меняется от рестарта | Сравните EXTERNAL_IP в .env с аргументами запущенного контейнера медиа-прокси |
После ./omniflow-ctl restart rtpe-1 (контейнер пересоздаётся и перечитывает .env) адреса совпадают, разговор слышен |
«Пришёл 200 OK, значит звонок прошёл» |
Ложный вывод: сигнализация и голос идут разными путями | Всегда смотрите колонку «Разговор» в истории звонков, а не факт ответа | Разговор длится столько же, сколько вы говорили |
| Симптом | Причина | Проверка | Что должно быть видно |
|---|---|---|---|
FAILED, в err — «Нет успешного REGISTER» |
Неверный realm, пароль, DNS-имя провайдера или он недоступен | ./omniflow-ctl trunk status <код>, затем ./omniflow-ctl logs kamailio --since 10m |
Статус переходит в AUTH_DONE; в логе исчезают отказы авторизации |
В логе «realms do not match» и 403 |
Провайдер запрашивает авторизацию другим realm, чем указан в транке | Поле «Дополнительно → Realm» в карточке транка | После указания realm провайдера — AUTH_DONE |
UNKNOWN часами, при этом ошибок нет, входящие «готовы» |
Для транка с регистрацией это значит, что REGISTER не отправляется — чаще всего не заполнены поля локальной регистрации (шаг 2.1) | Откройте карточку транка в панели и проверьте «Логин» и «SIP-домен» | Статус меняется на AUTH_SENT, затем AUTH_DONE |
| Провайдер шлёт звонок, а на платформе не происходит ничего — даже отказа | На транковом порту неопознанный источник отбрасывается молча, без ответа | Убедитесь, что 5080 открыт и что адрес провайдера совпадает с тем, что указан в транке |
Входящий появляется в «Истории звонков» с направлением «Вх» |
| Входящий дошёл, но никуда не поехал | Нет подходящего правила: номер в вызове не совпадает с --did |
Журнал звонка в карточке и ./omniflow-ctl bus req q.callroute.test … из подсказки шага 2.4 |
В журнале вместо «Маршрут не найден» — «Маршрут», и звонит нужная линия |
Если разбор не помог, соберите три вещи: вывод ./omniflow-ctl status (версия и состав),
вывод ./omniflow-ctl doctor и идентификатор проблемного звонка. Идентификатор печатается
последней строкой (traceId: …) у команд, работающих с платформой, а в панели он виден в карточке
звонка в режиме «Подробно» — строки «Chain:» и «Trace:» с кнопкой копирования. По одному этому
идентификатору звонок разбирается целиком. Обращаться — по тому же контакту, по
которому вы получили доступ к реестру образов.