Виртуальная АТС. Часть 2: Решаем проблемы безопасности с Asterisk и настраиваем звонки
В предыдущей статье мы рассмотрели простую установку IP АТС (IP PBX) Asterisk 16 из штатного репозитория на виртуальный сервер с Ubuntu 20.04. В такой конфигурации выставлять службу VoIP на всеобщее обозрение не стоит: необходимо сделать дополнительные настройки, связанные в том числе с информационной безопасностью.
Определяем модель угроз
Для начала разберемся, с какими рисками столкнется компания разместившая виртуальную АТС в интернет. Все их многообразие сводится к короткому списку:
- утечки конфиденциальных данных и искажение содержимого (перехват сессии);
- несанкционированный доступ к корпоративным информационным системам из-за уязвимостей в Asterisk и другом ПО на сервере, в частности из-за неправильной настройки;
- нарушения работы виртуальной АТС из-за направленных на отказ в обслуживании атак;
- перепродажа трафика после взлома АТС (наиболее распространенная разновидность атаки).
Какая-то часть уязвимостей связана непосредственно с программным обеспечением Asterisk. Разработчики IP АТС регулярно выпускают патчи, а системным администраторам остается только своевременно устанавливать обновления. Полной безопасности этот метод не гарантирует, поэтому стоит также ограничить доступ клиентов к серверу IP-телефонии. Посмотрим, что стоит сделать для организации безопасной телефонии.
Настраиваем межсетевой экран
Самый простой способ защиты — ограничить клиентские подключения межсетевым экраном. Поскольку VDS имеет реальный IP, нет нужды решать проблемы с пропуском трафика через NAT. Остается разрешить входящие соединения от абонентов, а все прочие заблокировать посредством Netfilter. На виртуальных серверах компании RuVDS с Ubuntu он настраивается с помощью предустановленной утилиты UFW (Uncomplicated Firewall). Если пакет ufw у вас не установлен, исправить это несложно:
sudo apt-get install ufw
Для начала проверим статус: sudo ufw status verbose
По умолчанию UFW выключен (Status: inactive), но торопиться включать его не стоит: если не изменить настройки, все входящие пакеты начнут рубиться на корню и вы потеряете доступ к серверу по SSH. Как минимум стоит разрешить входящие соединения на 22-й порт, при этом можно использовать предустановленный профиль приложения OpenSSH (просмотр профилей: sudo ufw app list):
# Разрешаем входящие соединения SSH
# с любого IP, используя профиль приложения
sudo ufw allow OpenSSH
# или с фиксированного IP (можно указать подсеть)
sudo ufw allow from 95.32.20.106 to any port 22
# Разрешаем все входящие соединения с клиентских IP (подсетей) для работы с Asterisk
sudo ufw allow from 95.32.20.106
# Включаем межсетевой экран
sudo ufw enable
Для просмотра политики фильтрации используйте команду:
sudo ufw status verbose
Для удаления правил нужно посмотреть их номера:
sudo ufw status numbered
sudo ufw delete N
Есть и другие средства для настройки Netfiler (тот же iptables), но совмещать разные утилиты не стоит — это чревато проблемами. Обойтись без фильтрации трафика не получится, потому что открытым всем ветрам ваш Asterisk не простоит и часа, как в консоли появятся вот такие веселые картинки:
Поскольку пользователи на удаленке сидят по домам (в теории), как правило они имеют реальный выделенный IP, и нам больше ничего не потребуется. В противном случае стоит позаботиться о создании защищенной виртуальной частной сети: она пригодится и для доступа к другим корпоративным ресурсам, которые не стоит выставлять на всеобщее обозрение. Более сложные средства защиты (fail2ban и т.д.) не имеют прямого отношения к Asterisk. Мы их рассмотрим в общем контексте и в других постах.
Избавляемся от лишних модулей
Эта часть настройки непосредственно с безопасностью не связана, однако в целом необходима. К тому же чем меньше возможностей предоставляет ваша АТС клиентам, тем труднее ее взломать — отсутствие лишней функциональности до известной степени осложнит жизнь потенциальным злоумышленникам.
Минимальная функциональность АТС выглядит примерно так:
- Поддержка SIP;
- Поддержка кодека G711 alaw only (при желании можно добавить все доступные кодеки);
- Запись звонков;
- Поддержка формата WAV (при желании можно добавить поддержку всех доступных форматов);
- Опционально: поддержка хранения детализации звонков на сервере баз данных.
Для управления сервисом Asterisk в интерактивном режиме используется встроенная текстовая консоль:
sudo asterisk -rvv
Файлы модулей *.so хранятся в каталоге /usr/lib/asterisk/modules/. Загружать и выгружать их можно в консоли без перезапуска сервера (имя модуля указывается без расширения, например, chan_sip вместо chan_sip.so):
module load NAME
module unload NAME
Настройки модулей Asterisk прописываются в конфигурационном файле /etc/asterisk/modules.conf. По умолчанию все доступные модули при старте сервера загружаются автоматически, но это легко изменить с помощью параметра autoload = yes|no. Отредактируем конфигурационный файл, предварительно сделав резервную копию дистрибутивного:
sudo mv /etc/asterisk/modules.conf /etc/asterisk/modules.conf.b
sudo nano /etc/asterisk/modules.conf
Есть два подхода к конфигурированию. В первом случае мы включаем автозагрузку всех существующих модулей, а ненужные отключаем через modules.conf (секция [modules]):
[modules]
autoload=yes
noload => module_name.so
Обратите внимание, здесь имя файла мы указываем с расширением.
Второй вариант: запретить автозагрузку всех и указать только нужные модули в секции [modules] файла modules.conf, например, так:
[modules]
autoload = no
load => chan_sip.so
load => codec_alaw.so
load => format_wav.so
load => app_dial.so
load => res_musiconhold.so
После редактирования меняем права доступа: sudo chown asterisk:asterisk /etc/asterisk/modules.conf
sudo chmod 640 /etc/asterisk/modules.conf
Смотрим список загруженных модулей в консоли Asterisk:
module show
Прочие модули добавляем по вкусу. Так будет выглядеть файл modules.conf для настройки IP АТС с достаточно развитой функциональностью:
[modules]
autoload=no ; отключаем автозагрузку всех модулей из /usr/lib/asterisk/modules/
; Поддержка VoIP (SIP)
load => chan_sip.so
load => res_sorcery_config.so
load => res_pjproject.so ; без него не загрузится res_rtp_asterisk.so
load => res_rtp_asterisk.so
load => app_dial.so ; приложение для звонка требует res_musiconhold.so
load => app_echo.so
load => bridge_simple.so ; нужен для соединения каналов
load => app_bridgewait.so
load => app_transfer.so ; приложение для перевода звонков
load => app_verbose.so ; приложение для детальной статистики в консоли
load => app_voicemail.so ; приложение голосовой почты требует res_adsi.so
load => app_playback.so ; приложение для проигрывания сообщений в линию
load => app_stack.so
load => app_confbridge.so ; приложение для конференций
load => app_directory.so
load => res_adsi.so
load => app_system.so ; нужно для запуска внешний приложений
load => app_queue.so ; нужно для поддержки очередей
; Требуются для получения статусов линий
load => func_devstate.so
load => app_chanisavail.so ; требуется для поддержки ChanIsAvail
load => func_cut.so ; требуется для поддержки функции cut
; Музыка при удержании вызова
load => res_musiconhold.so
load => pbx_config.so
; Поддержка доступных кодеков
load => codec_a_mu.so
load => codec_adpcm.so
load => codec_alaw.so
load => codec_ulaw.so
load => codec_gsm.so
load => codec_lpc10.so
load => codec_g726.so
load => codec_g722.so
; Поддержка форматов
load => format_gsm.so ; Raw GSM data
load => format_h263.so ; Raw h263 data
load => format_pcm.so ; Raw uLaw 8khz Audio support (PCM)
load => format_wav_gsm.so ; Microsoft WAV format (Proprietary GSM)
load => format_wav.so ; Microsoft WAV format (8000hz Signed Linear)
load => format_mp3.so ; mp3-format
; Поддержка плат Dahdi для аналоговых линий (на VDS это не нужно)
;load => chan_dahdi.so
; Парковка вызовов
load => res_parking.so
; Если используется res_monitor.so, могут понадобиться и другие модули
load => func_periodic_hook.so
load => func_strings.so ; поддержка STRFTIME
; поддержка CALLERID, если используется res_monitor.so для определения номера
load => func_callerid.so
load => func_volume.so
; поддержка записи разговоров
load => res_monitor.so
load => app_mixmonitor.so ; для app_mixmonitor.so требуется app_dial.so
load => func_channel.so
; Запись статистики звонков в базу данных MySQL напрямую (в конфигурации из статьи не используется)
;load => cdr_mysql.so
;load => res_config_mysql.so ; MySQL RealTime Configuration Driver
; Запись статистики звонков в базу данных MySQL через ODBC (в конфигурации из статьи не используется)
;load => res_odbc.so
;load => res_config_odbc.so
;load => cdr_odbc.so ;
; Поддержка SNMP (в конфигурации из статьи не используется)
;load => res_snmp.so
; Поддержка вызовов из /var/spool/asterisk/outgoing/ (в конфигурации из статьи не используется)
;load => pbx_spool.so
; Эти модули также могут пригодиться в хозяйстве (в конфигурации из статьи не используются)
;load => app_exec.so ; поддержка exec и execif
;load => app_while.so ; поддержка циклов в dialplan
;load => res_sorcery_astdb.so
;load => res_sorcery_realtime.so
;load => app_read.so
;load => app_stack.so
;load => cdr_csv.so ; выгрузка логов в /var/log/asterisk/cdr-csv/Master.csv
;load => func_cdr.so
;load => func_logic.so
;load => func_timeout.so
;load => func_shell.so
;load => pbx_ael.so
;load => res_ael_share.so
;load => res_agi.so
;load => res_speech.so ; требуется для res_agi.so
Обратите внимание: закомментировать строку можно с помощью точки с запятой.
После изменения файла modules.conf необходимо перезагрузить модули из консоли Asterisk:
module reload
Если требуется перезапустить Asterisk, вместо встроенной консоли воспользуйтесь следующей командой:
sudo systemctl restart asterisk
Все вызываемые модули должны быть установлены, иначе при попытке их загрузки Asterisk выдаст ошибку. Скажем, для поддержки формата MP3 придется установить пакет asterisk-mp3, а для работы с сервером MySQL напрямую понадобится asterisk-mysql:
sudo apt-get install asterisk-mp3
sudo apt-get install asterisk-mysql
Найти доступные в репозитории пакеты нетрудно с помощью команды:
apt-cache search asterisk
На самом деле модулей для Asterisk гораздо больше, мы перечислили далеко не все. Если вы, к примеру, установите АТС на физическом сервере и захотите подключить к нему аналоговые линии через плату интерфейсов телефонии, потребуется пакет asterisk-dahdi.
Конфигурируем VoIP
Теперь изменим файл sip.conf, таким образом, чтобы с Asterisk можно было работать:
sudo nano /etc/asterisk/sip.conf
Добавим в раздел [general] следующие строки, если вы этого еще не сделали:
alwaysauthreject=yes
allowguest=no
Первый параметр защищает сервер Asterisk от атаки перебором по номерам. Если его не включить, сервер будет сообщать злоумышленникам, когда абонента не существует. Найдя действующий номер, хакер может перейти к перебору паролей. При alwaysauthreject=yes ошибки аутентификации для существующих и несуществующих абонентов выглядят одинаково и подобрать пароль сложнее. Параметр allowguest=no запрещает т.н. гостевые звонки пользователям АТС. Можно также изменить порт, который слушает Asterisk на нестандартный с помощью директивы bindport (аналогично адрес, который слушает сервис VoIP настраивается с помощью bindaddr).
В файле sip.conf мы прописали абонентов (пиров — от анг. peers) АТС. Если пользователь работает с фиксированных IP, стоит ограничить для него возможность подключения. Также необходимо создать стойкие пароли, ввести ограничение на количество звонков и, разумеется, прописать подключения к внешним провайдерам VoIP (т.н. транки — от англ. trunk):
deny=0.0.0.0/0.0.0.0 ;
запрет подключения со всех узловpermit=xxx.xxx.xxx.xxx/24 ;
разрешить подключение из определенной подсети secret=сложный_пароль ;
пароли абонентов должны быть стойкими к переборуcall-limit=2 ;
ограничение количества одновременных звонков
В итоге файл sip.conf будет выглядеть примерно так:
[general]
context=default
allowoverlap=no
udpbindaddr=0.0.0.0
tcpenable=no
tcpbindaddr=0.0.0.0
transport=udp
srvlookup=yes
alwaysauthreject=yes
allowguest=no
; Настройки подключения к SIPNET c использованием chan_sip
; директива register не требуется
[sipnet]
remotesecret=пароль
defaultuser=логин
host=sipnet.ru
type=peer
context=sipnet-trunk; должен существовать в dialplan (файл extensions.conf)
insecure=invite
callbackextension=s
fromuser=логин
fromdomain=sipnet.ru
disallow=all
allow=alaw,ulaw
nat=no
directmedia=no
dtmfmode=rfc2833
[office](!)
; Для начала сделаем шаблон для внутренних номеров, чтобы не повторять настройки.
; Тиражирование общих для всех параметров упрощает их изменение.
type=friend
host=dynamic ; регистрировать клиента по имени, а не IP для входящего звонка
nat=no ; абоненты работают не через NAT
deny=0.0.0.0/0.0.0.0 ; запрет подключения со всех узлов
call-limit=2
qualify=yes ; опрашивать телефон каждые 2 секунды
dtmfmode=rfc2833 ; способ передачи dtmf сигналов, обычно rfc2833
; Запрещаем все кодеки, а затем указываем допустимые в порядке приоритета
disallow=all
allow=ulaw
allow=alaw
allow=g729
allow=g723
allow=g726
allow=h261
allow=h263
allow=h264
allow=h263p
; Задаем абонентов (пиров) на основе шаблона office
[1001](office)
permit=XXX.XXX.XXX.XXX/Netmask
secret=сложный_пароль
callerid=Директор <1001>
context=homeoffice ; должен существовать в dialplan (файл extensions.conf)
[1002](office)
permit=YYY.YYY.YYY.YYY
secret=сложный_пароль
callerid=Секретарь <1002>
context=homeoffice
При этом абонент 1001 может подключиться с любого адреса определенной подсети, а 1002 — только с фиксированного IP. Также мы задали абонентам номер, пароль, имя и контекст, который будет использоваться в плане маршрутизации звонков (dialplan). Инструкции по настройке транков лучше взять на сайтах поставщиков услуг: в нашем случае это SIPNET. Параметры сходны с параметрами других пиров — внутренних абонентов. Отметим также, что указанный в конфигурационном файле контекст (расскажем об этой сущности ниже) должен существовать в dialplan.
После внесения изменения конфигурационного файла sip.conf необходимо перезагрузить модуль SIP через консоль Asterisk: sip reload
Другие команды встроенной консоли для работы с модулем SIP:
sip show peers
— вывод состояния всех транков/пиров; sip show registry
— отображение всех регистраций; sip show channels
— отображение активных каналов; sip show settings
— просмотр глобальных настроек модуля SIP.
Dialplan и все-все-все
План маршрутизации звонков или dialplan часто называют сердцем Asterisk. Хранится он в файле /etc/asterisk/extensions.conf и по сути представляет собой сценарий, заставляющий АТС реагировать на внешние события. Писать скрипты плана звонков можно на разных языках, но мы рассмотрим встроенный, появившийся еще в первых версиях популярной IP АТС. После настройки и запуска Asterisk в файле extensions.conf будет какое-то содержимое. Заменим его собственным:
[general]
static=yes
writeprotect=no
priorityjumping=no
autofallthrough=yes
clearglobalvars=no
; Контекст по умолчанию принято закрывать ради удобства и безопасности
[default]
exten => _X.,1, NoOp ()
same => n, Busy ()
same => n, HangUp ()
; Определяем контекст homeoffice
[homeoffice]
; разрешаем внутренние звонки
exten => _1XXX,1, Dial (SIP/${EXTEN})
; звонки по России производим через SIPNET
exten => _.7XXXXXXXXXX,1, Dial (SIP/${EXTEN}@sipnet)
; Определяем контекст sipnet-trunk, разрешаем входящие звонки через SIPNET
[sipnet-trunk]
; входящие звонки рассмотрим в следующей статье
Синтаксис сценария довольно очевиден, в подробностях мы разберем его в следующей статье. Отметим только, что план звонков Asterisk базируется на четырех центральных понятиях:
- Контекстах (context) — сообщающихся между собой именованных (названия заключены в квадратные скобки) частях кода: наборах инструкций;
- Расширениях (extensions) — сериях шагов для обработки вызовов, начинающихся со служебного слова exten;
- Приоритетах — шагах расширений, нумерованных (обозначенных числом) или не нумерованных (обозначенных буквой n — next). Для упрощения кодинга помимо exten существует служебное слово same;
- Приложениях (applications) — выполняющих действия в текущем канале сущностях. Например, Dial — это приложение, которому нужно передать аргументы.
Расширения сортируют звонки по использующей набор паттернов маске, начинающейся с нижнего подчеркивания — оно дает нашей АТС понять, что речь идет о шаблоне: exten => _1XXX,1,Dial(SIP/${EXTEN})
Дальше указан приоритет и вызов приложения с передачей ему аргументов — все довольно просто.
Перезагрузим dialplan с помощью консоли Asterisk:
dialplan reload
Чтобы посмотреть актуальный dialplan, воспользуйтесь командой:
dialplan show
Обратите внимание, что вносить изменения в dialplan могут, например, загруженные вами модули.
Сейчас АТС позволяет внутренним абонентам общаться между собой, а также совершать внешние звонки по России через SIPNET. Это не так много, но для второго занятия достаточно. В текущей конфигурации был использован устаревший модуль chan_sip, поддержка которого в Asterisk со временем будет прекращена. В следующей статье мы рассмотрим переход на библиотеку PjSIP для работы со стеком протоколов VoIP, а также расширим dialplan для приема входящих вызовов, организации конференций и решения других задач маршрутизации звонков. Внимательные читатели могли заметить, что некоторые загруженные модули не были задействованы в примерах: они нам понадобятся, чтобы научиться записывать звонки, создавать очереди и делать прочие интересные фокусы.
Читайте наш блог)