FusionPBX и ACL

Моя статья — не полноценное описание продукта, а только небольшое уточнение хорошей публикации «FusionPBX, или снова-здорово, FreeSWITCH». Мне кажется в ней не очень хорошо раскрыта тема ACL в FusionPBX. Попробую заполнить этот пробел, исходя из собственного опыта работы с FreeSWITCH/FusionPBX.

И так, имеем установленный FusionPBX с зарегистрированным внутренним номером 1010 в домене domain.local и настроенным маршрутом для внешних вызовов в город. ACL используем, чтобы обезопасить нашу систему телефонии от несанкционированных вызовов, которые унесут наши денежки. Т.е. только из описанных в ACL сетей разрешить исходящие вызовы. И здесь нужно совершенно четкое понимание, как работает ACL в FusionPBX, его особенности, логику и точку его привязки.

Как и уважаемый автор вышеупомянутой статьи, я так же наступил на все грабли, связанные с ACL.

Начну с SipProfiles.
Оба профиля (буду их так называть), и internal, и external находятся в контексте Public, и это не случайно. Регистрация номеров происходит в профиле internal, на него и обратим внимание. В профиле internal привязан ACL-лист domains как apply-inbound-acl. Именно эта строчка отвечает за работу ACL на уровне профиля. Пока с профилями всё.

Context

Контекст, кроме всего прочего, используется в маршрутизации вызовов. Все входящие маршруты привязаны к контексту Public.

Исходящие (в город, на сотовые, междугородка, международка, и любые другие) маршруты находятся (по умолчанию) в контексте имени домена (назовем его domain.local).

ACL

Теперь давайте разберемся с ACL. По умолчанию, в только что установленной FusionPBX есть два ACL-листа:

domains действие по умолчанию: deny — этот лист привязан к профилю internal
lan действие по умолчанию: allow

В ACL-лист domains прописываем сеть (ну к примеру 192.168.0.0/24), делаем этой сети разрешение allow, применяем reloadacl.

Далее регистрируем телефон из этой сети, и вроде бы все хорошо и по инструкции и логично.
Начинаем тестировать, делаем вызов на внешний номер и… получаем бублик, а точнее дырку от бублика. Неожиданно!

Начинаем анализировать лог в консоли или через Log Viewer FusioPBX.

Видим наш вызов:

switch_channel.c:1104 New Channel sofia/internal/[email protected]

Видим сработавший ACL:

sofia.c:10208 IP 192.168.0.150 Approved by acl "domains[]". Access Granted.

И далее:

mod_dialplan_xml.c:637 Processing 1010 <1010>->98343379xxxx in context public
switch_core_state_machine.c:311 No Route, Aborting 
switch_core_state_machine.c:312 Hangup sofia/internal/[email protected] [CS_ROUTING] [NO_ROUTE_DESTINATION] 

Нет маршрута! Хотя маршрут у нас честно прописан.

Ответ на самом деле прост.

Вызов пришел. ACL его пропустил. А так как ACL привязан в профилю internal, а этот профиль находится в контексте public, FreeSWITCH честно смотрит маршрутизацию в контексте public. Но в контексте public только входящая маршрутизация, и система честно нам говорит, что нет там ни каких маршрутов в город.

Из сложившейся ситуации есть как минимум два выхода.

  1. Прикрутить этот ACL не к профилю, а к самому внутреннему номеру. Это может быть и самый правильный способ решения, т.к. ACL лучше привязывать как можно ближе к Extension для более тонкой настройки. Т.е. можно прописать конкретный адрес/адрес сети телефона, с которого он сможет сделать исходящий вызов. Минус этого варианта в том, что в каждом Extension придется это делать.
  2. Поправить ACL так, чтобы он корректно работал на уровне профиля. Я выбрал именно этот вариант, ибо добавить один раз сеть в ACL мне показалось проще, чем прописывать его в каждом Extension. Но это конкретно под мою задачу. Для других задач, возможно, нужна другая логика принятия решения.

И так. Поправим ACL domains следующим образом:

domains действие по умолчанию: allow

В ACL-лист domains прописываем сеть:

deny 192.168.0.0/24

Применяем, reloadacl.
Тестируем: набираем снова номер 98343379хххх и… идёт КПВ… АЛЛО. Всё работает.
Смотрим, что происходило в FreeSWITCH:
начинается вызов:

switch_channel.c:1104 New Channel sofia/internal/[email protected]

ACL не пропустил:

[DEBUG] sofia.c:10263 IP 192.168.0.150 Rejected by acl "domains". Falling back to Digest auth.

и далее:

mod_dialplan_xml.c:637 Processing 1010 <1010>->98343379xxxx in context domain.local
sofia/internal/[email protected] Regex (PASS) [Sity] destination_number(98343379xxxx) =~ /^9(8343[23]d{6})$/ break=on-false 

Маршрутизация прошла, и далее идет установление соединения, которое выходит за рамки темы.

Если мы поменяем адрес сети в ACL, но получим картину из первого тестирования, т.е. ACL вызов пропустит и маршрутизация скажет NO_ROUTE_DESTINATION.

Вот наверное и всё, что я хотел дополнить по ACL FusionPBX.

Надеюсь кому нибудь пригодится.

Источник: habr.com