company_banner

Виртуальная АТС. Часть 2: Решаем проблемы безопасности с Asterisk и настраиваем звонки

  • Tutorial

В предыдущей статье мы рассмотрели простую установку IP АТС (IP PBX) Asterisk 16 из штатного репозитория на виртуальный сервер RuVDS с 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 XXX.XXX.XXX.XXX to any port 22
# Разрешаем все входящие соединения с клиентских IP (подсетей) для работы с Asterisk
sudo ufw allow from XXX.XXX.XXX.XXX
# Включаем межсетевой экран
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.conf
[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 будет выглядеть примерно так:

Содержимое 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 для приема входящих вызовов, организации конференций и решения других задач маршрутизации звонков. Внимательные читатели могли заметить, что некоторые загруженные модули не были задействованы в примерах: они нам понадобятся, чтобы научиться записывать звонки, создавать очереди и делать прочие интересные фокусы.


Читайте наш блог )



RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Комментарии 6

    +3

    Ну почему chan_sip то в 2020 и на 16 астериске когда есть pjsip?
    Chan_sip deprecated уже давно и не поддерживается разработчиками. Если уж несёте в массы VoIP то несите релевантные модули.

      +3
      Вы пытаетесь достучаться до сердца копипасты? :)
        +2
        Я тоже этому поражаюсь.
        Сейчас уже даже в китайских железках pjsip… А эти всё дрочат на chan_sip.
        Статья отстой полный.
          0
          В текущей конфигурации был использован устаревший модуль chan_sip, поддержка которого в Asterisk со временем будет прекращена. В следующей статье мы рассмотрим переход на библиотеку PjSIP для работы со стеком протоколов VoIP, а также расширим dialplan для приема входящих вызовов, организации конференций и решения других задач маршрутизации звонков.


          Так ведь анонсировали же PjSIP, видимо все хотят охватить, включая процесс перехода на боевом сервере.
          0
          Поскольку пользователи на удаленке сидят по домам (в теории), как правило они имеют реальный выделенный IP

          Какая у вас интересная страна розовых единорогов… Реальный выделенный айпи скорее исключение. Тут дай-то бог динамический, а чаще всего вообще все сидят за натом на 100500 клиентов провайдера.
            0
            exten => _.7XXXXXXXXXX,1,Dial(SIP/${EXTEN}@sipnet)
            Использование этого шаблона может привести к странным результатам.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое