Нет звука в Asterisk на AlmaLinux: где на самом деле теряется голос и при чём тут ALSA с PulseAudio
Если Asterisk на AlmaLinux соединяет вызов, а абоненты слышат тишину, сначала проверьте RTP, межсетевой экран и адреса в SDP, а не звуковую карту. SIP может успешно установить вызов, хотя медиапоток не проходит. Ниже — мой порядок проверки, команды и редкий случай, когда звуковая подсистема действительно важна.
Почему Asterisk соединяет звонок, а в трубке тишина
Начну с неприятного: большинство инструкций по запросу «asterisk нет звука» отправляют вас ковырять ALSA, ставить alsa-utils и перезапускать PulseAudio. На сервере, который обслуживает SIP-телефоны и транк провайдера, это почти всегда пустая трата вечера. Голос между телефоном и Asterisk идёт по сети, пакетами RTP по UDP, а звуковая карта сервера в этом разговоре вообще не участвует. Если у вас нет опыта, а телефония нужна вчера, проще отдать это на ИТ-аутсорсинг для офиса, но разобраться самому тоже реально — ниже порядок, которым пользуюсь я. Сначала доказываем, где теряется звук, потом чиним.
Сигнализация SIP и медиа живут отдельно. Для SIP часто используют 5060/UDP или 5060/TCP, но порт зависит от транспорта и настроек вашей АТС. SIP договаривается о вызове: кто звонит, куда, какие кодеки, на какой адрес и порт слать звук. Затем телефоны и Asterisk обмениваются RTP в диапазоне, заданном в /etc/asterisk/rtp.conf параметрами rtpstart и rtpend. Если SIP прошёл, а RTP нет, телефон звонит, трубку снимают, длительность разговора тикает, а в динамике тишина. Иногда звук есть только в одну сторону — это отдельный симптом, а не готовый диагноз. Он помогает выбрать следующий шаг проверки.
Поэтому первая проверка — не драйверы, а маршрут пакетов. Я смотрю межсетевой экран на сервере, затем NAT между телефоном и Asterisk, потом кодеки и звуковые файлы. К звуковой подсистеме ОС перехожу только если используется локальная консоль или устройство. Такой порядок ведёт от сетевого пути к редким случаям, не заставляя переставлять драйверы вслепую. Скорость диагностики зависит от схемы сети и доступа к оборудованию: обещать универсальные пять или пятнадцать минут было бы рекламой, а не практикой.
Ошибка 1: искать звук в ALSA и PulseAudio, когда он идёт по сети
Когда ALSA и PulseAudio вообще имеют отношение к Asterisk? Только если используется канал, работающий со звуковым устройством сервера, например chan_console через PortAudio. Это может понадобиться для локальной консоли или оповещения через подключённые колонки. В обычном разговоре SIP-телефона с АТС звук идёт по сети, поэтому состояние звуковой карты на него не влияет. Я сначала проверяю загруженные каналы: если конфигурация не использует консольный аудиоканал, переустановка alsa-utils не объяснит пропажу RTP.
Если локальный канал нужен, проверьте доступ к устройству и то, какой процесс его занял. При графической среде пользовательский аудиосервер может уже работать с картой; состав звуковых компонентов зависит от установки AlmaLinux и выбранной среды, поэтому PipeWire или PulseAudio нельзя объявлять виновником по одному названию ОС. Пользователю службы Asterisk могут быть недоступны устройства в /dev/snd, а номер карты может указывать на HDMI вместо нужного входа или выхода. Сначала выясните устройство и права, потом меняйте конфигурацию аудиоканала. Запрет фоновой службе забирать карту вслепую — не диагностика, а ещё одна переменная.
В исходном коде Asterisk chan_console использует PortAudio и описан как замена устаревшим chan_alsa и chan_oss. Это не означает, что chan_console есть в каждой сборке: проверьте список реально загруженных модулей и зависимости своей версии. Я обычно не устанавливаю на сервер телефонии графическую среду и звуковой стек, если локальная аудиоконсоль не входит в задачу. А когда нужны громкая связь и оповещение, сначала оцениваю отдельный SIP-шлюз: так проще отделить аудиоустройство от роли АТС.
- asterisk -rx "module show like chan_" — какие каналы реально загружены
- aplay -l (пакет alsa-utils) — какие звуковые карты видит система
- id asterisk — входит ли служебный пользователь в группу audio
- fuser -v /dev/snd/* — какой процесс держит звуковое устройство
Ошибка 2: firewalld пропускает SIP, но режет RTP
На AlmaLinux firewalld часто управляет правилами хоста. В поставляемом firewalld определение службы sip открывает TCP и UDP порт 5060, если этот сервис доступен в установленной версии. Но SIP и RTP — разные потоки: одно правило для SIP не открывает медиа. Проверьте фактический транспорт и порт в конфигурации Asterisk, затем добавьте в firewall UDP-диапазон, совпадающий с эффективными rtpstart и rtpend. В образце rtp.conf Asterisk указаны 10000–20000, но комментарий отдельно задаёт значения по умолчанию 5000–31000. Поэтому диапазон из примера нельзя выдавать за универсальное значение по умолчанию. Если транк приходит с известных адресов, ограничьте доступ правилами firewalld подходящей зоны или rich rules.
Я сверяю три места: rtp.conf, правила firewalld и правила на маршрутизаторе, если телефоны или провайдер находятся снаружи. Проверьте, что адрес, порт и протокол совпадают на каждом участке. Для постоянного правила используйте --permanent, затем примените изменение через reload; сохраните и проверьте итоговый набор правил. Иначе конфигурация runtime может отличаться от permanent и после перезапуска поведение изменится. Расхождение легко принять за неисправность транка — такая версия удобна, но пакеты от этого не начинают ходить.
Ещё одна вещь, которую стоит проверить на AlmaLinux, — SELinux. Сам по себе он редко мешает RTP, если Asterisk установлен из пакетов и использует стандартные пути, но при сборке из исходников и нестандартных каталогах звуковых файлов я видел отказы в журнале audit. Отключать SELinux целиком не нужно: посмотрите ausearch по процессу asterisk и поправьте контекст. Отключённый SELinux — это не решение, а отложенная проблема. Если ausearch пуст, SELinux не при делах, и время на него тратить не нужно — возвращайтесь к сети. Если отказы есть, audit2why объяснит, что именно запрещено и почему.
- firewall-cmd --permanent --add-service=sip
- firewall-cmd --permanent --add-port=5000-31000/udp — только если этот диапазон задан в вашем rtp.conf
- firewall-cmd --reload && firewall-cmd --list-all
- ausearch -m AVC -c asterisk — отказы SELinux по процессу
Ошибка 3: NAT и кодеки — звук уходит не туда или не декодируется
Если сервер стоит за NAT, а телефоны или транк снаружи, проверьте SDP: Asterisk может сообщать удалённой стороне адрес, недоступный из её сети. В PJSIP внешние адреса и local_net задаются на объекте transport; настройки должны соответствовать реальной схеме адресации. На endpoint для устройств за NAT могут применяться rtp_symmetric, force_rport и rewrite_contact, но включать их всем подряд без разбора не нужно. rtp_symmetric возвращает RTP на адрес и порт, откуда он пришёл; force_rport влияет на адрес и порт для SIP-ответа, а rewrite_contact использует адрес источника запроса вместо указанного в Contact. direct_media=no оставляет медиапоток через Asterisk, когда прямой путь между сторонами за NAT не работает. Эти параметры не заменяют проверку SDP и маршрутизации.
Вторая часть проверки — кодеки. Если стороны не согласовали общий формат, Asterisk может транскодировать, если в установленной сборке есть нужная пара кодеков и модулей. Само несовпадение списка allow чаще мешает согласованию медиа, чем объясняет одностороннюю слышимость, поэтому сверяйте SDP обеих сторон и состояние каналов. Команда core show translation показывает доступные пути транскодирования и их стоимость. Я проверяю фактический набор форматов и требования оператора, а не ставлю alaw первым «для всех российских операторов»: условия зависят от конкретного транка.
Если молчат только голосовое меню или музыка на удержании, проверьте звуковые файлы нужного языка и формата, а также путь и права к ним. Приложение Playback не воспроизводит файл, которого нет; ищите сообщение о ненайденном файле в CLI и журнале Asterisk. Для одного тестового вызова включите pjsip set logger on и rtp set debug on, затем выключите отладку: pjsip set logger off и rtp set debug off. SIP-лог покажет обмен и SDP, а RTP-отладка — медиапакеты; долго держать подробную отладку включённой без нужды незачем.
Как проверить RTP: порядок диагностики
Я делаю тестовый звонок и смотрю на него с трёх сторон: SIP/SDP в Asterisk, RTP-отладка и захват tcpdump на сервере. Уточните диапазон в rtp.conf перед фильтром захвата — статический пример команды подходит только для этого диапазона. Если входящие RTP-пакеты видны, а исходящих нет, проверьте адрес в SDP, маршрут и правила на выход. Если пакеты не приходят, проверьте сетевой экран на сервере и периметре. Когда RTP идёт в обе стороны, но голоса нет, сравните согласованные кодеки и сообщения Asterisk. После проверки выключите отладку командой rtp set debug off.
Для SIP-разбора удобен sngrep: он показывает сообщения и SDP в виде диаграммы вызова. Я смотрю строки c= с адресом медиа и m=audio с портом и списком форматов. Частный адрес у внешнего участника — повод проверить NAT, но не окончательный диагноз: подтвердите, куда реально отправляются пакеты. Порт должен попадать в разрешённый диапазон с обеих сторон маршрута. На этот разбор может уйти больше или меньше четверти часа — зависит от числа сетевых узлов и доступности журналов. Если sngrep отсутствует, проверьте доступность пакета для вашей версии AlmaLinux и подключённых репозиториев, затем установите его штатным способом.
Я отдельно сравниваю вызов с телефона в локальной сети и с внешнего абонента. Если локальный звонок работает, а внешний нет, проверьте NAT, внешний адрес в SDP, правила маршрутизатора и ограничения оператора. Если не работает и локальный, остаются и сетевые правила, и endpoint, и согласование кодеков — один этот симптом не назначает виновника. Разберите один участок за раз и записывайте изменение вместе с результатом тестового звонка. Иначе после правок сразу в нескольких местах отличить исправление от случайности будет нечем. Для полного чек-листа по сетевому участку пригодится проверка SIP-транка и сети.
- asterisk -rx "pjsip set logger on« и asterisk -rx »rtp set debug on"
- tcpdump -ni any udp portrange 10000-20000 — замените диапазон на фактический из rtp.conf
- sngrep — диаграмма вызова и SDP
- asterisk -rx "core show translation" — перекодирование между форматами
Условный разбор: 12 телефонов и тишина в трубке
В условной сети «Хорда-Сервис» сервер на AlmaLinux 9 с Asterisk обслуживает двенадцать SIP-телефонов и транк провайдера. Вызовы соединяются, но слышимость односторонняя: сотрудник слышит абонента, а тот — тишину. Администратор два дня переустанавливал alsa-utils, удалял PipeWire и перезапускал сервер. Ничего не изменилось: локального аудиоканала не было. При захвате пакетов обнаружили, что ожидаемый RTP от телефонов до сервера не доходит. Это условный пример, но ход проверки здесь ровно тот же: сначала измерить медиапоток, потом менять конфигурацию.
При первом разборе проверили параметры rtp.conf, firewalld и маршрут через пограничный маршрутизатор. В кейсе был задан суженный диапазон 10000–10999, и на сервере открыли соответствующий UDP-диапазон. После этого локальные тестовые вызовы заработали в обе стороны. Для внешних вызовов отдельно поправили адреса NAT в транспорте PJSIP и убедились по SDP, что удалённая сторона получает достижимый адрес; на транке оставили direct_media=no, а правила маршрутизатора согласовали с выбранным диапазоном RTP. Порядок полезен тем, что проверяет сигнализацию и медиа отдельно, а не лечит ALSA наугад.
В этом условном разборе сетевую часть исправили примерно за час после того, как нашли причину; такая длительность не гарантируется в другой топологии. Звуковая подсистема ОС не оказалась причиной, потому что вызовы шли через сетевой медиатракт, а не через аудиоустройство сервера. После изменений проверили входящие и исходящие вызовы и сохранили конфигурацию. Я также отдельно проверяю мониторинг регистрации транка: отсутствие регистрации и отсутствие RTP — разные сбои, и сигнализация о первом не заменяет диагностику второго. Подробный разбор кодеков вынесен в материал ошибки кодеков в Asterisk.
- Сверить диапазон в rtp.conf и firewall
- Проверить адреса c= и m=audio в SDP
- Проверить RTP в обе стороны
- Повторить входящий и исходящий тест
Частые вопросы
Нужна ли ALSA для работы Asterisk с SIP-телефонами?
Нет. Звук между SIP-телефонами и Asterisk идёт по сети в RTP. ALSA или PulseAudio нужны только каналам, работающим со звуковой картой сервера, например chan_console.
Какие порты открыть в firewalld для Asterisk?
Порт и протокол SIP из активного транспорта (часто это 5060/UDP) и UDP-диапазон RTP, заданный в rtp.conf. Правило SIP само по себе RTP не открывает; после --permanent примените reload и проверьте зону.
Почему звук есть только в одну сторону?
Причиной могут быть NAT, firewall, неверный адрес в SDP или путь RTP. Сравните адрес и порт в SDP с захватом пакетов, затем проверьте external_media_address, local_net и настройки endpoint в PJSIP.
Почему нет голосового меню и музыки на удержании?
Обычно не установлены звуковые файлы нужного языка или формата. В консоли Asterisk при воспроизведении будет предупреждение о ненайденном файле.
Нужно ли отключать SELinux для Asterisk на AlmaLinux?
Нет. Если есть отказы, найдите их через ausearch по процессу asterisk и поправьте контексты, а не выключайте защиту целиком.
Источники
- Asterisk Documentation — NAT with PJSIP — Назначение local_net, external_media_address, external_signaling_address, direct_media и NAT-настроек endpoint. https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Configuring-res_pjsip-to-work-through-NAT/
- Asterisk — rtp.conf.sample — Комментарии к значениям rtpstart и rtpend по умолчанию и пример диапазона 10000–20000. https://github.com/asterisk/asterisk/blob/master/configs/samples/rtp.conf.sample
- Asterisk — chan_console source — chan_console использует PortAudio и заменяет устаревшие chan_alsa и chan_oss. https://github.com/asterisk/asterisk/blob/master/channels/chan_console.c
- firewalld — Open a Port or Service — Различие runtime и permanent правил, добавление портов и служб через firewall-cmd. https://firewalld.org/documentation/howto/open-a-port-or-service
- firewalld — SIP service definition — Служба sip задаёт TCP и UDP 5060; RTP в этом определении отсутствует. https://github.com/firewalld/firewalld/blob/main/config/services/sip.xml
- Asterisk Documentation — Playback() — Поведение приложения Playback при воспроизведении звуковых файлов. https://docs.asterisk.org/Asterisk_21_Documentation/API_Documentation/Dialplan_Applications/Playback/
