Телефония: нумерация и маршрутизация
Актуально для: SimpleTwo 0.9.x · Проверено: 23.10.2026
Связь с телефонной сетью обслуживает PSTN-шлюз — отдельная роль pstn с SIP-транками к
оператору связи (разделы 7 и 8): входящие номера ведут во встречи, к сотрудникам и в голосовое
меню с донабором внутреннего номера, исходящие идут по правилам плана нумерации. Клиенты
предлагают набор номера сами, как только сервер разрешает его учётной записи, — отдельной сборки
не нужно (см. «Порядок включения» ниже). Роль mcu — это не PSTN-шлюз: она подключает к встречам
терминалы переговорок, которые уже есть у вас, и не работает ни с транками, ни с городскими
номерами — см. Переговорки и SIP-терминалы. Здесь — про документ, которым
вы будете управлять звонками наружу: план нумерации. Внутренние номера выдаёт тот же план, и
принадлежат они только ему: у людей свой диапазон (по умолчанию 2000–7999), а у переговорных, ботов и гостей может
быть свой — без него переговорные получают номера из диапазона людей, боты и гости номера не получают. Два вида
учёток не делят номер. План и выдачу номеров хранит каталог.
1. Как это устроено
План — один версионированный документ на организацию. Администратор правит его в консоли, координатор сохраняет новую ревизию и отправляет снимок в плоскость коммуникаций.
Снимок отправляется при изменении, а не запрашивается на каждый вызов. Это сделано намеренно: плоскость управления в пути телефонного вызова означает, что доступность координатора становится доступностью телефона. Пока координатор недоступен, телефония работает по последнему полученному снимку; кнопка «отправить снимок» существует как подстраховка.
Документ состоит из:
| Часть | Что задаёт |
|---|---|
| Площадки | единый реестр мест: офис (административная принадлежность сотрудника и переговорной — страна нумерации, часовой пояс, свои транки, главный номер) или ЦОД (где стоят серверы) |
| Транки | оператор на проводе: откуда приходят его вызовы, куда уходят наши, digest и REGISTER; формат цифр, префикс выхода, номера (DID и реестр для представления) |
| Правила | какой номер через какой транк уходит и каким номером представляется |
| Экстренные | отдельный план для экстренных номеров |
| Направления | какие коды стран вообще разрешены |
| Квоты | пределы одновременности, частоты и расходов |
2. Порядок — это часть плана
Правила обходятся сверху вниз, первое совпавшее выигрывает. Транки внутри правила пробуются в том порядке, в котором записаны. Второе — не мелочь: именно так выражается «основной транк и резервный». Если нужно разложить нагрузку на два транка, это пишется двумя правилами, а не перемешиванием внутри одного.
3. Номер приводит к единому виду сервер
Клиент отправляет ровно то, что набрал человек. E.164 вычисляется на сервере — по стране площадки звонящего, а не по локали устройства: одни и те же семь цифр с телефона с немецким регионом и с российским — это два разных звонка, и ни один из пользователей ничего не сделал неправильно.
С 20.10.2026 таблица площадок — единый реестр мест. У площадки есть вид: офис — где
находятся люди, переговорные и их аппараты; ЦОД — где стоят серверы. ГЕО площадки — её
страна. Телефония читает только офисы: у ЦОД нет главного номера, транк и правило на него не
ссылаются, а учётная запись, которой указан ЦОД, считается с неизвестной площадкой (и консоль не
даёт так сделать). Сервер помещается в ЦОД в своих настройках («Серверы и развёртывание»); хост без
такой настройки стоит в ЦОД, созданном из его записи ГЕО Secure Access (dc-ru для записи RU).
По ГЕО строятся SRV-домены MCU для аппаратов переговорных — см. «Переговорные».
Третье состояние здесь запрещает, в отличие от большинс тва других мест продукта. Причина простая: цена неверной догадки в остальных случаях — пустое поле, а тут — счёт и обращение по поводу мошенничества.
4. Экстренные номера
Экстренные — отдельная плоскость, а не правило. Они сопоставляются первыми, по сырым цифрам, до приведения номера к единому виду и до всех прочих проверок, никогда не маршрутизируются по резервному транку и не считаются в квоты.
Он не маршрутизируется в экстренные службы. Это осознанное поведение первой версии: отказ, который видно, лучше молчаливой маршрутизации «куда-нибудь». Предупредите пользователей, ч то звонить 112 нужно с мобильного телефона.
5. Разрешённые направления и квоты
Направления — список разрешённых кодов стран; выигрывает самое длинное совпадение
(+7 — это и Россия, и Казахстан, и организация может хотеть одно без другого).
Квоты считаются там же, где идут звонки, на общей шине:
| Квота | Что ограничивает |
|---|---|
| одновременные на организацию / на транк / на учётную запись | пиковую нагрузку; на транке считаются и входящие звонки, а его собственный «Макс.» действует вместе с квотой плана — меньший из двух |
| звонков в минуту на учётную запись | всплеск с одной учётки |
| новых направлений в час | типичный признак подобранного пароля |
| потолок расходов за окно (месяц — по умолчанию — или сутки, UTC) — на организацию и на учётную запись | деньги — блокирует, а не уведомляет |
| самый долгий звонок, минут | плечо, которое никто не заметил и которое тарифицируется всю ночь |
| рабочие часы | международные звонки вне окна |
Потолок расходов именно блокирует: уведомление в 03:00 — это сообщение, которое прочитают в девять утра. Расход — это сумма оценок стоимости из журнала звонков, каждая по тарифу своего транка; звонок через транк без тарифа посчитать нельзя, поэтому, пока потолок задан, такой звонок отклоняется.
Счётчики одновременных звонков, звонков в минуту и новых направлений живут в общем redis (той же
шине, что у пула SFU), когда он настроен у messaging: счётчик в памяти одного экземпляра — не
лимит. Без redis messaging работает одним экземпляром, и счётчики — его память (/healthz
messaging: pstn_dialout.counters).
6. Проверка и стоп-кран
- Проверить номер — введите номер и увидите, что с ним сделает план: к какому виду о н будет приведён, какое правило совпадёт, через какой транк уйдёт и каким номером представится. Быстрее, чем звонить и разбираться по журналам.
- Остановить телефонию — стоп-кран: исходящие прекращаются, в документе остаётся, кто и когда его дёрнул. Нужен ровно в тот момент, когда счёт растёт, а причина ещё не найдена.
- Отправить снимок — принудительная синхронизация плоскости коммуникаций с текущей ревизией.
Каждая правка плана пишется в аудит, как и любое действие администратора.
7. Транки: оператор на проводе
Под каждым транком в таблице — вторая строка, описание оператора на проводе:
| Поле | Что вписать |
|---|---|
| Адреса оператора | IP или CIDR, откуда приходят его INVITE. Вызов принимается только с этих адресов; всё остальное шлюз отбрасывает без ответа. 0.0.0.0/0 и всё шире /8 не сохраняется |
| Пр оверять входящие | для оператора, адреса которого нельзя перечислить: шлюз требует от его INVITE digest транка |
| Адрес для исходящих, транспорт, порт | куда уходят наши вызовы — имя или IP без sip: и без порта; TLS везде, где оператор его поддерживает (порт по умолчанию 5060, для TLS — 5061) |
| SIP-домен | домен оператора, если он не совпадает с адресом: хост в From исходящего и в регистрации |
| Имя и пароль digest | выданные оператором. Пароль только записывается: хранится зашифрованным (тем же мастер-ключом, что DKIM и сертификаты), больше не показывается; пустое поле оставляет прежний, «стереть пароль» удаляет |
| REGISTER у оператора и срок | для оператора, который требует регистрацию: шлюз держит её сам, обновляет на 4/5 срока и снимает при остановке |
| Тариф | строка на префикс: префикс цена-минуты [шаг-с [за-соединение]], цены — в копейках валюты квот (7 300 60, 7495 100 1); выигрывает самый длинный префикс. По нему журнал оценивает стоимость звонка, и им держится потолок расходов: пока потолок задан, транк без т арифа звонков не несёт |
Номера транка — одновременно его DID: когда два транка приходят с одного адреса, вызов относится к тому, чей номер набран. Если номера не совпали ни у одного — вызов отклоняется.
Пароль не входит в план. Координатор хранит его отдельно и передаёт только в messaging, отдельной отправкой рядом со снимком плана; шлюз спрашивает у messaging на каждый вызов, чей это транк и с каким digest звонить. При заблокированном шифровании (мастер-ключ не загружен) новый пароль не сохраняется, а транки не отправляются — messaging работает по прежней копии.
8. PSTN-шлюз: развёртывание и что уже работает
Это отдельная роль pstn, не mcu. Терминалы переговорок и транки оператора обслуживают
разные хосты: у них разные собеседники (ваши аппараты и чужой SBC), разная модель угроз
(мошенничество со счётом возможно только на транке) и одинаковые порты по умолчанию — поэтому
на одном хосте они не живут.
Перед развёртыванием
- messaging — шлюз получает от него исходящие звонки своих транков, узнаёт, чей транк у входящего, и спрашивает пропуск в каждую комнату. Ключа SFU на хосте шлюза нет и не будет. Шлюз ходит к messaging по его публичному адресу (HTTPS): шины redis и приватной сети шлюзу не нужно, поэтому его можно поставить рядом с оператором в другой стране.
- SFU — шлюз входит в комнату как участник, по публичному имени SFU.
- Хост: 4 vCPU / 4 ГБ — ориентировочно ~80 одновременных звонков (каждый перекодируется, ~0,05 ядра; ~320 кбит/с на звонок на узле). Маршрутизируемый IPv4 на интерфейсе или NAT 1:1 с проброшенными 5060 и диапазоном RTP; симметричный NAT не работает, SIP-сторона — только IPv4.
Без связи с messaging шлюз звонков не принимает и не совершает: каждое решение о звонке принимает messaging.
Развёртывание
Серверы → Добавить хост → роль «PSTN-шлюз (транки оператора)»:
| Поле | Что вписать |
|---|---|
| Приватный адрес | необязателен: шлюзу не нужна приватная сеть |
| Публичное DNS-имя | необязательно; с ним координатор заказывает сертификат и открывается SIP-TLS на 5061 |
| Адрес в сторону транков | IPv4 на этом хосте, на который шлют SBC операторов (пусто — все интерфейсы) |
| Анонсируемый IP | публичный IPv4 для SDP, Via и Contact за NAT 1:1 (пусто — определяется сам) |
| Диапазон RTP | по умолчанию 10000-20000; два порта на звонок |
Выполните команду на хосте. Агент поставит simpletwo-pstn, библиотеки, с которыми он собран
(libopus, libopusfile, libsoxr), откроет 5060/udp+tcp и диапазон RTP, а 5061/tcp — только когда
сертификат уже на диске. Строка в «Серверах» показывает, слушает ли 5060.
Если координатор говорит «this coordinator has no simpletwo-pstn binary», значит, в этом выпуске
ещё не задан PSTN_VERSION — первый выпуск шлюза публикуется отдельным тегом. Хост ждёт и
сам встанет, когда координатор обновится.