Как найти сбой SIP-транка в контейнере Asterisk 21
Если после обновления Asterisk до 21-й версии пропали звонки, сначала проверьте SIP-драйвер, сетевой маршрут и адреса в SDP. Я разбираю диагностику по слоям: от регистрации PJSIP до RTP в Docker. Так вы отделите ошибку конфигурации от проблемы провайдера и не будете чинить несуществующие патчи.
1. Что изменилось в Asterisk 21 для SIP
Первая проверка после обновления Asterisk до 21-й версии — не Docker и не TLS. В этой версии удалён модуль chan_sip, который раньше читал sip.conf и обслуживал команды семейства sip. Для новых конфигураций используется PJSIP: его модуль называется chan_pjsip, а настройки обычно находятся в pjsip.conf. В официальном перечне изменений Asterisk 21 удаление chan_sip указано прямо. Если после обновления ваш старый сценарий ищет sip set debug on или sip show peers, он не «почти работает»: этих команд уже нет вместе с драйвером. Я видел, как администраторы часами сравнивали NAT, хотя начинать надо было с загруженных модулей.
Проверьте, что реально запущено, внутри того же контейнера, где работает Asterisk: asterisk -rx 'core show version', затем asterisk -rx 'module show like pjsip'. Для списка конечных точек используйте asterisk -rx 'pjsip show endpoints', а для SIP-трассировки — asterisk -rx 'pjsip set logger on'. Когда диагностика закончена, выключите подробный вывод командой asterisk -rx 'pjsip set logger off'. Эти проверки отвечают на разные вопросы: версия и модуль подтверждают состав программы, список endpoint показывает прочитанную конфигурацию, а logger показывает обмен сообщениями. Начните с настройки Asterisk в Docker, если нужен разбор сети и конфигурации вместе.
Не переносите файл sip.conf механически в pjsip.conf и не переименовывайте параметры наугад. PJSIP описывает транспорт, endpoint, объект аутентификации, AoR и при необходимости регистрацию отдельными объектами; один старый peer не превращается в один новый раздел с тем же набором строк. Сначала соберите сведения у оператора: адрес SIP-сервера, тип транспорта, учётные данные, формат номера, кодеки, правила входящих вызовов и способ регистрации. Затем сопоставьте каждое требование с PJSIP. Если транк работает по IP без регистрации, конфигурация будет отличаться от транка, которому нужны REGISTER и Digest-аутентификация. В документации Asterisk это не косметическое переименование: объекты отвечают за разные части SIP-соединения.
Есть и ещё одна ловушка: наличие секции в pjsip.conf не доказывает, что Asterisk принял её. Ошибка имени параметра, пропущенный type=endpoint или ссылка на несуществующий объект могут оставить конфигурацию неполной. Сверяйте не только файл, но и результат pjsip show endpoint ИМЯ и журнал запуска. Если нужный endpoint отсутствует в списке, сначала ищите синтаксическую ошибку и сообщения res_pjsip. Перезапускать Docker до чтения ошибки — как менять телефонный кабель, не посмотрев, включён ли аппарат. Ирония короткая, зато кабель цел.
- Asterisk 21 не содержит chan_sip
- PJSIP использует pjsip.conf
- Трассировка: pjsip set logger on
- Сверяйте конфигурацию с CLI
2. Как проверить NAT и адрес в SDP
Docker bridge сам по себе не ломает SIP, но контейнер получает внутренний адрес, и NAT может не переписать сведения о сигнализации и медиа так, как ожидает удалённая сторона. Для PJSIP за NAT в транспортном объекте рассматривают local_net, external_signaling_address и external_media_address; для endpoint часто отдельно проверяют direct_media. Это не универсальная вставка из четырёх строк: значения зависят от локальной подсети, внешнего адреса и топологии. Официальный пример Asterisk показывает, как внешний media-адрес используется для переписывания SDP при отправке за пределы local_net. Адреса из примера документации тестовые; в рабочей конфигурации указывают адрес своей сети и проверяют результат по фактическому SDP.
Разделите две вещи: SIP-сигнализация сообщает, кто звонит и куда, а RTP переносит звук. Регистрация может быть успешной, но медиа всё равно не пойдёт: в SDP окажется недоступный частный адрес или ответный поток не попадёт в контейнер. При одностороннем звуке сравните адрес и порт в строках c= и m= SDP с адресами, доступными удалённому участнику, и проверьте сетевые счётчики. Не делайте вывод «провайдер игнорирует запрос» лишь потому, что в телефоне тишина: сначала выясните, дошёл ли INVITE, пришёл ли ответ, согласовались ли кодеки и куда направлен RTP. Здесь полезно проверить почему пропадают звонки в Asterisk Docker, но причина после перезапуска контейнера может отличаться от ошибки NAT.
Для контейнера с обычным bridge проверьте публикацию тех портов и протоколов, которые действительно настроены в Asterisk и согласованы с оператором. В документации Asterisk для одного NAT-сценария показаны входящие TCP/UDP 5060 и UDP 10000–20000, перенаправленные на внутренний сервер; это пример, а не обязательный диапазон для каждого инсталляции. Фактический RTP-диапазон задаётся конфигурацией Asterisk, обычно в rtp.conf. Опубликовать 5060/UDP, но забыть RTP — получить рабочий обмен приглашениями без гарантии звука. А публиковать весь диапазон «на всякий случай» без сверки с настройками — способ усложнить правила firewall.
Проверьте путь пакета на каждом слое: публикация порта Docker, правила межсетевого экрана хоста, маршрутизатор или облачный firewall, затем сокет процесса. В docker compose запись порта должна включать нужный протокол, а диапазон — совпадать с тем, который настроен для RTP. Параметр --network=host не является обязательным лекарством и меняет сетевую модель контейнера; включать его только потому, что «так советуют для телефонии», не нужно. Сначала зафиксируйте сетевой режим, слушающие сокеты и направление пакетов. Команда ss -lunp на хосте и захват tcpdump на интерфейсе помогают понять, где пропадает UDP-пакет. Отсутствие вывода в Asterisk ещё не доказывает, что виноват firewall внутри контейнера.
- PJSIP NAT: local_net и внешние адреса
- Сверьте SDP и фактический RTP-диапазон
- Проверьте публикацию UDP в Docker
- Не назначайте host-сеть вслепую
3. Как отличить ошибку регистрации от потери RTP
Сначала наблюдайте за сигнализацией во время одной контролируемой попытки вызова. Включите pjsip set logger on, выполните звонок и отметьте, появляется ли исходящий INVITE, какой ответ возвращает оператор и чем завершается диалог. Код ответа сам по себе не является диагнозом: 401 может быть Digest-вызовом аутентификации; посмотрите WWW-Authenticate и проверьте, следует ли повторный запрос с Authorization. Если обмен заканчивается отказом, выясняйте причину по полному диалогу и данным оператора. Ответ 403 означает запрет запроса, но сам код не объясняет, какое правило сработало. Официальный troubleshooting guide Asterisk рекомендует собирать сведения через PJSIP logger и проверять наличие endpoint в CLI; смысл кодов и обработку аутентификации задаёт RFC 3261.
Если регистрации нет, проверьте, что endpoint и связанные объекты действительно загружены, совпадают имена ссылок auth и aors, а учётные данные, realm и адрес сервера соответствуют данным оператора. Команды pjsip show endpoint ИМЯ, pjsip show aor ИМЯ и pjsip show registrations дают более полезную картину, чем случайный grep по конфигурации. Для входящего вызова проверьте сопоставление источника с endpoint: PJSIP должен определить, к какому endpoint относится пакет. Если пакеты от транка приходят, но endpoint не совпадает, проверьте объект identify и его адресные правила. Не открывайте доступ всем источникам вместо корректного сопоставления — это не диагностика, а расширение поверхности атаки.
Если SIP-обмен завершился нормально, но звука нет или слышно только одну сторону, переходите к медиапути. Во время активного звонка можно включить rtp set debug on, затем после проверки выполнить rtp set debug off. Команда показывает наблюдаемые RTP-пакеты в консоли, но не исправляет маршрут и не заменяет захват трафика на сетевом интерфейсе. Сопоставьте адреса отправителя и получателя из вывода с SDP и правилами NAT. Убедитесь, что пакеты доходят до хоста, публикуются в контейнер и уходят обратно к удалённому участнику. Если пакетов нет уже на внешнем интерфейсе, Asterisk тут ни при чём; если они приходят на хост, но не контейнер, смотрите публикацию портов и firewall.
Включённая трассировка печатает содержимое SIP-диалога, включая адреса и служебные данные; не оставляйте её без причины и не отправляйте необработанный лог в общий чат. Сохраните короткий фрагмент с временем, направлением, кодом ответа и обезличенными идентификаторами. При необходимости используйте docker compose logs --since=5m ИМЯ_СЕРВИСА, подставив фактическое имя сервиса из своего Compose-файла. Команды netstat -tunlp | grep 5060 и sip set debug on из старых инструкций не универсальны для минимального образа и Asterisk 21: netstat может отсутствовать, а sip set debug относится к удалённому драйверу. Лучше знать, какой вопрос решает каждая команда.
- SIP: pjsip set logger on/off
- Проверьте endpoint, AoR и регистрацию
- RTP: rtp set debug on/off
- Сверьте пакеты на хосте и в контейнере
4. Что проверить в TLS и сертификатах
TLS имеет смысл проверять, только если транк действительно использует TLS. В Asterisk 21 настройки относятся к PJSIP и транспортному объекту в pjsip.conf, а старые параметры tlsenable, tlsbindaddr и tlscertfile из примера для chan_sip нельзя без проверки переносить в конфигурацию этой версии. Официальный учебный материал Asterisk описывает конфигурацию защищённых вызовов; объект транспорта задаёт протокол TLS и файлы сертификата и ключа. Точные имена опций зависят от требуемого сценария и версии, поэтому сверяйте их с актуальной справкой модуля и документацией установленной версии, а не с чужим compose-файлом.
Проверьте, что TCP-порт для SIP-TLS опубликован и доступен на нужном интерфейсе, сертификат и закрытый ключ смонтированы по путям, которые видны именно внутри контейнера, а пользователь процесса Asterisk может их прочитать. Убедитесь, что сертификат соответствует имени узла, цепочка доверия полная, а срок действия актуален. Если TLS-соединение не устанавливается, снимите точное сообщение журнала и проверьте согласование версии протокола, шифров и проверки сертификата с оператором. Не ослабляйте проверку сертификата и не заставляйте сервер «откатываться» до старой версии TLS по совету без подтверждения. Шифрование не лечит неверный адрес в SDP, а UDP-порты RTP не становятся TLS только потому, что SIP-сигнализация зашифрована.
У Asterisk есть несколько конфигурационных уровней, которые легко перепутать: TLS защищает SIP-сигнализацию между узлами, а защита медиапотока — отдельный вопрос. Если оператор требует только TLS для транка, уточните, использует ли он обычный RTP или SRTP, какие сертификаты ожидает и проверяет ли имя сервера. Согласуйте транспорт с endpoint и регистрацией, иначе транспорт может быть правильно описан, но не применяться к конкретному транку. Затем проверьте handshake и обмен REGISTER/INVITE отдельно. Разбор TLS handshake отвечает, почему стороны не договорились о защищённом соединении; PJSIP logger отвечает, что произошло после начала SIP-диалога. Смешивать эти этапы — всё равно что искать причину отказа домофона в настройках микрофона.
В исходной версии статьи утверждалось, будто Asterisk 21 в Docker всегда собирается с OpenSSL 3.0, требует определённые musl-патчи и что tlsclientmethod=tlsv1_2 — обязательное исправление. Универсального основания для такой связки нет: библиотека и опции зависят от конкретного образа и сборки, а названные параметры относились к другой конфигурационной модели. Я убрал эти рецепты. Если есть конкретная ошибка загрузки модуля или TLS handshake, фиксируйте версию образа, вывод core show version, сведения о сборке и текст ошибки; только потом подбирайте совместимое исправление. Миф о волшебном патче обычно переживает сам баг.
- TLS настраивается в PJSIP-транспорте
- Сверьте сертификат, ключ и права
- Проверяйте TLS и RTP раздельно
- Не навязывайте TLS 1.2 без причины
5. План проверки после изменения конфигурации
До правки сохраните конфигурацию и зафиксируйте, что именно меняете: версию образа, SIP-транспорт, NAT-адреса, публикацию портов или правила firewall. Не меняйте всё одновременно. Иначе даже удачный результат не покажет, какое действие помогло, а неудачный размоет исходную причину. Сверьте ожидаемый RTP-диапазон в rtp.conf с Docker Compose и внешним firewall; проверьте, что TCP/UDP протоколы соответствуют транспорту SIP. При изменении PJSIP transport учитывайте, что для применения ряда параметров транспорта может потребоваться перезапуск Asterisk. Планируйте его отдельно и не маскируйте сетевую проблему пересозданием контейнера.
После запуска проверьте core show version, наличие chan_pjsip, список endpoint, регистрации и слушающие адреса. Затем выполните один исходящий и один входящий вызов, если оба направления нужны. Для каждого сохраните результат отдельно: INVITE и ответ оператора, параметры SDP, факт прихода RTP, двусторонний звук. Так станет видно, ломается ли регистрация, маршрутизация вызова, согласование кодека или медиа. Перезагрузка контейнера не является тестом звонка: она лишь показывает, что процесс стартует. Убедитесь также, что после рестарта конфигурация не пропадает и что используются именно тот образ и тома, которые вы проверяли. Для соседнего случая с кодеками пригодится материал об ошибках кодеков Asterisk.
Ведите короткую таблицу наблюдений: этап, ожидаемый результат, фактический результат и следующий слой проверки. Например: «REGISTER — ответ 401, затем 200; endpoint зарегистрирован» или «INVITE принят, SDP содержит частный адрес, RTP не приходит». Не записывайте реальные пароли и адреса клиентов в статью, тикет или публичный чат. Для сравнения используйте обезличенные значения, а исходные логи храните с ограниченным доступом. Если переносите настройку между стендом и рабочей системой, отдельно проверьте подсети, внешний адрес, портовую публикацию и credentials: одинаковый файл не означает одинаковую сеть.
Я считаю задачу решённой не когда контейнер стал зелёным в панели, а когда тестовый вызов проходит в нужных направлениях, собеседники слышат друг друга, а после штатного рестарта конфигурация и соединение возвращаются. Оставьте выключенными отладочные команды, сохраните конфиги и запишите, какие порты открыты и зачем. Если оператор меняет адреса, транспорт или диапазон RTP, вернитесь к тем же проверкам, а не к старому чек-листу, где 5060 и 10000–20000 объявлены священными числами. Телефония не обязана работать по чужому шаблону. Она обязана работать по согласованной схеме.
- Меняйте по одному параметру
- Проверьте входящий и исходящий вызов
- Зафиксируйте SDP и направление RTP
- Выключите отладку после проверки
Частые вопросы
Работает ли chan_sip в Asterisk 21?
Нет. Модуль chan_sip удалён в Asterisk 21; для SIP используйте PJSIP и конфигурацию pjsip.conf.
Как включить SIP-отладку в Asterisk 21?
В CLI выполните `pjsip set logger on`, а после проверки отключите командой `pjsip set logger off`.
Какие порты открыть для RTP в Docker?
Откройте настроенный в Asterisk RTP-диапазон UDP и опубликуйте его в Docker и firewall. Точный диапазон зависит от конфигурации; 10000–20000 — пример из документации, не обязательное значение.
Почему регистрация есть, а звука нет?
Регистрация проверяет SIP, а звук идёт по RTP. Сверьте адреса в SDP, NAT, публикацию RTP-портов и прохождение пакетов в обе стороны.
Нужны ли Asterisk 21 musl-патчи для Docker?
Универсального требования нет. Сначала установите, какой образ и сборка используются, и ищите конкретное сообщение об ошибке; не применяйте неподтверждённый патч наугад.
Источники
- Asterisk 21: что нового — Официальный список изменений подтверждает удаление chan_sip в Asterisk 21. https://docs.asterisk.org/Asterisk_21_Documentation/WhatsNew/
- PJSIP за NAT — Официальное руководство описывает local_net, external_media_address, external_signaling_address, direct_media и пример проброса SIP/RTP-портов. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Configuring-res_pjsip-to-work-through-NAT/
- Руководство по диагностике PJSIP — Официальная документация проверяет pjsip set logger on, pjsip show endpoints и разбор типовых ошибок PJSIP. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Asterisk-PJSIP-Troubleshooting-Guide/
- Сбор диагностических данных Asterisk — Официальная документация перечисляет команды отладки; pjsip set logger on предназначена для нового PJSIP-драйвера. https://docs.asterisk.org/Operation/Logging/Collecting-Debug-Information/
- Учебник по защищённым вызовам — Официальный учебный материал Asterisk описывает настройку защищённой SIP-связи и TLS. https://docs.asterisk.org/Deployment/Secure-Calling/Secure-Calling-Tutorial/
- RFC 3261: SIP — Первичный стандарт описывает ответы 401/403 и Digest-аутентификацию в SIP. https://www.rfc-editor.org/rfc/rfc3261.html



