Почему PJSIP не пропускает звонки: проверяем конфиг
Если после правки pjsip.conf вызовы пропали, сначала проверьте, загрузились ли объекты PJSIP и совпадает ли путь конкретного вызова с настройкой. Я разбираю пять типовых ошибок в Asterisk 20: от неверно связанного endpoint до попытки лечить перезапуском то, что требует проверки SIP-ответа.
1. Транспорт: не путайте объявление и выбор
Первая ошибка — считать, что любому endpoint обязательно нужна строка transport=udp, а без секции транспорта Asterisk вообще не слушает SIP. Это неверное обобщение. В PJSIP транспорт описывается отдельным объектом с type=transport, protocol и bind; endpoint может ссылаться на него параметром transport. Если ссылка не задана, Asterisk выбирает совместимый настроенный транспорт для адреса назначения. Поэтому отсутствие строки transport у endpoint само по себе не доказывает причину сбоя. Я начинаю с фактического состояния: в CLI смотрю pjsip show transports, затем проверяю адрес и протокол, которые ожидает телефон или оператор. Услуга настройки IP-телефонии начинается с такой проверки, а не с механической замены всех портов на 5060.
Минимальный пример транспорта UDP выглядит так: [transport-udp], type=transport, protocol=udp, bind=192.0.2.10:5060. Адрес 192.0.2.10 здесь из документационного диапазона для примеров, его надо заменить адресом интерфейса вашей АТС. Порт 5060 часто встречается в SIP-конфигурациях, но это не обязательное значение для каждой установки: сверяйте его с телефоном, провайдером, NAT и межсетевым экраном. Если меняете bind, протокол или TLS-параметры, не рассчитывайте, что обычная перезагрузка конфигурации применит изменение: документация Asterisk указывает, что транспортные изменения требуют полного перезапуска Asterisk, если отдельно не настроена возможность перезагрузки транспорта. Перезапуск согласуйте с окном обслуживания, иначе диагностическая правка сама оборвёт текущие разговоры. При работе за NAT отдельно проверьте адреса сигнализации и RTP. Транспорт сам по себе не исправляет неверно объявленный внешний адрес; пригодится настройка PJSIP за NAT.
В условном сценарии «Бриз-Строй» я бы зафиксировал до изменения три вещи: какой интерфейс слушает SIP, какой транспорт прописан у удалённой стороны и что показывает CLI. Допустим, у компании 18 телефонов и один транк, а проблема появилась после смены сетевого интерфейса. Не нужно объявлять, что «сломался весь PJSIP»: сперва сопоставляем адрес bind с реальным интерфейсом, затем сверяем тестовый вызов и ответ удалённой стороны. Такой сценарий — схема разбора, а не подтверждённый реальный клиентский проект; конфигурацию провайдера нельзя выводить из одного имени секции.
- Проверьте `pjsip show transports`
- Сверьте bind, протокол и порт на обеих сторонах
- Для изменения транспорта планируйте полный перезапуск
2. Endpoint — объект, а не строка endpoint_id
Вторая ошибка — искать в pjsip.conf параметр endpoint_id и требовать, чтобы он совпадал с именем секции. Это не правило конфигурации PJSIP. Имя в квадратных скобках задаёт имя объекта, а его тип задаёт type=endpoint; отдельной директивой endpoint_id обычный endpoint не переименовывают. Например, [office-trunk] вместе с type=endpoint создаёт объект с таким именем. Проверить, загрузился ли он, можно командой pjsip show endpoint office-trunk. Команда pjsip show endpoints покажет список, но сам факт присутствия объекта не доказывает, что маршрутизация, учётные данные и dialplan настроены верно. Миф «имя секции обязано повторяться в endpoint_id» только уводит от реальной причины.
Для входящего запроса Asterisk должен сопоставить SIP-пакет endpoint. В зависимости от конфигурации сопоставление идёт по имени в SIP-запросе или по объекту identify, который связывает endpoint с адресом источника. Поэтому транк, у которого меняется пользователь в заголовке From, может требовать identify с корректным match, а не переименования endpoint. Если совпадение не найдено, изучайте сообщение Asterisk и источник запроса; не исправляйте наугад учётную запись. В документации PJSIP отдельно описаны endpoint, AOR, auth, identify и transport: это связанные, но разные объекты. Полезный ориентир — практическая настройка res_pjsip, особенно когда звонок доходит до АТС, но не попадает в нужный контекст.
В сценарии «Бриз-Строй» с 18 телефонами я бы не называл статус регистрации доказательством корректного endpoint. Для одного аппарата проверил бы его секцию, type=endpoint, ссылку aors, нужный context, а затем способ сопоставления входящего запроса. Для оператора проверил бы endpoint и identify отдельно. Нельзя объединять всё в правило «имя секции равно логину»: имя объекта, SIP-имя абонента и имя в credentials могут отличаться. Сначала устанавливаем, чей именно запрос не сопоставлен — телефона, транка или регистрации — и только потом меняем конфиг.
- Убедитесь, что секция имеет `type=endpoint`
- Проверьте `aors`, `context` и `identify` по задаче
- Сверьте результат `pjsip show endpoint <имя>`
3. Аутентификация: `auth` и `outbound_auth` не взаимозаменяемы
Третья типовая ошибка — поставить auth= везде, где встречается слово «авторизация». В PJSIP направление важно. auth у endpoint используется для проверки входящих запросов, когда удалённая сторона должна предъявить данные Asterisk. outbound_auth указывает объект auth, которым Asterisk ответит на вызов или регистрацию после challenge от удалённой стороны. У исходящего транка обычно есть отдельный объект [provider-auth] с type=auth, auth_type=userpass, username и password, а endpoint и registration ссылаются на него через outbound_auth. Пароль в статье или тикете не публикуйте: при диагностике достаточно показать имя объекта и скрыть секрет.
Пример связи: [provider-auth], type=auth, auth_type=userpass, username=ACCOUNT, password=REDACTED; в секции endpoint задаются outbound_auth=provider-auth и нужный aors, а в секции registration — outbound_auth=provider-auth, если для REGISTER требуется аутентификация. Это не готовый универсальный шаблон: часть операторов принимает исходящие вызовы без регистрации, часть требует регистрации, а иногда настройки для вызова и регистрации различаются. В руководстве по регистрации исходящего SIP-транка Asterisk показывает эти роли раздельно. Если сервер возвращает challenge, смотрите ответ и выбранный auth-объект, а не добавляйте пароль в случайную секцию.
Для учебного разбора «Бриз-Строй» предположим: один транк, 18 аппаратов, у оператора есть отдельный логин для регистрации. Тогда я сначала проверю, существует ли auth-секция и правильно ли на неё указывает outbound_auth именно в registration; для исходящего INVITE отдельно посмотрю endpoint. Успешный REGISTER ещё не гарантирует разрешение на исходящие вызовы: у оператора могут быть разные правила учётной записи, маршрута и caller ID. И наоборот, транк без регистрации может отправлять вызовы, если оператор так его выдал. Слова «без auth сервер всегда отвергнет» и «одна auth-секция нужна всему» технически не выдерживают проверки.
- Для исходящего challenge проверьте `outbound_auth`
- Для проверки входящих запросов проверьте `auth`
- Секреты маскируйте в логах и примерах
4. Регистрация: client_uri — не копия username
Четвёртая ошибка — требовать буквального совпадения client_uri с username в auth. client_uri задаёт SIP URI клиента для REGISTER; auth-секция содержит учётные данные, которыми Asterisk отвечает на запрос авторизации. Их значения нередко связаны, но формат и имя определяет оператор. У одной услуги логин может быть номером, у другой — отдельным именем; в URI также важен домен. Поэтому фраза «не совпало — регистрация невозможна» неверна без требований конкретного регистратора. Проверяйте server_uri, client_uri, outbound_auth, transport и ответ сервера вместе. Команда pjsip show registrations помогает увидеть состояние регистрации, но причина отказа находится в деталях обмена и ответе оператора.
server_uri указывает сервер регистрации, client_uri — адрес клиента в запросе REGISTER, outbound_auth — ссылку на данные для ответа на challenge. В некоторых сценариях outbound_auth не нужен вовсе: официальная документация прямо допускает регистрацию без него, если аутентификация не требуется. Не добавляйте sip_user: это не параметр, который надо подставить в секцию registration вместо client_uri. Не называйте любой отказ строкой «Registration failed» и не делайте из неё диагноз: сначала смотрите точный SIP-код, текст ответа и повторные попытки. Если регистрация горит, а вызовы всё ещё не идут, отдельно проверяйте AOR и исходящий маршрут. Это другой участок настройки.
В сценарии с «Бриз-Строй» я записал бы выданные оператором значения в закрытый рабочий лист, сверил бы их с тремя полями конфигурации и затем проверил вывод pjsip show registrations. Предположим, оператор просит URI вида sip:ACCOUNT@sip.example.com, но для digest-авторизации выдаёт отдельный username: это допустимое различие, если так требует его схема. В публикации нельзя подменять эту схему именем конкретного провайдера или обещать, что единый набор параметров подойдёт всем. Уточните у оператора, что должно находиться в URI и какое имя используется в challenge. SIP-конфигурация любит буквальные ответы на буквальные требования — догадки тут дорого обходятся.
- Сверьте `server_uri` с адресом регистратора
- Сверьте `client_uri` с форматом, выданным оператором
- Проверьте `outbound_auth` и фактический ответ сервера
5. Логи: включите трассировку и выключите её после проверки
Пятая ошибка — утверждать, что в Asterisk 20 PJSIP-логирование по умолчанию всегда выключено, а все записи обязательно лежат в /var/log/asterisk/messages. Наличие файла и состав каналов зависит от logger.conf и сборки. Для SIP-обмена в CLI есть команда pjsip set logger on; для общей детализации документация рекомендует core set verbose 4 и core set debug 4. Это помогает увидеть последовательность сообщений и ответы сторон, но не превращает любой лог в диагноз. Включайте трассировку на короткое время, воспроизводите проблему, отмечайте точное время, затем отключайте её (pjsip set logger off) и возвращайте уровни к прежним. SIP-логи могут содержать номера, адреса и другие чувствительные данные; перед отправкой наружу их нужно проверить и обезличить.
Я разбираю звонок по этапам. Если нет исходящего INVITE — смотрю dialplan и приложение набора. Если INVITE есть, но нет ответа — проверяю транспорт, адрес назначения и сетевой путь. Если приходит challenge, сопоставляю его с outbound_auth; если получен отказ — фиксирую код и текст ответа, не заменяя их догадкой. Для входящего вызова отдельно проверяю сопоставление endpoint, затем контекст и маршрут. В консоли полезны pjsip show endpoint <имя>, pjsip show registrations и pjsip show transports; точную доступность команды и вывод сверяйте с установленной версией и модулями. Похожую логику проверки по месту обрыва показывает статья о звонках, обрывающихся через 30 секунд: это отдельный симптом, не универсальное объяснение любой тишины.
В условном разборе компании «Бриз-Строй» я бы ограничил диагностику одним тестовым звонком, например на 10–15 минут, а не оставлял logger включённым «на всякий случай». Мы зафиксировали бы время, направление вызова и ожидаемый номер назначения; затем сопоставили бы вывод CLI с журналом и убрали секреты перед передачей файла. В статье я не утверждаю, будто такая авария действительно происходила у клиента: «Бриз-Строй» здесь только заданный условный пример. Моя практика простая: сначала доказать, на каком шаге пропал вызов, потом менять одну причину за раз и повторять тот же тест. Это экономит время и оставляет понятный след изменений.
- Включите `verbose`, `debug` и PJSIP logger
- Воспроизведите один известный сценарий
- Выключите трассировку и обезличьте журнал
Частые вопросы
Нужно ли указывать transport в каждой секции endpoint?
Нет. PJSIP может выбрать совместимый транспорт автоматически. Явная ссылка полезна, когда нужно зафиксировать конкретный транспорт; проверяйте фактический выбор командой `pjsip show transports` и настройками стороны назначения.
Что означает endpoint_id в pjsip.conf?
Обычно такой параметр не нужен: имя объекта задаётся именем секции, а тип — строкой `type=endpoint`. Проверяйте имя и загруженную конфигурацию через `pjsip show endpoint <имя>`.
Когда использовать auth, а когда outbound_auth?
`auth` у endpoint относится к проверке входящих запросов. `outbound_auth` указывает учётные данные, которыми Asterisk отвечает на исходящий challenge; точную схему сверяйте с настройками оператора.
Должен ли client_uri совпадать с username?
Не обязательно. `client_uri` формирует адрес клиента в REGISTER, а username используется в аутентификации. Сопоставьте оба значения с требованиями регистратора.
Применит ли pjsip reload изменение транспорта?
Обычная перезагрузка PJSIP не применяет изменения транспорта в стандартном случае. Документация Asterisk требует полного перезапуска, если не настроено специальное разрешение перезагружать транспорт.
Где искать SIP-лог Asterisk?
Расположение зависит от настроек логгера. Для временной диагностики включите `pjsip set logger on` в CLI, воспроизведите вызов и после проверки отключите трассировку.
Источники
- Asterisk Documentation: PJSIP configuration sections and relationships — Назначение endpoint, AOR, transport, identify и registration; формат секций. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/PJSIP-Configuration-Sections-and-Relationships/
- Asterisk Documentation: res_pjsip (Asterisk 20) — Параметры endpoint и auth, поведение транспорта и требование полного перезапуска для изменения транспорта. https://docs.asterisk.org/Asterisk_20_Documentation/API_Documentation/Module_Configuration/res_pjsip/
- Asterisk Documentation: Configuring Outbound Registrations — Роли server_uri, client_uri и outbound_auth при регистрации у SIP-провайдера. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Configuring-Outbound-Registrations/
- Asterisk Documentation: Collecting Debug Information — Команды verbose/debug и включение PJSIP trace в CLI; рекомендация отключать дополнительную отладку после воспроизведения. https://docs.asterisk.org/Operation/Logging/Collecting-Debug-Information/
- Asterisk Documentation: PJSIP Troubleshooting Guide — Рекомендуемые диагностические команды для сбора подробностей PJSIP. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Asterisk-PJSIP-Troubleshooting-Guide/



