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

Как найти сбой TLS в Asterisk и вернуть звонки

Автор: , директор ООО «АйТи-Фреш» · · ~13 мин чтения
Маршрут TLS-сигнализации Asterisk и отдельный путь аудио
Проверяйте сбой по слоям

Если после включения TLS в Asterisk не проходят звонки, сначала выясните, где обрывается цепочка: TCP-соединение, проверка сертификата, SIP-обмен или RTP-аудио. Я разбираю эти уровни по порядку, показываю корректные параметры PJSIP и объясняю, почему один открытый порт не чинит всё сразу.

Сначала определите, на каком этапе рвётся звонок

TLS защищает SIP-сигнализацию между участниками соединения. Сам по себе включённый TLS не означает, что аудио тоже зашифровано: голос обычно передаётся отдельно по RTP, а для шифрования медиапотока настраивают SRTP. Поэтому фраза «включили TLS — звонки сломались» пока не диагноз. Это только отметка времени, после которой нужно сравнить поведение до и после изменения. В сложных случаях я подключаю поддержку ИТ-инфраструктуры и начинаю с трёх вопросов: устанавливается ли TCP-соединение, проходит ли TLS-рукопожатие, видит ли Asterisk SIP-запрос INVITE? Если INVITE уже дошёл, сертификатная часть могла отработать, и искать причину нужно дальше по SIP-ответам и маршруту вызова.

Сначала откройте консоль Asterisk и снимите короткий фрагмент лога во время одной контрольной попытки. Для PJSIP включите протокольную трассировку командой pjsip set logger on, затем сразу воспроизведите сбой; после сбора выключите её командой pjsip set logger off, чтобы не оставлять подробный лог включённым без нужды. Смотрите, дошёл ли INVITE, что отвечает удалённая сторона и на каком шаге появляется ошибка. Если нужна базовая схема объектов, пригодится разбор настройки PJSIP в Asterisk. Для проверки загруженных объектов подойдут pjsip show transports, pjsip show endpoints и pjsip show endpoint <имя>. Команда sip show peers относится к chan_sip; при PJSIP она не является проверкой регистрации или состояния endpoint. Команды должны соответствовать драйверу, а не привычке.

Не привязывайте любой отказ к сертификату. Ответ SIP 403 — это отказ на уровне SIP-политики или авторизации, а не универсальный код «сертификат не подошёл». Ошибка TCP-соединения означает, что удалённый узел не установил транспорт; сообщение о TLS handshake указывает на TLS-уровень; полученный INVITE без подходящего маршрута ведёт уже к диалплану. Разные причины дают разные следы. Сохраните время попытки и небольшой участок лога вокруг неё, иначе в общем журнале легко смешать регистрацию, входящий вызов и фоновый обмен OPTIONS. Это скучная дисциплина, зато она дешевле гадания по конфигу.

Условный пример: на одной АТС регистрация телефона оставалась активной, а исходящий вызов не соединялся после смены транспорта. Мы бы не стали немедленно перевыпускать весь парк сертификатов. Сначала проверили бы, какой endpoint инициирует вызов, какой transport к нему привязан и виден ли INVITE в PJSIP-логе. Если INVITE уходит, а ответ не возвращается, проверяем путь обратно и внешние адреса; если он не уходит, проверяем состояние endpoint и правила набора. Если рукопожатие вообще не состоялось — возвращаемся к сертификату, версии TLS, имени узла и TCP-доступности. Такой порядок не обещает чудес, но быстро отсекает неподходящие версии.

Не публикуйте полный SIP-лог: в нём могут быть номера и данные авторизации.
Диагностика TLS-звонка в Asterisk по сетевым этапам
Ищите первый неуспешный этап

Проверьте сертификат и ключ как пару

Для PJSIP в секции transport используются cert_file и priv_key_file; tls_cert_file и tls_private_key — неверные названия параметров для этого примера. Сертификат и закрытый ключ должны соответствовать друг другу, быть доступны процессу Asterisk и иметь читаемый формат. Сертификатный файл сам по себе не обязан содержать ключ: в конфигурации можно указать отдельные файлы. В официальном примере Asterisk также используется отдельная цепочка CA для проверки доверия. Не копируйте названия полей между sip.conf и pjsip.conf: у старого chan_sip и PJSIP разные настройки, а похожее имя файла ещё не делает параметр совместимым.

Проверьте, что именно лежит в путях, указанных в активном transport, а затем выведите срок действия и subject сертификата: openssl x509 -in /путь/к/cert.pem -noout -subject -issuer -dates. Эта команда помогает прочитать сертификат; она не подтверждает сама по себе, что ключ ему соответствует, что цепочка доверия полная или что имя сервера совпало с тем, которое проверяет клиент. Проверьте также владельца и права доступа файла от имени пользователя службы. Не выкладывайте ключ в тикет, чат или статью — закрытый ключ не диагностический лог. Если требуется взаимная аутентификация, отдельно разберитесь с ca_list_file, verify_client и require_client_cert в документации именно вашей версии.

Сопоставление имени важно для стороны, которая проверяет сертификат сервера: ожидаемое DNS-имя или адрес должны соответствовать сертификату и настройке клиента. Но утверждение «CN не совпал — звонок всегда не пойдёт» слишком грубое: результат зависит от того, кто выступает TLS-клиентом, включена ли проверка сервера и как устроена проверка имён в конкретном стеке. Не лечите ошибку отключением проверки на постоянной основе. Сертификатная проверка — часть общей безопасности Asterisk. Для диагностики сначала установите, какую сторону и какое имя проверяет лог, затем исправьте сертификат, доверенную CA или адрес подключения. Если проверка отключается ради изолированного теста, верните её в штатную конфигурацию до публикации сервиса.

Утилита ast_tls_cert присутствует в официальном руководстве Asterisk как способ создать тестовый CA, сертификат сервера и клиентские сертификаты. Её ключи и ожидаемые файлы зависят от конкретного скрипта, поэтому команда из чужой статьи вроде ast_tls_cert -C /etc/asterisk/keys не годится как универсальная инструкция: -C задаёт common name, а не каталог назначения. В официальном учебном примере команда выглядит так: ./ast_tls_cert -C pbx.example.com -O "Example" -d /etc/asterisk/keys -b 2048. Это пример генерации самоподписанного CA и сертификата, а не команда для слепого копирования в рабочую систему. Для боевого сервиса обычно используют сертификат от доверенного CA и процедуру его регулярного обновления; наличие скрипта в пакете не делает самоподписанный сертификат автоматически подходящим для телефонов.

Настройте PJSIP transport, не смешивая его с endpoint

Минимальная основа TLS-транспорта в pjsip.conf выглядит так; реальные пути и сетевые адреса подставляют свои. Здесь показаны параметры транспортного объекта, а не весь телефонный профиль: endpoint, AoR, авторизация и dialplan настраиваются отдельно.

[transport-tls] type=transport protocol=tls bind=0.0.0.0:5061 cert_file=/etc/asterisk/keys/asterisk.crt priv_key_file=/etc/asterisk/keys/asterisk.key

Нельзя свести рабочий вызов к наличию transport=tls. PJSIP связывает транспорт с endpoint, AoR, правилами определения входящего endpoint и контекстом диалплана. Параметр allow задаёт список допустимых кодеков; он не включает TLS и не устраняет ошибку рукопожатия. Если список кодеков пуст или не совпадает с возможностями второй стороны, сигнализация может пройти, но медиасогласование вызова завершится неудачно или без общего кодека. Поэтому allow=all — не волшебный ремонт. Укажите только реально нужные и поддерживаемые кодеки по политике вашей АТС.

Не объявляйте порты 5060 и 5061 обязательной парой и не называйте сам факт их использования конфликтом. В примере Asterisk TLS привязан к TCP-порту 5061, но конкретный порт задаётся bind; одновременно два transport не могут занять один и тот же адрес с одним и тем же портом. Это ограничение сокета, а не запрет иметь UDP и TLS рядом. Проверьте, на каком адресе и порту действительно слушает процесс, какой порт указан в телефоне или транке и совпадает ли это с сетевым фильтром. У одного из узлов может быть нестандартная схема — универсальное значение из примера её не отменяет.

Transport-конфигурация PJSIP имеет важную особенность: после её правки обычно нужен полный перезапуск Asterisk; одной перезагрузки конфигурации модуля недостаточно, если только транспорт не настроен для допустимой перезагрузки и это поддерживает ваша версия. Планируйте его в согласованное окно, потому что перезапуск влияет на вызовы. Перед ним проверьте синтаксис по документации сборки и сохраните копию исходного файла. В CLI после запуска посмотрите pjsip show transports и проверьте журнал старта на ошибки разбора. Если transport не загрузился, дальнейшие изменения кодеков и dialplan не исправят первичную ошибку.

Не отключайте проверку сертификата для постоянной работы ради быстрого зелёного статуса.
Я могу проверить TLS transport, сертификаты и сетевой маршрут на вашей АТС, а затем подтвердить исправление контрольным вызовом. Обсудить задачу
Схема параметров PJSIP transport TLS и связанных настроек
Не смешивайте сигнализацию и медиа

Разделите TCP-сигнализацию, firewall и NAT

Для SIP over TLS нужен доступ к TCP-порту, на котором слушает TLS transport. Правило iptables -A INPUT ... из случайной инструкции — не универсальный фикс: на сервере могут работать nftables, firewalld, облачный firewall, ACL маршрутизатора и отдельные правила на телефонии. Открывайте ровно тот порт и только с тех адресов, которым он нужен, учитывая входящее и ответное направление в вашей политике. Убедитесь, что правило попало в активную цепочку и не перекрыто более ранним запретом. Проверить, что процесс слушает, можно средствами ОС, а доступность с другой стороны проверяйте с того сетевого сегмента, откуда подключается телефон или транк.

TLS защищает SIP-сигнализацию по TCP, а RTP-медиа остаётся отдельным потоком. Поэтому ситуация, когда регистрация и вызов устанавливаются, но нет аудио или слышит только одна сторона, обычно требует проверки SDP, RTP-маршрута, NAT и диапазона медиапортов, а не повторного выпуска сертификата. TLS не «переносит» голос через свой порт. В разборе звонка сопоставьте адреса и порты в SDP с тем, что реально доступно на маршрутизаторе, и проверьте обе стороны аудиопотока. Если нужен шифрованный голос, отдельно настраивается SRTP и согласуется совместимость клиентов; одного TLS для этого недостаточно.

При размещении за NAT официальное руководство PJSIP описывает local_net, external_signaling_address и external_media_address в секции transport. Они решают разные задачи: внешний адрес сигнализации и адрес RTP в SDP не являются взаимозаменяемыми. Asterisk применяет внешние адреса с учётом локальной сети и условий обмена, а не просто заменяет любой адрес во всех пакетах. Не вставляйте случайный IP из примера в конфиг; используйте адрес своей схемы и корректную маску локальной сети. Если у сигнализации и медиа разные внешние адреса или есть SIP-прокси, конфигурация будет зависеть от топологии.

Если регистрация отображается как успешная, это ещё не гарантия, что исходящий INVITE пройдёт тем же путём или что ответ и аудио вернутся. Проверьте настройки транспорта у конкретного endpoint, контакт в AoR, адрес назначения транка и маршрут в dialplan. На сети проверьте состояние TCP-сессии и прохождение пакетов, а для медиапроблем отдельно изучите RTP. Если используется SIP ALG, проверьте документацию маршрутизатора и наблюдаемое поведение: не объявляйте его причиной без подтверждения. Сетевые устройства иногда переписывают SIP-содержимое и мешают согласованности адресов, но это гипотеза для проверки, не диагноз по умолчанию.

Проверьте исправление одним контролируемым вызовом

После правки я фиксирую исходное состояние, перезапускаю Asterisk только если менялся transport или этого требуют настройки, затем проверяю, что transport загрузился и endpoint виден. В CLI помогают pjsip show transports, pjsip show endpoints и pjsip show endpoint <имя>. Далее включаю pjsip set logger on, выполняю один тестовый звонок и записываю, дошёл ли INVITE, какой ответ вернулся и состоялось ли завершение вызова. Затем выключаю трассировку. Не считайте строку «Registered» доказательством исправного аудио: она говорит о регистрации, а не о маршруте RTP или совместимости кодеков.

Для отдельной проверки TLS-слушателя можно использовать openssl s_client -connect имя-узла:порт -servername имя-узла -showcerts. Укажите тот порт, который реально настроен, и DNS-имя, ожидаемое сертификатом. Успешное TLS-соединение показывает, что удалённый процесс ответил на TLS и передал сертификатную цепочку; оно не проверяет регистрацию SIP, настройки endpoint, авторизацию, маршрут набора или наличие RTP. При тестировании от самого сервера результат может отличаться от теста с телефона за NAT или с внешней сети, поэтому проверяйте с нужной точки подключения.

Проведите вызов в обе стороны и отдельно проверьте слышимость обоих абонентов. Смотрите на SIP-ответы, SDP, согласованный кодек и факт двусторонней передачи RTP. Если соединение установлено, но нет медиа, возвращайтесь к сетевым адресам, диапазону медиапортов, direct media и настройкам SRTP; если INVITE не появился, разбирайте transport, endpoint и dialplan. Сравните результаты до и после изменения, не меняя сразу несколько параметров. Одно изменение за раз — не медлительность, а способ понять, что именно помогло.

Сертификаты требуют учёта срока действия и проверки процедуры обновления. Уведомление заранее полезно, но конкретное число дней — внутренняя политика, а не встроенное правило Asterisk. После обновления проверьте, подхватил ли файл процесс и требуется ли для этого полный перезапуск в вашей версии; отдельно убедитесь, что клиенты доверяют CA и видят правильное имя сервера. Для транспортов без allow_reload=yes документация предупреждает, что изменения вступают в силу только после полного перезапуска. Не запускайте его автоматически посреди рабочего дня: предусмотрите окно и контрольный вызов после работ.

Диагностика завершена только после проверки вызова и звука в обе стороны.
Контрольный список проверки PJSIP TLS-звонков
Подтвердите звонок и двусторонний звук

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

Какие параметры сертификата нужны для PJSIP TLS?

В секции transport указывают `cert_file` и `priv_key_file`; при проверке доверия настраивают CA и соответствующие параметры проверки. Точные параметры сверяйте с документацией вашей версии.

Почему при рабочей регистрации не проходит звонок?

Регистрация не подтверждает, что INVITE проходит по нужному endpoint и маршруту. Проверьте PJSIP-лог, ответы SIP, транспорт и dialplan.

Порт 5061 обязателен для TLS?

Нет. Это типичный пример из документации Asterisk; фактический порт задаётся в `bind` TLS transport и должен совпадать с настройками клиента и firewall.

Шифрует ли SIP TLS голос?

TLS защищает SIP-сигнализацию. Для шифрования медиапотока отдельно настраивают SRTP и проверяют совместимость устройств.

Нужно ли перезапускать Asterisk после правки transport?

Документация PJSIP указывает, что изменения transport обычно применяются только после полного перезапуска; проверьте условия своей версии и планируйте окно.

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

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

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

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

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

Источники

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