Asterisk 21 в Docker: почему не идут звонки
АйТи Фреш
Серверы и инфраструктура

Как найти сбой SIP-транка в контейнере Asterisk 21

Автор: , директор ООО «АйТи-Фреш» · · ~14 мин чтения
Схема-загадка звонка Asterisk в Docker: сигнал проходит, RTP теряется
SIP проходит, RTP теряется

Если после обновления 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 до чтения ошибки — как менять телефонный кабель, не посмотрев, включён ли аппарат. Ирония короткая, зато кабель цел.

Старые команды sip.* в Asterisk 21 не заменяют проверку PJSIP: сначала подтвердите драйвер и загруженные endpoint.
Схема PJSIP и RTP для Asterisk 21 в Docker
Asterisk 21 использует PJSIP

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 внутри контейнера.

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 относится к удалённому драйверу. Лучше знать, какой вопрос решает каждая команда.

Тишина — симптом, а не диагноз. Сначала отделите сигнализацию от медиапотока.
Если после проверки драйвера, PJSIP и NAT причина всё ещё не ясна, мы разберём конфигурацию и сетевой маршрут вместе: от SIP-ответа до RTP-пакета. Обсудить задачу
Диагностика SIP и RTP в Docker по этапам звонка
Сначала найдите потерянный этап

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, сведения о сборке и текст ошибки; только потом подбирайте совместимое исправление. Миф о волшебном патче обычно переживает сам баг.

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 объявлены священными числами. Телефония не обязана работать по чужому шаблону. Она обязана работать по согласованной схеме.

Проверка PJSIP, регистрации, NAT и RTP в Asterisk Docker
Звонок проверен по всем слоям

Частые вопросы

Работает ли 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?

Универсального требования нет. Сначала установите, какой образ и сборка используются, и ищите конкретное сообщение об ошибке; не применяйте неподтверждённый патч наугад.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи