# Глава 22. Безопасность

> _Мы тратим время на поиски безопасности и ненавидим, когда получаем ее._
>
> -- Джон Стейнбек

Безопасность вашей системы Asterisk имеет решающее значение, особенно если система подключена к Интернету. Злоумышленники могут заработать много денег, используя системы для бесплатных телефонных звонков. В этой главе даются советы о том, как обеспечить более надежную защиту для вашего развертывания VoIP.

## Сканирование действительных учетных записей

Если вы выставляете свою систему Asterisk в общедоступный Интернет, одна из вещей, которую вы почти наверняка увидите - это сканирование действительных учетных записей. Пример 22-1 содержит записи лога с одной из производственных систем Asterisk авторов.[1](https://learning.oreilly.com/library/view/asterisk-the-definitive/9781492031598/ch22.html%22%20/l%20%22idm46178396108536) Это сканирование началось с проверки различных общих имен пользователей, а затем перешло к сканированию числовых аккаунтов. Обычно пользователи называют учетные записи SIP так же, как и внутренние номера на АТС. Это сканирование использует этот факт.

---

**Подсказка**

Используйте нечисловые имена пользователей для своих учетных записей VoIP, чтобы их было сложнее угадать. Например, в этой книге мы используем MAC-адрес SIP-телефона в качестве имени учетной записи в Asterisk.

---

#### Пример 22-1. Отрывок лога сканирования учетной записи

```text
[Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from
'"123"<sip:123@127.0.0.1>' failed for '203.86.167.220:5061' - No matching peer
found
[Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from
'"1234"<sip:1234@127.0.0.1>' failed for '203.86.167.220:5061' - No matching peer
found
[Aug 22 15:17:15] NOTICE[25690] chan_sip.c: Registration from
'"12345"<sip:12345@127.0.0.1>' failed for '203.86.167.220:5061' - No matching peer
found
...
[Aug 22 15:17:17] NOTICE[25690] chan_sip.c: Registration from
'"100"<sip:100@127.0.0.1>' failed for '203.86.167.220:5061' - No matching peer found
[Aug 22 15:17:17] NOTICE[25690] chan_sip.c: Registration from
'"101"<sip:101@127.0.0.1>' failed for '203.86.167.220:5061' - No matching peer found
```

В любой системе логи будут полны попыток вторжения. Это просто характер подключения систем к интернету. В этой главе мы обсудим некоторые способы настройки вашей системы таким образом, чтобы она имела надежные механизмы для решения этих проблем.

## Уязвимости аутентификации

В первом разделе этой главы обсуждалось сканирование имен пользователей. Даже если у вас есть имена пользователей, которые трудно угадать, очень важно, чтобы у вас были надежные пароли. Если злоумышленник может получить действительное имя пользователя, он, скорее всего, попытается подобрать пароль. Надежные пароли делают это намного сложнее.

Схема аутентификации по умолчанию SIP-протокола является слабой. Аутентификация выполняется с помощью механизма вызова и ответа MD5. Если злоумышленник может перехватить любой трафик, например SIP-вызов, выполненный с ноутбука в открытой беспроводной сети, ему будет намного проще работать с брутфорсом паролей, поскольку это не потребует запросов аутентификации у сервера.

---

**Подсказка**

Используйте надежные пароли. В Интернете доступно множество ресурсов, которые помогают определить, что представляет собой надежный пароль. Есть также много надежных генераторов паролей. Используй их!

---

## Fail2ban

В предыдущих двух разделах рассматривались атаки, связанные со сканированием действительных имен пользователей и подбором паролей брутфорсом. [Fail2ban](http://www.fail2ban.org/wiki/index.php/Main_Page) - это приложение, которое может просматривать журналы Asterisk и обновлять правила брандмауэра, чтобы блокировать источник атаки в ответ на слишком большое количество неудачных попыток аутентификации.

---

**Подсказка**

Используйте Fail2ban при предоставлении услуг Voice over IP в ненадежных сетях. Оно автоматически обновит правила брандмауэра, чтобы заблокировать источники атак.

---

### Установка

Fail2ban доступен в виде пакета во многих дистрибутивах. Кроме того, вы можете установить его из исходников, загрузив с веб-сайта Fail2ban. Чтобы установить Fail2ban на RHEL, необходимо включить репозиторий EPEL (который был рассмотрен в [Главе 3](glava-03.md)). Вы можете установить Fail2ban, выполнив следующую команду:

```text
$ sudo yum install fail2ban
```

---

**Примечание**

Установка Fail2ban из пакета будет включать скрипт запуска, чтобы гарантировать запуск при загрузке компьютера. Если вы устанавливаете из исходных кодов, убедитесь, что вы предпринимаете необходимые шаги для гарантированной постоянной работы Fail2ban.

---

### Конфигурация

Во-первых, мы хотим настроить журнал безопасности в Asterisk, который Fail2ban может использовать.

```text
$ sudo vim /etc/asterisk/logger.conf
```

Раскомментировать (или добавить) строку, которая разрешает чтение `security => security` и измените `dateformat` даты для понимания её в журнале fail2ban.

```text
[general]
exec_after_rotate=gzip -9 ${filename}.2;
dateformat = %F %T
[logfiles]
;debug => debug
security => security
;console => notice,warning,error,verbose
console => notice,warning,error,debug
messages => notice,warning,error
full => notice,warning,error,debug,verbose,dtmf,fax
```

Затем перезагрузите logger Asterisk:

```text
$ sudo asterisk -rx 'logger reload'
```

Поскольку текущие версии Fail2ban уже поставляются с определением изолятора Asterisk, все, что нам нужно сделать, это включить его:

Для этого рекомендуется создать файл _/etc/fail2ban/jail.local_ (технически вы можете поместить его в _/etc/fail2ban/jail.conf_, но он скорее всего будет перезаписан):

```text
$ sudo vim /etc/fail2ban/jail.local

[asterisk]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
           sendmail[name=ASTERISK, dest=me@shifteight.org, sender=fail2ban@shifteight.org]
logpath  = /var/log/asterisk/messages
          /var/log/asterisk/security
maxretry = 5
findtime = 21600
bantime  = 86400
```

Мы установили запрет на 24 часа, но вы можете сделать время больше или меньше, как пожелаете (время запрета определяется в секундах, так что его необходимо рассчитать). Поскольку большинство атакующих хостов меняются через несколько часов, нет никакого вреда в разблокировании IP-адреса через 24 часа. Если хост атакует снова, он снова будет заблокирован.

О, вы также можете указать ему игнорировать ваш IP (или любые другие IP-адреса, с которых можно получать попытки подключения). Если вы случайно заблокировали себя, когда делали какую-то лабораторную работу и неправильно регистрировались, не волнуйтесь, вы в конечном итоге сделаете это с собой (если, конечно, не создадите список игнорирования для соответствующих IP-адресов).

```text
[DEFAULT]
ignoreip = <ip-адрес(а), разделенные запятыми>

[asterisk]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
           sendmail[name=ASTERISK, dest=me@shifteight.org, sender=fail2ban@shifteight.org]
logpath  = /var/log/asterisk/messages
           /var/log/asterisk/security
maxretry = 5
findtime = 21600
bantime  = 86400
```

Перезапустите Fail2ban и все будет хорошо.

```text
$ sudo systemctl reload fail2ban
```

Проверьте это, если можете, с IP-адреса, который вы не против заблокировать (например, дополнительный компьютер в вашей лаборатории, который может стать объектом тестирования в данном случае). Попытайтесь зарегистрироваться с использованием неверных учетных данных, и после пяти попыток (или любого другого значения, для которого вы установили `maxretry`) этот IP-адрес должен быть заблокирован.

Вы можете увидеть, какие адреса блокирует Asterisk jail, с помощью команды:

```text
$ sudo fail2ban-client status asterisk
```

И если вы хотите разблокировать IP,[2](https://learning.oreilly.com/library/view/asterisk-the-definitive/9781492031598/ch22.html#idm46178396052456) следующая команда должна сделать это.

```text
$ sudo fail2ban-client set asterisk unbanip <ip для разбанивания>
```

Дополнительную информацию о Fail2ban можно найти на странице [Fail2ban wiki](http://www.fail2ban.org/wiki/index.php/Main_Page).

## Шифрование медиапотока

В то время как мы приводили в этой книге примеры, которые использовали шифрование, имейте в виду, что вы можете настроить SIP так, что медиапоток будет отправляться в незашифрованном виде. В этом случае любой, кто перехватит RTP-трафик между двумя SIP-узлами, сможет использовать довольно простые инструменты для извлечения звука из этих вызовов.

## Уязвимости диалплана

Диалплан Asterisk - это еще одна область, где важна безопасность. Диалплан можно разбить на несколько контекстов для обеспечения управления доступом к расширениям. Например, вы можете разрешить своим офисным телефонам совершать звонки через провайдера. Тем не менее, вы не захотите, чтобы анонимные абоненты, которые попадают в ваше главное меню компании, могли затем набрать номер через вашего провайдера. Используйте контексты, чтобы гарантировать доступ к услугам, которые стоят вам денег, только доверенным абонентам.

---

**Подсказка**

Создавайте контексты диалплана с большой осторожностью. Кроме того, избегайте размещения любых расширений, которые могут стоить вам денег в контексте `[default]`.

---

Одна из последних уязвимостей диалплана Asterisk, обнаруженных и опубликованных - это идея инъекций диалплана. Уязвимость инъекций диалплана начинается с расширения, имеющего шаблон, который заканчивается символом соответствия всему - точкой. Возьмите это расширение в качестве примера:

```text
exten => _X.,1,Dial(PJSIP/otherserver/${EXTEN},30)
```

Шаблон для этого расширения соответствует всем расширениями (любой длины), которые начинаются с цифры. Такие шаблоны довольно распространены и удобны. Затем расширение отправляет этот вызов на другой сервер, используя протокол IAX2, с таймаутом набора 30 секунд. Обратите внимание на использование здесь переменной `${EXTEN}`. Вот где кроется уязвимость.

В мире Voice over IP нет причин, по которым набираемый номер должен быть числовым. На самом деле, это довольно распространенное использование SIP, чтобы иметь возможность набрать кого-то по имени. Поскольку нечисловые символы могут быть частью набранного добавочного номера, что произойдет, если кто-то отправит вызов на такой добавочный номер?

```text
1234&DAHDI/g1/12565551212
```

Подобный вызов является попыткой использования уязвимости инъекции диалплана. В предыдущем определении расширения, как только `${EXTEN}` был вычислен, фактический оператор `Dial()`, который будет исполняться, будет иметь вид:

```text
exten => _X.,1,Dial(PJSIP/otherserver/1234&DAHDI/g1/12565551212,30)
```

Если в системе настроена PRI, этот вызов совершит вызов через PRI на номер, выбранный злоумышленником, даже если вы явно не предоставили доступ к PRI этому абоненту. Эта проблема может стоить вам больших затрат.

Существует несколько подходов к решению этой проблемы. Первый и самый простой подход - всегда использовать строгое сопоставление шаблонов. Если вы знаете длину ожидаемых расширений и ожидаете только числовые расширения, используйте строгое соответствие числовому шаблону. Например, такой шаблон будет работать, если вы ожидаете только четырехзначные числовые номера:

```text
exten => _XXXX,1,Dial(PJSIP/otherserver/${EXTEN},30)
```



Другой подход к смягчению уязвимостей инъекций диалплана заключается в использовании функции диалплана `FILTER()` . Возможно, вы хотели бы разрешить числовые расширения любой длины. `FILTER()` позволяет сделать это легко и безопасно:

```text
exten => _X.,1,Set(SAFE_EXTEN=${FILTER(0-9A-F,${EXTEN})})
    same => n,Dial(PJSIP/otherserver/${SAFE_EXTEN},30)
```

Дополнительные сведения о синтаксисе функции диалплана `FILTER()` см. в выводе данных команды _core show function FILTER_ в Asterisk CLI.

Более комплексный (но и сложный) подход может заключаться в проверке всех набранных цифр функциями, не входящими в диалплан (например, запросы к базе данных, которые проверяют набранную строку на соответствие разрешениям пользователя, шаблонам маршрутизации, таблицам ограничений и т.д.). Это мощная концепция, но она выходит за рамки данной книги.

---

**Подсказка**

Будьте осторожны с уязвимостями инъекциями диалплана. Используйте строгое сопоставление шаблонов или используйте функцию диалплана `FILTER()` во избежание подобных проблем.

---

## Безопасность сетевых API Asterisk

Чтобы защитить AGI, AMI и ARI, вам нужно будет тщательно рассмотреть следующие рекомендуемые методы:

* Разрешить подключения непосредственно к API только из `localhost/127.0.0.1`.
* Используйте соответствующую платформу между API Asterisk и вашим клиентским приложением,а также обрабатывайте безопасность соединения через фреймворк.
* Контролируйте доступ к фреймворку и системе с помощью строгих правил брандмауэра.

Кроме того, применяются те же правила безопасности и рекомендации, что и в любом критически важном веб-приложении.

## Другие меры по снижению риска

В Asterisk есть и другие полезные функции, которые можно использовать для снижения риска атак. Первый заключается в использовании параметров `permit` и `deny` для создания списков управления доступом (ACL) для привилегированных учетных записей. Рассмотрим АТС, которая имеет SIP-телефоны в локальной сети, но также принимает SIP-вызовы через интернет. Такие вызовы получают доступ только к главному меню компании, в то время как локальные SIP-телефоны имеют возможность совершать исходящие вызовы, которые уже стоят денег. В этом случае рекомендуется настроить списки управления доступом, чтобы только устройства в локальной сети могли использовать учетные записи для телефонов.

В таблице `ps_endpoints` параметры `permit` и `deny` позволяют указать IP-адреса, но также можно указать метку в файле `/etc/asterisk/acl.conf`. Фактически ACL принимаются почти везде, где настроены подключения к IP-службам. Например, еще одно полезное место для ACL находится в файле _/etc/asterisk/manager.conf_, для ограничения учетных записей AMI до одного хоста, который может использовать интерфейс менеджера.

ACL можно определить в _/etc/asterisk/acl.conf_.

```text
[named_acl_1]
deny=0.0.0.0/0.0.0.0
permit=10.1.1.50
permit=10.1.1.55

[named_acl_2] ; Именованные ACLs также поддерживают IPv6.
deny=::
permit=::1/128

[local_phones]
deny=0.0.0.0/0.0.0.0
permit=192.168.0.0/255.255.0.0
```

Когда именованные ACL были определены в _acl.conf_, попросите Asterisk загрузить их с помощью команды `reload acl`. После загрузки они должны быть доступны через интерфейс командной строки Asterisk:

```text
*CLI> module reload acl

*CLI> acl show

acl
---
named_acl_1
named_acl_2
local_phones

*CLI> acl show named_acl_1

ACL: named_acl_1
---------------------------------------------
  0: deny - 0.0.0.0/0.0.0.0
  1: allow - 10.1.1.50/255.255.255.255
  2: allow - 10.1.1.55/255.255.255.255
```

Теперь, вместо того, чтобы потенциально повторять одни и те же записи `permit` и `deny` в нескольких местах, вы можете применить ACL по его имени. Вы найдете поле `acl` в таблице `ps_endpoints`, которое можно использовать для указания на именованный ACL в файле _acl.conf_.

```text
mysql> select id,transport,aors,context,disallow,allow,acl from ps_endpoints;

|id          |transport    |aors        |context|disallow|allow        |acl |
|0000f30A0A01|transport-udp|0000f30A0A01|sets   |all     |ulaw         |NULL|
|0000f30B0B02|transport-udp|0000f30B0B02|sets   |all     |ulaw         |NULL|
|SOFTPHONE_A |transport-udp|SOFTPHONE_A |sets   |all     |ulaw,h264,vp8|NULL|
|SOFTPHONE_B |transport-udp|SOFTPHONE_B |sets   |all     |ulaw,h264,vp8|NULL|

mysql> update ps_endpoints
        set acl='local_phones'
        where id in ('0000f30A0A01','0000f30B0B02','SOFTPHONE_A','SOFTPHONE_B')
       ;

mysql> select id,transport,aors,context,disallow,allow,acl from ps_endpoints;

|id          |transport    |aors        |context|disallow|allow        |acl         |
|0000f30A0A01|transport-udp|0000f30A0A01|sets   |all     |ulaw         |local_phones|
|0000f30B0B02|transport-udp|0000f30B0B02|sets   |all     |ulaw         |local_phones|
|SOFTPHONE_A |transport-udp|SOFTPHONE_A |sets   |all     |ulaw,h264,vp8|local_phones|
|SOFTPHONE_B |transport-udp|SOFTPHONE_B |sets   |all     |ulaw,h264,vp8|local_phones|
```

---

**Подсказка**

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

---

Ещё одним способом снижения риска безопасности является настройка лимитов вызовов. Рекомендуемый метод реализации ограничений вызовов - использование функций диалплана `GROUP()` и `GROUP_COUNT()`. Вот пример, который ограничивает количество вызовов от каждого узла SIP не более чем двумя одновременно:

```text
exten => _X.,1,Set(GROUP(users)=${CHANNEL(endpoint)})
    same => n,NoOp(${CHANNEL(endpoint)} : ${GROUP_COUNT(${CHANNEL(endpoint)})} calls)
    same => n,GotoIf($[${GROUP_COUNT(${CHANNEL(endpoint)})} > 2]?denied:continue)
    same => n(denied),NoOp(There are too many calls up already. Hang up.)
    same => n,HangUp()
    same => n(continue),NoOp(continue processing call as normal here ...)
```

---

**Подсказка**

Используйте ограничения вызовов, для гарантии что если учетная запись скомпрометирована, ее нельзя использовать для совершения сотен телефонных звонков одновременно.

---

## Ресурсы

Для устранения некоторых уязвимостей системы безопасности необходимо внести изменения в исходный код Asterisk. Когда эти проблемы обнаруживаются, команда разработчиков Asterisk выпускает новые релизы, содержащие только исправления для проблем безопасности, чтобы обеспечить быстрое и легкое обновление. В этом случае команда разработчиков Asterisk также публикует рекомендательный документ по безопасности, в котором обсуждаются сведения об уязвимости. Мы рекомендуем Вам подписаться на [список рассылки _asterisk-announce_](http://lists.digium.com/mailman/listinfo/asterisk-announce), чтобы убедиться, что вы узнаете об этих проблемах, когда они возникают.

---

**Подсказка**

Подпишитесь на список asterisk-announce, чтобы быть в курсе уязвимостей системы безопасности Asterisk.

---

Одним из самых популярных инструментов для сканирования учетных записей SIP и взлома паролей является [SIPVicious](http://sipvicious.org/). Мы настоятельно рекомендуем вам взглянуть на него и использовать для аудита ваших собственных систем. Если ваша система доступна из интернета, другие, скорее всего, запустят SIPVicious против неё, поэтому убедитесь, что вы сделали это в первую очередь.

## Вывод—Лучший идиот

В технологической индустрии есть принцип, который гласит: "Как только что-то станет идиотским, природа изобретет лучшего идиота." Суть этого заявления заключается в том, что никакие усилия в области развития не могут считаться завершенными. Всегда есть место для улучшения.

Когда дело доходит до безопасности, вы всегда должны иметь в виду, что люди, которые хотят воспользоваться вашей системой, очень мотивированы. Независимо от того, насколько безопасна ваша система, кто-то всегда будет искать пути для её взлома.

Мы не защищаем паранойю, но предполагаем, что то, что мы описали здесь, ни в коем случае не является последним словом о безопасности VoIP. Несмотря на то, что в этой книге мы постарались быть максимально всеобъемлющими, вы должны взять на себя ответственность за безопасность своей системы.

Преступники упорно работают, чтобы найти слабые места и использовать их.

[1](https://learning.oreilly.com/library/view/asterisk-the-definitive/9781492031598/ch22.html%22%20/l%20%22idm46178396108536-marker) Реальный IP-адрес был заменен на 127.0.0.1 в записях лога.

[2](https://learning.oreilly.com/library/view/asterisk-the-definitive/9781492031598/ch22.html%22%20/l%20%22idm46178396052456-marker) Например, себя, потому что вы забыли определить `ignoreip`...

[Глава 21. Системный мониторинг и журналирование](glava-21.md) | [Содержание](SUMMARY.md) | [Глава 23. Asterisk: Будущее телефонии](glava-23.md)