Настройка fail2ban для защиты asterisk

Что такое fail2ban и зачем он нужен для asterisk?

О том, что такое fail2ban, Вы можете прочитать в разделе безопасность Linux. Рассмотрим, зачем fail2ban нужен для защиты asterisk.

Как Вам известно, asterisk является приложением (сервером) для IP-телефонии. То есть позволяет подключившимся к нему клиентам звонить друг другу и во внешний мир, используя (помимо всего прочего) линии телефонной связи. При этом возникают следующие риски:

  1. клиенты идентифицируются по логину/паролю, а также (как правило) по IP адресу. При этом существует возможность подобрать пароль (раньше или позже, в зависимости от его сложности, но в любом случае это возможно), причем крайне часто ограничения по IP адресам далеко не такие жесткие, как хотелось бы (в идеале для каждого клиента должен быть свой уникальный IP адрес)
  2. входящие звонки из интернета (например, с других серверов asterisk). С этими подключениями все сложнее, поскольку asterisk (в базовой конфигурации) не предусматривает отображение IP адресов, с которых производится подключение.

Программа fail2ban в связке с брандмауэром (например, iptables) и правильно настроенным asterisk (отображающим в логах полную информацию, в том числе IP адреса клиентов и других серверов) позволяет эффективно заблокировать попытки подключения и подбора пароля.

Перед началом настройки Вам необходимо установить iptables и fail2ban. Кроме того, iptables должен быть уже настроен (и разрешать подключения к asterisk) до начала настройки fail2ban! Прочитать, как настроить iptables можно здесь: настройка iptables для работы asterisk. Вы также можете установить fail2ban до установки самого asterisk, и в этом случае (по крайней мере, теоретически) в процессе установки последние версии asterisk обнаруживают установленный fail2ban и настраивают его автоматически. Однако:

  1. Не всегда вопрос безопасности IP-телефонии рассматривается до установки asterisk. То есть скорее всего, Вы захотите установить fail2ban на систему с уже установленным (и настроенным) астериском.
  2. Не во всех случаях автоматическое конфигурирование срабатывает вообще, не говоря уже о том, чтобы оно сработало правильно (и начало блокировать все атаки на asterisk).

Настройка ведения логов asterisk

В первую очередь имеет смысл настроить ведение логов asterisk, чтобы информация сразу же начала собираться в нужном нам формате и виде. Для этого в каталоге конфигурации asterisk (по умолчанию это /etc/asterisk) найдите файл logger.conf и внесите в него следующие изменения: раскомментируйте (уберите точку с запятой в начале строки):

dateformat=%F %T ; ISO 8601 date format

Это нужно для того, чтобы asterisk писал в логи дату в правильном формате:
год-месяц-день часы:минуты:секунды

Начиная с 10-й версии asterisk, Вы можете включить Asterisk Security Framework. Для этого в файле logger.conf найдите и раскомментируйте (или добавьте) строку:

security => security

В этой строке с левой стороны от стрелки указано имя файла, в котором будут сохраняться события, а с правой стороны – уровни (типы событий), которые будут сохраняться. В данном примере события, относящиеся к уровню security (и только они), будут сохраняться в файл с именем security в папке логов asterisk.
Разумеется, после внесения изменений необходимо, чтобы asterisk перечитал конфигурацию. Для этого можно либо перезагрузить сервис астериска, либо только конфигурацию логов (logger reload из asterisk CLI).

После этого в папке логов asterisk (по умолчанию /var/log/asterisk) появится файл с именем security. Не забудьте настроить ротацию логов для этого файла (так же, как и для остальных логов asterisk)!

Настройка правил фильтрации

Теперь нам необходимо создать фильтр, который будет извлекать из общего потока сообщений астериска потенциально опасные события (неверный логин/пароль, попытка входа с неразрешенного IP адреса, и т.д. и т.п.). При этом нам необходимо не только обнаруживать такие потенциально опасные события, но и вычленять оттуда IP адрес, с которого было выполнено действие. То есть мы не просто ищем определенные строки в файлах событий астериска, а настраиваем правила фильтрации.
Правила фильтрации можно прописать в файле /etc/fail2ban/filter.d/asterisk.conf. Вот образец содержимого этого файла:

В asterisk версии 1.4 и более ранних используются строки типа “… failed for ‘<HOST>’ …”, а в asterisk 1.8 и выше – строки “… failed for ‘<HOST>:.*’ …”, поскольку начиная с версии asterisk 1.8 в логах появилась информация о номере порта, которой нет в asterisk 1.4. Приведенный выше вариант учитывает как старые, так и новые версии asterisk, так что Вам нет необходимости в нем что-либо менять.

Для asterisk версии 10 и выше, если Вы включили ведение логов security, не забудьте прописать правила фильтрации для этих логов!

Правила фильтрации можно прописать в файле /etc/fail2ban/filter.d/asterisk-security.conf. Вот образец содержимого этого файла:

 

Настройка изоляторов (jails) для fail2ban

Теперь нам необходимо создать описания так называемых “изоляторов” (jails) для fail2ban, т.е. “привязать” наши фильтры к fail2ban: объяснить, в каких файлах эти строки искать, и что потом делать.

Для этого откройте файл /etc/fail2ban/jail.conf

  1. Убедитесь, что нет (или не включено) других правил, связанных с asterisk! Для этого достаточно сделать поиск по файлу по имени “asterisk” (без кавычек) и убедиться, что если такие правила есть, для каждого из них свойство enabled установлено в false:
    enabled = false
  2. В случае, если версия asterisk меньше 10-й, либо Вы не хотите использовать логи security (использование логов security крайне рекомендуется), то Вам достаточно будет создать только одно правило. В противном случае Вам понадобится создать 2 правила.

Правило № 1

Это правило необходимо создать для всех версий asterisk. Вы можете создать новое правило, или модифицировать любое из уже имеющихся, но отключенных. Новое правило (поскольку в нашем примере используется fail2ban в связке с iptables) будет называться asterisk-iptables и будет применяться к файлу, в котором сохраняются все основные виды событий астериска (notice, warning, error, …). По умолчанию в астериске этот основной файл логов называется messages, но (например) в FreePBX это будет файл под названием full (как называется файл у Вас – см. настройки астериска в файле logger.conf). Итак, само правило:

 

Правило № 2

Это правило будет работать только в случае, если версия asterisk – 10 или новее, а также если включено ведение логов security (см. выше). Вы также можете создать новое правило, или модифицировать любое из уже имеющихся, но отключенных. Новое правило (поскольку в нашем примере используется fail2ban в связке с iptables) будет называться asterisk-security-iptables и это правило будет использовать для анализа файл security в каталоге логов астериска:

 

Запуск fail2ban

Теперь необходимо запустить (или перезапустить) fail2ban и (если это необходимо, например iptables еще не был запущен) iptables.

Для запуска iptables (его нужно запустить первым) выполните следующую команду:
/etc/init.d/iptables start

Для перезапуска fail2ban выполните следующую команду:
/etc/init.d/fail2ban restart

Для проверки, что fail2ban запущен успешно и правило загружено, выполните следующую команду:
fail2ban-client status asterisk-iptables
и (если есть второе правило)
fail2ban-client status asterisk-security-iptables

Для отображения списка правил iptables выполните следующую команду:
iptables -L -n

В случае, если Вы только что установили fail2ban / iptables, не забудьте убедиться, что они настроены у Вас стартовать автоматически при загрузке системы!

 

Проверка работы fail2ban

Главное в процессе проверки fail2ban – иметь под рукой другой компьютер (или локальный доступ к серверу asterisk), чтобы в случае, когда fail2ban заблокирует Ваш IP адрес, Вы смогли подключиться и удалить эту блокировку!

Необходимо обязательно проверить работу связки fail2ban + iptables, поскольку, даже если Вы все настроили (или скопировали) правильно, возможно множество комбинаций событий, в результате которых настренные Вами блокировки работать не будут.

Последовательность действий для проверки работы связки fail2ban + iptables:

  1. Убедитесь, что у Вас настроен запуск iptables и fail2ban при старте компьютера
  2. Если Вы настроили 2 правила для fail2ban, настоятельно рекомендуем проверить работу каждого из них по отдельности. Для этого отключите одно из правил (enabled = false), например asterisk-security-iptables
  3. перезагрузите компьютер и проверьте, что:
    1. службы iptables и fail2ban запущены:
      service fail2ban status
      service iptables status
    2. одно из правил включено, а другое – выключено:
      fail2ban-client status asterisk-iptables
      fail2ban-client status asterisk-security-iptables
      При этом для выключенного правила появится сообщение:
      Sorry but the jail 'asterisk-security-iptables' does not exist ,
      а для включенного – сообщение вида:
      Status for the jail: asterisk-iptables
      |- filter
      | |- File list: /var/log/asterisk/messages
      | |- Currently failed: 0
      | `- Total failed: 0
      `- action
      |- Currently banned: 0
      `- Total banned: 0
  4. Запустите SIP-клиент (обязательно не с самого сервера asterisk, а с другого компьютера!), и указав неверные данные для авторизации (IP адрес для подключения должен быть IP адресом сервера asterisk!), попробуйте авторизоваться 3 раза или более (количество авторизаций, после которых IP адрес блокируется, задается в параметре maxretry для каждого правила отдельно). В качестве тестового sip клиента можно использовать программу sipsak, которая работает из командной строки.
  5. Если Вы запустили SIP клиента с того же компьютера, с которого подключались к серверу asterisk, и если fail2ban + iptables были настроены правильно, то на данный момент Ваш IP адрес заблокирован, и Вы не можете подключиться к серверу asterisk с этого компьютера (проверьте это!). Подключитесь к asterisk с другого компьютера (или локально) и продолжайте выполнение команд.
  6. Запустите команду вида:
    fail2ban-client status asterisk-iptables
    для включенного правила, и убедитесь, что IP адрес, с которого подключался SIP клиент, находится в списке заблокированных IP (banned).
  7. Теперь по аналогии с действиями из пункта 2 разблокируйте второе правило (например asterisk-security-iptables) и заблокируйте первое (asterisk-iptables).
  8. Выполните действия с пункта 3 по пункт 6, только вместо перезагрузки компьютера (что тоже можно сделать) достаточно перезагрузить службу fail2ban. После этого сразу разблокируется IP адрес компьютера, на котором Вы запускали SIP клиент, и его можно будет (и нужно, как в пункте 4) запустить еще раз – для проверки работы второго правила. Обратите внимание, что может и не разблокировать (точнее, разблокировать и снова заблокировать) – в этом случае Вам лучше сделать паузу findtime секунд, после чего еще раз перезагрузить сервис fail2ban.
  9. После того, как Вы проверили работу обоих правил по отдельности, не забудьте обязательно включить их оба (для asterisk-iptables и для asterisk-security-iptables параметр enabled = true). После этого, разумеется, не забудьте перезагрузить сервис fail2ban.
  10. И последний пункт: если Вы выполнили предыдущие пункты достаточно быстро (в течение нескольких минут), то может оказаться, что после включения обоих правил (и последующей перезагрузки fail2ban) у Вас снова заблокируется IP адрес, с которого Вы запускали SIP клиента.
    Будьте внимательны!

 

Управление правилами fail2ban

Временное отключение блокировки IP адреса

Для этого Вам необходимо воспользоваться услугой iptables. Сначала мы выведем список правил на консоль, а затем выбрав нужные IP, удалим их из бана.

Для просмотра списка правил введите команду:

iptables -L -n

Вы увидите сообщение следующего вида:

Chain INPUT (policy ACCEPT)
target prot opt source destination
...
fail2ban-ASTERISK all -- 0.0.0.0/0 0.0.0.0/0
...
Chain fail2ban-ASTERISK
target prot opt source destination
DROP all -- 1.2.3.4 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
...

Нас интересует удалить из бана IP адрес 1.2.3.4, который (как мы видим) находится в цепочке правил (chain) под названием fail2ban-ASTERISK. Набираем команду:

iptables -D fail2ban-ASTERISK -s 1.2.3.4 -j DROP

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

iptables -L -n

то увидим, что IP адрес исчез из блокировки iptables (хотя и остался в блокировке fail2ban!). При этом мы снова можем подключаться к серверу asterisk

 

Постоянное отключение блокировки IP адреса

Для того, чтобы fail2ban не блокировал определенный IP адрес (или несколько IP адресов) независимо от того, сколько неудачных попыток подбора пароля (и прочих “неправомерных” действий) они совершили, необходимо произвести дополнительную настройку jails в файле /etc/fail2ban/jail.conf

В каждом правиле файла jail.conf может присутствовать параметр ignoreip, который задает список IP адресов, попадающих в “белый список” для этого правила. Поскольку правил у нас может быть два, обратите внимание, что Ваш IP необходимо прописывать в обоих правилах!

Параметр имеет следующий вид:

ignoreip = 127.0.0.1/8 192.168.0.0/16 1.2.3.4

То есть Вы можете прописывать как подсети, так и отдельные IP адреса (в данном случае в “белый список” попадают IP 127.0.0.1-127.0.0.255, 192.168.0.1-192.168.255.255 и 1.2.3.4).

Разблокировка IP адреса, с которого производилось тестирование

Во время проверки правильности настройки fail2ban Вы неоднократно запускали SIP клиента для тестирования работы по блокировке будущих атак из интернета. И в процессе последующей работы Вам, возможно, также понадобится время от времени производить действия, последствиями которых может быть блокировка со стороны fail2ban / iptables. Хотелось бы не дожидаться, когда fail2ban “соизволит” разблокировать IP сам (а это может быть довольно долго – поскольку параметр bantime можно выставить хоть на час, хоть на день, хоть на год).

Существуют 2 пути решения подобной проблемы:

  1. Внести IP адрес в правилах fail2ban в список ignoreip. Но иногда это может быть нежелательно (чтобы, например, производить периодическое тестирование работы fail2ban)
  2. Обычно время findtime (это длительность интервала в секундах, за которое событие [атака, подбор пароля] должно повториться maxretry раз, после чего бан вступит в силу) намного меньше, чем bantime (это время бана в секундах, по истечении которого IP адрес удаляется из списка заблокированных). Например, findtime выставляется в 10 минут, а bantime – час. Либо findtime – час, а bantime – день или даже больше. И так далее. Поэтому имеет смысл сделать паузу длительностью не менее, чем findtime с момента последнего тестирования (и забанивания Вашего IP адреса), после чего перезагрузить сервис fail2ban. При перезагрузке сервиса fail2ban все блокировки аннулируются. Однако при последующей загрузке fail2ban логи анализируются снова, и если в логах в течение findtime было maxretry неудачных попыток подключения с одного IP, этот IP будет снова забанен сразу после запуска fail2ban.

Тестирование конфигурации fail2ban

Вы можете проверить, как будет применяться фильтр fail2ban к тому или иному логу. Для этого можно запустить команду:

fail2ban-regex /var/log/asterisk/messages /etc/fail2ban/filter.d/asterisk.conf

Где /var/log/asterisk/messages – это пример пути к файлу с логами, который будет фильтроваться, а /etc/fail2ban/filter.d/asterisk.conf – сам фильтр, который содержит те фрагменты [сообщения об ошибках], которые должны быть в логе [чтобы забанить IP адреса атакующих].

 

И напоследок: вместо перезагрузки fail2ban с помощью service fail2ban restart можно выполнить следующую команду fail2ban-client reload

 

Ссылки на источники

Материалы по fail2ban взяты (в частности) с официального сайта www.fail2ban.org, регэкспы и правила jails для астериска взяты из раздела Asterisk fail2ban.

config/filter.d/asterisk.conf

# Fail2Ban filter for asterisk authentication failures
#

[INCLUDES]

# Read common prefixes. If any customizations available — read them from
# common.local
before = common.conf

[Definition]

_daemon = asterisk

__pid_re = (?:\s*\[\d+\])

iso8601 = \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{4}

# All Asterisk log messages begin like this:
log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])? [^:]+:\d*(?:(?: in)? \w+:)?

failregex = ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Registration from ‘[^’]*’ failed for ‘<HOST>(:\d+)?’ – (?:Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Call from ‘[^’]*’ \(<HOST>:\d+\) to extension ‘[^’]*’ rejected because extension not found in context
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s (?:Host )?<HOST> (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b)
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer ‘[^’]*’ \(from <HOST>\)$
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s hacking attempt detected ‘<HOST>’$
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s SecurityEvent=”(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)”(?:(?:,(?!RemoteAddress=)\w+=”[^”]*”)*|.*?),RemoteAddress=”IPV[46]/(UDP|TCP|WS)/<HOST>/\d+”(?:,(?!RemoteAddress=)\w+=”[^”]*”)*$
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s “Rejecting unknown SIP connection from <HOST>”$
^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request (?:'[^’]*’ )?from ‘(?:[^’]*|.*?)’ failed for ‘<HOST>(?::\d+)?’\s\(callid: [^\)]*\) – (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$

# FreePBX (todo: make optional in v.0.10):
# ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from <HOST>$

ignoreregex =

# Author: Xavier Devlamynck / Daniel Black
#
# General log format – main/logger.c:ast_log
# Address format – ast_sockaddr_stringify
#
# First regex: channels/chan_sip.c
#
# main/logger.c:ast_log_vsyslog – “in {functionname}:” only occurs in syslog

 

 

here is an example to check regexp

 

[2019-05-01 04:20:47] NOTICE[16333]: res_pjsip/pjsip_distributor.c:659 log_failed_request: Request ‘INVITE’ from ‘<sip:001173141336@10.0.0.238>’ failed for ‘62.210.12.84:60195’ (callid: 907028066-841951920-2029782004) – No matching endpoint found

 

the command is:

fail2ban-regex -v /home/test /etc/fail2ban/filter.d/asterisk.conf

cmd Page()

it makes sense to comment pin into confbridge.conf, cuz page asks for the password

 

page alternative is RTP  multicast https://www.voip-info.org/asterisk-multicastrtp-channels

 

helpful doc https://www.voip-info.org/asterisk-paging-and-intercom

 

I checked myself

 

// Set(_ALERT_INFO=\”RA\”); // This is for the PolyComs
// SIPAddHeader(Alert-Info: Ring Answer);
SIPAddHeader(Alert-Info: answer-after=0); // yealink T22
// SIPAddHeader(Call Info Answer-After=0); // This is for the Snoms and Others
SIPAddHeader(Call-Info <sip:10.1.0.7>\;answer-after=0); // Cisco 504

linphone

I’m trying to configure push for the Linphone I just compiled for iOS. However, when it registers it sends something like this (instead of 2 seperate contacts):

Contact: sip:242683@172.17.106.190:55522;app-id=org.linphone.uz.voip.dev;pn-type=apple;pn-tok=SECRETTOKEN;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=notes_of_the_optimistic.caf;pn-msg-snd=msg.caf;pn-timeout=0;pn-silent=1;transport=udp;+sip.instance=”urn:uuid:d7de811f-b0a8-4e6b-addf-423137603356″

Also, Asterisk reports an error:

WARNING[79953]: res_pjsip_registrar.c:457 rx_task_core: Failed to validate contacts in REGISTER request from ‘242683’

 

The Asterisk error (preventing a correct REGISTER) was solved by modifying PJSIP:
/usr/local/src/pjproject-2.4.5/pjsip/include/pjsip/sip_config.h : define PJSIP_MAX_URL_SIZE 256
=> increased this to 1024.

 

or new path in asterisk14 /usr/include/pjsip/sip_config.h

Asterisk AGI BASH

использую давно bash в качестве AGI. Чего только на нём не делал – всё работает как часы.

Для того, чтобы получить в диалплан обратно параметры из bash, нужно сделать следующее:
#!/bash

# тут получили параметры, переданные скрипту как $1, $2 и т.п..
# произвели какие-то вычисления и нам нужно вернуть в диалплан
# переменную $res и использовать её в диалплане как bashres:

echo “SET VARIABLE bashres $res”
В диалплане после этого на время жизни канала будет доступно значение локальной переменной bashres:
….
exten => s,n,AGI(myscript,${ARG1}, ${ARG2})
exten => s,n,NoOp(Result: ${bashres})
…..

 

SIP Safe cause codes

 

use with Hangup(code) or Hangup(USER_BUSY)

Safe cause codes
21 CALL_REJECTED Call Rejected 403 Forbidden
1 UNALLOCATED Unallocated (unassigned) number 404 Not Found
18 NO_USER_RESPONSE No user responding 408 Request Timeout
22 NUMBER_CHANGED Number changed 410 Gone
19 NO_ANSWER User alerting, no answer 480 Temporarily Unavailable
28 INVALID_NUMBER_FORMAT Invalid number format 484 Address Incomplete
17 USER_BUSY User busy 486 Busy Here
58 BEARERCAPABILITY_NOTAVAIL Bearer capability not available 488 Not Acceptable Here
38 NETWORK_OUT_OF_ORDER Network out of order 500 Server Internal Error
29 FACILITY_REJECTED Facility rejected 501 Not Implemented
27 DESTINATION_OUT_OF_ORDER Destination out of order 502 Bad Gateway
34 NORMAL_CIRCUIT_CONGESTION Circuit/channel congestion 503 Service Unav

 

Hex Dec Описание AMI Cause SIP ответ
 0x0 0  Неопределенная ошибка (Cause not defined)  NOT DEFINED
 0x1 1  Номер не найден (Номера не существует) (Unallocated or unassigned number)  UNALLOCATED  404, 485, 604
 0x2 2  Нет маршрута к указанной транзитной сети (No route to specified transmit network)  NO ROUTE TRANSIT NET
 0x3 3  Нет маршрута до указанного номера (No route to destination)  NO ROUTE DESTINATION  420
 0x4 4  Отправка определенной тоновой информации (Send special information tone)
 0x5 5  В дозвоне ошибочный префикс транка (Misdialled trunk prefix)  MISDIALLED TRUNK PREFIX
 0x6 6  Канал не поддерживается (Channel unacceptable)  CHANNEL UNACCEPTABLE
 0x7 7  Вызов направлен в указанный канал (Call awarded and being delivered in an established channel)  CALL AWARDED DELIVERED
 0x8 8  Префикс 0 вызван, но не разрешён (Prefix 0 dialed but not allowed)
 0x9 9  Префикс 1 вызван, но не разрешён (Prefix 1 dialed but not allowed)
 0xA 10  Префикс 1 не вызван, но требуется (Prefix 1 not dialed but required)
 0xB 11  Получено больше цифр, чем разрешено, вызов обрабатывается (More digits received than allowed, call is proceeding)
 0x10 16  Нормальное завершение вызова (Normal call clearing)  NORMAL CLEARING
 0x11 17  Вызываемый номер занят (User busy)  USER BUSY  486, 600
 0x12 18  Нет ответа (No user responding)  NO USER RESPONSE  408
 0x13 19  Нет сигнализации от пользователя, нет ответа (User Alerted, No answer from user)  NO ANSWER  480, 483
 0x15 21  Вызов отклонен (Call rejected)  CALL REJECTED  401, 403, 407, 603
 0x16 22  Номер изменился (Number changed to number in diagnostic field)  NUMBER CHANGED  410
 0x17 23  Оплата за счёт вызываемого абонента отклонена (Reverse charging rejected)
 0x18 24  Звонок приостановлен (Call suspended)
 0x19 25  Звонок возобновлён (Call resumed)
 0x1A 26  Невыбранная абонентом очистка (Non-selected user clearing)
 0x1B 27  Направление не обслуживается (Destination out of order)  DESTINATION OUT OF ORDER  502
 0x1C 28  Неверный формат номера или неполный адрес (Invalid number format or incomplete address)  INVALID NUMBER FORMAT  484
 0x1D 29  Функциональная возможность отклонена сетью (EKTS facility rejected by network)  FACILITY REJECTED  501
 0x1E 30  Ответ на сообщение “ЗАПРОС СОСТОЯНИЯ” (Response to STATUS ENQUIRY)  RESPONSE TO STATUS ENQUIRY
 0x1F 31  Нормальное состояние, не уточнено (Normal, unspecified)  NORMAL UNSPECIFIED
 0x21 33  Схема вышла из строя (Circuit out of order)
 0x22 34  Нет схемы доступа/канала (No circuit/channel available)  NORMAL CIRCUIT CONGESTION
 0x23 35  Направление недостижимо (Destination unattainable)
 0x24 36  Вышло из строя (Out of order)
 0x25 37  Вырождающийся сервис (Degraded service)
 0x26 38  Сеть вышла из строя (Network out of order)  NETWORK OUT OF ORDER  500
 0x27 39  Уровень транзитных задержек не может быть достигнут (Transit delay range cannot be achieved)
 0x28 40  Уровень пропускной способности не может быть достигнут (Throughput range cannot be achieved)
 0x29 41  Временная неработоспособность (Temporary failure)  NORMAL TEMPORARY FAILURE  409
 0x2A 42  Сетевое оборудование перегружено (Switching equipment congestion)  SWITCH CONGESTION  5xx
 0x2B 43  Доступ к информации отклонен (Access information discarded)  ACCESS INFO DISCARDED
 0x2C 44  Запрашиваемая схема/канал не доступны (Requested circuit channel not available)  REQUESTED CHAN UNAVAIL
 0x2D 45  Упреждение (Preempted)  PRE EMPTED
 0x2E 46  Приоритетный вызов блокирован (Precedence call blocked)
 0x2F 47  Ресурс недоступен (Resource unavailable, unspecified)
 0x31 49  Запрашиваемая услуга недоступна (Quality of service unavailable)
 0x32 50  Нет подписки на запрошенную услугу (Requested facility not subscribed)  FACILITY NOT SUBSCRIBED
 0x33 51  Оплата за счёт вызываемого абонента не разрешена (Reverse charging not allowed)
 0x34 52  Исходящие вызовы закрыты (Outgoing calls barred)  OUTGOING CALL BARRED
 0x35 53  Исходящие вызовы закрыты в пределах закрытой абонентской группы (Outgoing calls barred within CUG)
 0x36 54  Входящие вызовы закрыты (Incoming calls barred)  INCOMING CALL BARRED
 0x37 55  Входящие вызовы ограничены в пределах закрытой абонентской группы (Incoming calls barred within CUG)
 0x38 56  Нет подписки на услугу ожидания вызова (Call waiting not subscribed)
 0x39 57  Возможности переноса информации не санкционированы (Bearer capability not authorized)  BEARERCAPABILITY NOTAUTH
 0x3A 58  Возможности переноса информации в данный момент недоступны (Bearer capability not presently available)  BEARERCAPABILITY NOTAVAIL  488, 606
 0x3F 63  Сервис или опция недоступны (Service or option not available, unspecified)
 0x41 65  Возможности переноса информации не реализованы (Bearer service not implemented)  BEARERCAPABILITY NOTIMPL
 0x42 66  Тип канала не поддерживается (Channel type not implemented)  CHAN NOT IMPLEMENTED
 0x43 67  Выбор транзитной сети не проддерживается (Transit network selection not implemented)
 0x44 68  Сообщение не поддерживается (Message not implemented)
 0x45 69  Затребованная услуга не реализована (Requested facility not implemented)  FACILITY NOT IMPLEMENTED
 0x46 70  Доступны только ограниченные возможности переноса цифровой информации (Only restricted digital information bearer capability is available)
 0x4F 79  Сервис или опция неприменимы, не определено (Service or option not implemented, unspecified)
 0x51 81  Неверное значение идентификатора вызова (Invalid call reference value)  INVALID CALL REFERENCE
 0x52 82  Указанный канал не существует (Identified channel does not exist)
 0x53 83  Присутствует приостановленный звонок, но этот вызов не идентифицирован (A suspended call exists, but this call identity does not)
 0x54 84  Идентификатор вызова уже используется (Call identity in use)
 0x55 85  Нет приостановленных вызовов (No call suspended)
 0x56 86  Вызов, имеющий затребованный идентификатор звонка, был очищен (Call having the requested call identity has been cleared)
 0x57 87  Вызываемый абонент не является членом закрытой абонентской группы (Called user not member of CUG)
 0x58 88  Несовместимый адресат (Incompatible destination)  INCOMPATIBLE DESTINATION
 0x59 89  Адрес назначения отсутствует и услуга прямого вызова не подписана (Non-existent abbreviated address entry)
 0x5A 90  Запись несуществующего сокращённого адреса (Destination address missing, and direct call not subscribed)
 0x5B 91  Выбрана неверная транзитная сеть (использование в пределах страны) (Invalid transit network selection (national use))
 0x5C 92  Неверная возможность параметра 93 — отсутствует обязательный информационный элемент (Invalid facility parameter 93 Mandatory information element is missing)
 0x5D 93  Несуществующий тип сообщения или не применим (Message type non-existent or not implemented)
 0x5F 95  Неверное сообщение (Invalid message, unspecified)  INVALID MSG UNSPECIFIED
 0x60 96  Отсутствует обязательный информационный элемент (Mandatory information element is missing)  MANDATORY IE MISSING
 0x61 97  Тип сообщения не существует (Message type non-existent or not implemented)  MESSAGE TYPE NONEXIST
 0x62 98  Неправильное сообщение (Message not compatible with call state or message type non-existent or not implemented)  WRONG MESSAGE
 0x63 99  Информационный элемен не существует или не указан (Information element nonexistent or not implemented)  IE NONEXIST
 0x64 100  Неверное содержимое информационного элемента (Invalid information element contents)  INVALID IE CONTENTS
 0x65 101  Сообщение не совместимо со статусом вызова (Message not compatible with call state)  WRONG CALL STATE
 0x66 102  Восстановлено по истечении таймера (Recover on timer expiry)  RECOVERY ON TIMER EXPIRE  504
 0x67 103  Несуществующий или не применимый параметр — передаётся (Parameter non-existent or not implemented – passed on)  MANDATORY IE LENGTH ERROR
 0x6F 111  Ошибка протокола (Protocol error, unspecified)  PROTOCOL ERROR
 0x7F 127  Пользователи не договорились о параметрах передачи данных (Internetworking, unspecified)  INTERWORKING  4xx, 505, 6xx
 <0x80 <128  Собственные диагностические коды. Обычно используются для передачи команд управления или обслуживания между мультиплексорами. (Proprietary diagnostic code. Typically used to pass proprietary control or maintenance messages between multiplexers)

forwarding ports on Mikrotik for asterisk

l2tp-out1 это интерфейс L2TP client (собственно VPN для инета)
ether1 интерфейс LAN (в мою квартирную сеть 🙂 )
ether2 WAN в него провод от провайдера
192.168.0.30 адрес Asterisk

Добавил в настройках фаервола дополнительно одно правило
chain=forward action=accept protocol=udp dst-address=192.168.0.30
in-interface=l2tp-out1 out-interface=ether1

и это правило уже было
chain=dstnat action=dst-nat to-addresses=192.168.0.30 protocol=udp
in-interface=l2tp-out1 dst-port=10000-25000

а эти правила для регистрации клиентов из внешнего мира

chain=dstnat action=dst-nat to-addresses=192.168.0.30 to-ports=5060
protocol=tcp in-interface=l2tp-out1 dst-port=5060

chain=dstnat action=dst-nat to-addresses=192.168.0.30 to-ports=5060
protocol=udp in-interface=l2tp-out1 dst-port=5060

Мониторинг транков (trunk) в asterisk с помощью zabbix

Мне понадобился простой мониторинг состояния транков в asterisk. Иногда после проблем с интернетом на некоторых серверах автоматически не восстанавливаются транки к sip провайдерам. Приходится дергать их вручную через sip reload после того, как пользователи начинают жаловаться. А так как провайдеров может быть несколько, не всегда сразу становится понятно, что какой-то из каналов отвалился.

Введение

Я буду использовать очень простую проверку. В интернете находится много рецептов по мониторингу asterisk с помощью zabbix. Есть готовые наборы скриптов на питоне, есть шаблоны. Можно настроить мониторинг практически всего, что только пожелаешь.

Мне не хотелось во всем этом разбираться и нагромождать в систему, так как нужно только состояние транков — зарегистрирован или нет. Усложнять чем-то еще свои системы мониторинга не хотелось. Больше никакие данные мне не нужны. Я стараюсь настраивать мониторинг только тех параметров, которые реально необходимы. Это позволяет экономить время и ресурсы сервера.

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

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

Настройка агента для мониторинга транков (trunks)

Создадим папку для пользовательских скриптов в каталоге zabbix:

# mkdir /etc/zabbix/scripts

Создаем в ней скрипт asterisk.trunk.sh следующего содержания:

#!/bin/sh
# Получаем количество всех транков в системе
number_tranks=`/usr/sbin/asterisk -rx "sip show registry" | grep "SIP registrations" | awk '{print $1}'`
# Считаем количество зарегистрированных транков
reg_tranks=`/usr/sbin/asterisk -rx "sip show registry" | grep Registered | wc -l`
# Вычисляем разницу между полученными значениями
let result=$number_tranks-$reg_tranks
# Выводим результат вычисления
echo $result

Назначаем владельцем файла пользователя zabbix и выставляем права на выполнение скрипта:

# chown zabbix. /etc/zabbix/scripts/asterisk.trunk.sh
# chmod 0750 /etc/zabbix/scripts/asterisk.trunk.sh

Теперь просто запустите скрипт и посмотрите результат. Если все регистрации подключены, то скрипт должен вернуть значение 0:

# /etc/zabbix/scripts/asterisk.trunk.sh
0

Открываем на редактирование конфиг агента и добавляем параметр UserParameter:

UserParameter=asterisk.trunk,/etc/zabbix/scripts/asterisk.trunk.sh

Перезапускаем zabbix-agent той командой, что соответствует вашей системе. В CentOS 7 делаем так:

# systemctl restart zabbix-agent

Теперь проверим с помощью zabbix_agentd какое значение будет отправлять агент на сервер:

# zabbix_agentd -t asterisk.trunk
asterisk.trunk [t|0]

Все в порядке, то что надо. На этом настройка агента на сервере asterisk закончена. Переходим на сервер мониторинга.

Создание шаблона мониторинга asterisk на сервере zabbix

Нам нужно создать шаблон на сервере, для назначения его серверам с астериском. Здесь ничего сложного, делаем все то же самое, что мы делали ранее, настраивая мониторинг рейда mdadm. Идем в раздел Configuration -> Templates, нажимаем Create template.

Создание шаблона Asterisk

Пишем название и добавляем его в группу с шаблонами.

Указываем параметры нового шаблона

Открываем шаблон, переходим в раздел Items и жмем на Create item. Заполняем параметры нового итема как на картинке.

Создание элемента для мониторинга транков

Я поставил интервал проверок 120 секунд = 2 минуты. Вы можете поменять под свои нужды этот параметр. Сохраняем новый итем.

Для сбора данных все готово. Теперь назначаем шаблон серверам с астериском, где мы подготовили агенты мониторинга и скрипты и ждем поступления данных. Проверять как обычно идем в Latest data. Через пару минут должны поступить значения.

Просмотр данным мониторинга asterisk

У меня пришло значение 0 как и должно быть. Все регистрации на месте. Теперь нам нужно добавить триггер, который будет отправлять уведомление, если какая-нибудь из регистраций отвалится. Для этого идем в созданный шаблон и переходим в раздел Triggers. Жмем Create trigger и указываем значения, как у меня.

Создание триггера мониторинга регистраций

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

Возможные ошибки

Если ваш новый item не работает, получает статус not supported, а в описании причины ошибка:

Unable to connect to remote asterisk (does /var/run/asterisk/asterisk.ctl exist?)

Необходимо разрешить пользователю zabbix, от которого работает скрипт, запускать asterisk. Для этого добавляем в файл /etc/sudoers в самый конец следующую строку:

zabbix ALL = NOPASSWD: /usr/sbin/asterisk

После этого проверяем выполнение скрипта от пользователя zabbix:

# sudo -u zabbix /etc/zabbix/scripts/asterisk.trunk.sh

Если получаете вывод значения, значит все в порядке. Если же все равно видите ошибку:

Unable to connect to remote asterisk (does /var/run/asterisk/asterisk.ctl exist?)

Добавьте в скрипт перед /usr/sbin/asterisk выполнение /usr/bin/sudo. Должно получиться так:

reg_tranks=`/usr/bin/sudo /usr/sbin/asterisk -rx "sip show registry" | grep Registered | wc -l`

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

sudo: sorry, you must have a tty to run sudo

Эта ошибка появится, если у вас пользователь zabbix создан без какой-либо оболочки. Это зависит от системы и версии заббикс агента. Проверить можно в файле /etc/passwd:

# cat /etc/passwd | grep zabbix
zabbix:x:496:496:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin

Пользователям без оболочки по-умолчанию запрещено использовать sudo, которое мы добавили в скрипт. Исправить это можно в фале /etc/sudoers, закомментировав параметр:

#Defaults    requiretty

После этого снова отцепляем шаблон и прикрепляем заново. Теперь должно быть все в порядке.

Постарался предусмотреть все варианты развития событий. Наличие тех или иных ошибок будет зависеть от операционной системы и версии zabbix и asterisk.

Заключение

В очередной раз zabbix подтвердил свою простоту и гибкость настроек. Буквально за несколько минут, после беглого безрезультатного поиска в гугле, я смастерил простенький скрипт и добавил его к системе мониторинга. Поставленную задачу он успешно выполняет. Так как ставил на разные системы, пришлось отловить несколько ошибок.

t.38 – fax

Самое главное есть картинка с tcpdump которая разжевывает что нужно искать в tcpdump

Вводная: Факсы не ходят.

С чего начинать ?
Проверяем модули факса asterisk:
CLI> module show like fax

Module                         Description                              Use Count
res_fax.so                     Generic FAX Applications                 1
res_fax_spandsp.so             Spandsp G.711 and T.38 FAX Technologies  0
2 modules loaded
Проверяем наличие файла /etc/asterisk/udptl.conf с содержимым
[general]

udptlstart=4000
udptlend=4999
;udptlchecksums=no

udptlfecentries = 3

udptlfecspan = 3
Проверяем открытые порты по udp c 4000 по 4999

И начинать надо со снятия дампа и просмотре в wireshark
Причем снимать надо сразу обе стороны:
Обмен сервера с конечным устройством и обмен сервера с провайдером:
Сервер: 192.168.1.2
Шлюз: 192.168.1.220
Провайдер: 195.69.158.38

Вот так не правильно:
tcpdump -i any host 192.168.1.2 -s0 -w fax5.pcap -v

А вот правильно:
tcpdump -i any host 195.69.158.38 or host 192.168.1.220 or host 192.168.1.2 -s0 -w fax3.pcap -v
Мы снимаем два плеча – устройство и астер и астер и провайдер

Загрузили снятый файл себе на компьютер открыли в wireshark – telephony – Voip Call
tcpdump fax3

Теперь внимательно:
В табличке видим 4 колонки
Дамп снял 2 звонка, и 1 и 2 строка это первый звонок, а 3 и 4 второй звонок.
Это видно по параметрам Start time (1 колонка)
Выделяем 1 и 2 колонку и нажимаем – Flow

fax3-c1

fax3-c2
Нас собственно говоря интересует нижняя часть рисунка – именно кусок с начала INVITE SDP (t38)
Как видно – провайдер на прислал приглашение на переключение в t38 на которое мы не ответили нечего
раз мы нечего не ответили – значит у нас косяк с настройкой оборудования – не переключился он в t38

Дяденька, а покажите как должен выглядит с дампе нормальный прошедший факс:

Не забывайте что мы снимали дамп на два плеча:
То есть между устройством и астером (1) и астером и провайдером (2)
и пакеты INVITE SDP (t38) и 200 OK SDP (t38) у вас должно быть дважды
у астера будут один порт UDP на прием от устройства и другой порт на передачу до провайдера.

633822

Запрос переключения в t38 – INVITE SDP (t38)
и подтверждение переключения – 200 OK SDP (t38)

Опа, как все просто, пойду факсы настраивать 🙂
А вот фиг, даже запрос на переключение и подтверждение переключения не означает что факс пошел.
Теперь то не так ? а теперь надо смотреть порты согласования – на каких портах договорись о передаче факса
Встаём на INVITE SDP (t38)
Раскрываем нижнюю часть, и смотрим что передали мы до сервера по поводу t38 и на каком порту мы хотим принимать
Нижняя картинка в оригинальном размере http://ic.pics.livejournal.com/awsswa/10807794/6634/6634_original.jpg
Отправитель  (Src 10.59.0.1) Получатель (Dst 10.59.0.3)
Порт на котором будет работать 10.59.0.1 UDP 4118

fax3-5

Потом смотрим что пришло по 200 OK SDP (t38) – на чем они договорились (картинка одинакова )
только меняются порты и передающая и принимающая сторона.
Тут уже будет порт на котором будет работать 10.59.0.3

===========================================================================
Теперь необходимо посмотреть обмен пакетами в ходе работы:

в строке поиска wireshark сбиваем фильтр:
udp.port == номер порта UDP на котором договаривались о передаче, и уведите что прошло
если все хорошо будет обмен с обоих сторон.

Ну и теперь осталось совсем простое решение:
В asteriks в консоле
> udptl set debug on
И смотрим глазками обмен между устройствами (тут правда ип адреса другие и порты но нам важен принцип)

UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 11, len 6)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 11, len 16)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 12, len 48)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 12, len 56)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 13, len 8)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 13, len 56)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 14, len 33)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 14, len 83)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 15, len 8)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 15, len 85)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 16, len 19)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 16, len 56)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 17, len 8)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 17, len 56)
UDPTL (SIP/104-00007435): packet from 192.168.0.11:24278 (seq 18, len 8)
UDPTL (SIP/333-00007431): packet to 192.168.0.15:6042 (seq 18, len 31)

Если пакеты есть только от одной стороны – значит где косяк или с портами или с NAT или маршрутизацией
(В самом худшем случаи с провайдером, который может просто не пускать факс по t38 и придется гонять факс в голосе g711 – где уже нет никакой диагностики)

Продолжаем:
А бывают ли случаи когда нечего сделать нельзя и факсы вообще не ходят – не по t38 не по g711 ?
Такой провайдер как Энфорта доказал что это можно сделать
Вводная теория:
Когда мы общаемся с провайдером есть так сказать 2 вида связи:
1) Сигналка: это всякие служебные сообщения суть которых рассказана выше (INVITE, OPTIONS, REGISTRY)
2) Голосовой трафик: RTP где собственно идет уже сам голос каком нибудь кодаке

Провайдер ради снижения нагрузки может разбивать Сигналку и Голос на разные адреса:
Типа: регистрации и служебные общения на 109.109.109.199
А голосовой трафик уже на 109.109.109.200

Так вот, Энфорта сделала это, проблема только в том что голосовой трафик она пустила на свою внутреннюю сеть,
которую не видно снаружи 172.24.59.10
( мы ведь помним что 172.16.0.0 — 172.31.255.255 (Маска подсети 255.240.0.0 или для бесклассовой адресации /12))
Соответственно в заголовке приходит что трафик надо слать на 172.24.59.10 – и вообщем все … некуда его слать
Это их косяк – они в invite анонсируют внутреннею сеть

Update:

exten => что-то,n,Set(FAXOPT(gateway)=yes)
exten => что-то,n,ReceiveFAX(${FAXFILE},f)
Пишет ошибку: “executing ReceiveFAX on a channel with a T.38 Gateway is not supported”
Достаточно убрать Set(FAXOPT(gateway)=yes)
также очень важно чтобы на стороне провайдера был отключен транскодинг. Иначе факсы не ходят.
ReceiveFAX – работает если номер виртуальный..если в sip.conf прописать номер то работать не будет!

Передача факсов через VoIP-сети не работает. Иногда у вас получится достичь достаточно высокого процента успешных передач факсов. Может случиться, что вы создадите такую установку, которая будет работать на 100% всё время своего существования. Это редкие, неповторимые установки. Вам необходимо использовать правильный протокол FAX over IP, такой, как например Т.38, чтобы достичь постоянного, надёжного результата передачи факсов через IP-сети.

Для скептиков

Вы не верите, что передача факсов через VoIP-протоколы не работает? Вы слышали, что всё прекрасно работает если использовать кодеки рекомендации G.711? Читайте далее, если вы хотите понять, почему всё намного сложнее, и проблематичнее, чем этот подход.

Пытаясь ужиться с передачей факсов через VoIP-сети…

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

Не получится налить кварту в пинту

Наиболее распространённая проблема при передачи факсов через VoIP-сети – это самая простая из решаемых. Речевые кодеки с низкой скоростью передачи данных не могут передавать быстрые модемные сигналы без грубейшего их искажения. Неужели вы ожидаете, что G.729 8 кбит/с кодек сможет без искажений передать сигнал модема факса скорости 9.6 кбит/с? Если да, то, скорее всего, вы верите в вечный двигатель, и так далее. Я бы смог вам предложить неплохую сделку по этому поводу, если вы согласитесь купить Лондонский мост (London Bridge – прим. перевод.). Единственные широко поддерживаемые кодеки, которые могут адекватно сохранить сигналы модема факса до 14,4 бод (V.17) – это G.711 u-закон и A-закон. Полная версия G.726 кодека также будет работать с сигналом факса до 9,6 бод. Хотя не все устройства, которые рекламируются с поддержкой G.726, будет действительно поддерживать эту спецификацию. Несколько быстрых переходов в коде программы кодека могут значительно сократить вычислительные издержки, и всего лишь небольшому числу людей нужна полная поддержка G.726. Поэтому результаты на разных устройствах могут отличаться. Как бы то ни было, G.726 кодек был специально разработан для передачи среднескоростных сигналов модемов, таких как протокол V.29 на котором работает факс.

Совсем недавно стали популярными факс-аппараты с поддержкой скорости передачи до 33,6 кбит/с (V.34bis). Эта скорость передачи вряд ли будет надёжно работать через любое VoIP-соединение, даже если используются кодеки G.711 A-закон или u-закон. Кодеки смогут обеспечить требуемое качество сигнала, но задержки в VoIP-канале, даже если они будут стабильными, не дадут эхокомпенсаторам в любом факс-модеме возможности обучиться до нужного предела. Более медленные модемы факсов – V.27ter, V.29 и V.17 не используют эхокомпенсации, поэтому данной проблемы с ними не возникает.

Низкоскоростные кодеки имеют нулевой шанс нормально передать любое стандартное факс-сообщение. Некоторые кодеки без проблем передадут через канал контрольные сообщения факса в 300 бит/с (V.21). Но они не смогут передать быстрые сигналы модемов, непосредственно несущие информацию о передаваемом сообщении.

Модемам не нравится относительность

В мире ТфОП, коммутированная сеть имеет конечное значение задержки для каждого конкретного звонка. Скорость, с которой данные попадают в сеть, всегда равна скорости, с которой они её покидают. Задержка между концами канала не имеет дрожаний фаз (jitter – прим. перевод.), и не изменяется пошагово в любой из своих характеристик, за исключением вынужденных обстоятельств (например переход на обходные маршруты, если часть канала, до этого проходившая через оптоволокно, вдруг оборвалась). Эти характеристики каналов требуются модемам, они были разработаны для них. В IP-сетях дрожания это просто факт, от которого никуда не уйти. Дрожание можно свести до допустимого предела, используя приоритезацию (QoS) трафика, поддерживаемую большинством IP-оборудования, но только если вы можете контролировать сеть от начала и до конца. Если же звонок проходит через публичную часть сети Internet, там нет QoS-а. С трудом можно представить себе бизнес-модель оператора связи, который бы ввёл бы QoS на публичной части сети. Поэтому, при первом приближении, временные характеристики голоса, входящего в VoIP-сеть, такие же, как на выходе, но при детальном рассмотрении они могут быть очень и очень разными.

Если VoIP-сеть работает через локальную сеть или через WAN-соединение с включенным QoS-ом, вы можете достичь близкую к нулю вероятность потери пакетов, и очень, очень низкое значение дрожаний. Далее, многие полагают, что буфер на приёмном конце канала будет смягчать влияния средних по величине дрожаний, поэтому сигнал на выходе VoIP-канала будет прекрасно восстанавливаться в оригинальный. Чаще всего, эти люди будут правы. Но никаких гарантий. Есть много различных конструкций буфера дрожаний. Много современных вариантов динамически адаптируют длину буфера тем или иным способом, тем или иным алгоритмом. Если дрожание невелико, динамическая буферизация отключается, и вся система работает хорошо. Если динамическое управление буфером нельзя отключить, его поведение может, в общем-то, значительно ухудшить качество восстановления сигнала модема. Различные алгоритмы будут:

  • Гарантированно терять пакеты, настраивая буферизацию до такого предела, когда некоторый постоянный процент пакетов не будут считаться поздними, и будут отбрасываться. Потеря пакетов обычно встраивается в такие алгоритмы, и результаты могут быть вполне приемлемыми для голоса. Это вполне резонный обмен: терять небольшое количество пакетов, и взамен иметь нечто менее подверженное задержкам.
  • Регулировать периоды тишины во всех отсчётах пакетов (обычно по 20 мс). В спецификации факса, некоторые периоды тишины определены значениями 75+-20мс. Периоды в 20мс могут сбить их с толку.
  • Постоянно регулировать временные характеристики вне периодов тишины, используя техники наложения краёв и смешения. Этот подход считается произведением искусства для речевых буферов, и при этом – полной катастрофой для модема факса…

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

Модемы не любят подавление тишины

В зависимости от реализации в том или ином оборудовании, подавление тишины может полностью уничтожить звонок с факсом. Если подавление тишины включено, детектор голоса постоянно проверяет звонок, пытаясь обнаружить наличие голоса – т.е. сигналов модема. Некоторые из них были разработаны таким образом, чтобы фокусироваться на речевом сигнале, и отбрасывать все посторонние шумы – в нашем случае тоны модема факса. Поэтому, эти детекторы могут недоброкачественно включать и выключать аудио-нагрузку когда модем факса начинает и заканчивает передачу. И если даже они качественно переключаются, алгоритмы подавления тишины обычно сильно искажают сигналы уровни которых находятся около пороговых отметок.

Во время периодов тишины, в аудио-нагрузку постоянно вносится “комфортный шум”, который симулирует нормальную обстановку, которую вы слышите во время привычного звонка через ТфОП. Это означает, что период, который обычно будет полон тишины (факсы передают сгенерированные сигналы, то есть нет внешних шумов), будут сильно зашумлены. Модем на приёмной стороне может не увидеть достаточно чёткой “тишины” чтобы корректно определять границы сигналов модема передающего факса.

Модемы любят полное общение

Модемам требуется полноценный канал аудио. Если внести в него потерю пакетов, последствия будут суровыми, но реальный эффект будет зависеть в основном от оборудования, которое вы используете. Предположим, пакет в 20мс теряется в середине страницы факса. Понятно, что эта потеря приведёт к утрате какой-то части передаваемого изображения, но будет ли это влиять на передачу небольшого отрезка, или всего остатка страницы? Если приёмная сторона VoIP-канала вставляет 20 мс тишины, приёмный модем факса почти наверняка воспримет эти 20 мс как конце страницы. Если приёмная сторона вставляет 20 мс какого-то шума или звука, приёмный модем факса наверняка сможет перейти через разрыв в приёме. Всё зависит от конкретного оборудования. Если приёмная сторожа вставляет больше или меньше чем 20 мс какого-то шума, понятно, что остаток страницы будет принят с искажениями.

Подводя итог сказанному

Факс, как и все прочие приложения с использованием модемных соединений, работают из рук вон плохо и ненадёжно при передаче через VoIP-каналы. Эта ситуация не изменится в лучшую сторону со временем. Она будет ухудшаться. Вообще говоря, чем сложнее становится оборудование в гонке за качественной передачей голоса, тем хуже это оборудование становится для использования с модемами. В ближайшей перспективе (например, до того момента, когда все приложения по работе с данными будут полностью работать на IP-протоколе), единственным выходом для достижения приемлемых результатов будут протоколы с промежуточным хранением store-and-forward, а также протоколы, “подогнанные” для передачи модемных данных поверх IP-каналов.

Спецификация FAX over IP (FoIP)

Большинству современных факсовых аппаратов не хватает порта RJ-45 и поддержки стека протоколов TCP/IP. Лишь несколько из самых самых последних моделей факсов могут напрямую подключаться к Интернет, даже несмотря на то, что протоколы для этого были стандартизованы ещё пять-семь лет назад. На сегодняшний день только несколько самых высококлассных факсовых аппаратов содержат такой функционал. Что это означает? Это означает, что в мире, стремительно движущемся в сторону VoIP для телефонии, срочно необходима поддержка работы традиционных факсовых аппаратов поверх IP-каналов, и эта поддержка будет нужна до тех пор, пока самый последний традиционный факс не будет утилизирован.

FoIP с промежуточным хранением (Store and forward FoIP) – T.37

Спецификация T.37 определяет стандартный метод передачи факсов через IP-сети методом промежуточного хранения. Это простой, элегантный и надёжный метод. Единственный реальный недостаток – что это не метод реального времени. На самом деле это даже преимущество, но чисто психологически это самый что ни на есть недостаток. Передача факсов в реальном времени даёт пользователю иллюзию того, что как только его аппарат сказал “Отправка завершена”, документ уже в руках получателя. Конечно, это полностью ложное представление. Документ может находиться в неком буфере (например, в буфере факсового аппарата, в котором кончилась бумага, или в сервере Fax-to-email), о котором пользователь ничего не знает. Документ может находиться в корзине для мусора, потому что его сочли спамом. Конечно, если начать это объяснять, все проникаются идеей и говорят что понимают. Но никто не собирается отказываться от неприязни к факсам, не работающим в реальном времени. Некоторые полагают, что отчёт, выданный факсовым аппаратом, можно привязать к документу, удостоверяющему некое официальное действие: “мы отправили вам факс и вы получили его в таком-то часу”. Возможно. Одно время суды принимали как улики отчёты телексов, отправляемые организациями, подделка которых занимала не так много времени.

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

Рекомендация T.37 определяет процедуру приёма факса на шлюзе, создания e-mail сообщения, содержащего факс как приложение, пересылку e-mail сообщения на удалённый шлюз, набор номера и доставку факса к принимающей стороне. Опционально, факс может быть доставлен в виде приложения непосредственно на e-mail принимающей стороне. Также, факсы могут быть отправлены непосредственно в систему промежуточного накопления по электронной почте от самого отправителя, чтобы затем набрать номер и передать сообщение на традиционный факс.

T.37 – это очень простая спецификация. Ей не надо многого объяснять. Она основана на проверенных временем, широко используемых протоколах – SMTP, MIME и так далее – и только лишь определяет некоторые детали, необходимые для связи всех составляющих воедино и использования с факсом. Это означает, что спецификацию T.37 можно очень просто развернуть в любой системе, содержащей составляющие компоненты. T.37 это хорошая спецификация. T.37 это зрелая, здоровая спецификация. T.37 – это единственно здравый способ работать с факсом на сегодняшнее время.

FoIP реального времени (Real time FoIP) – T.38

Всего лишь один стандарт был разработан для факса в реальном масштабе времени через IP – спецификация T.38. Прежде чем приступить к обсуждению, что есть T.38, необходимо отметить некоторые факты о текущем статусе стандарта в реальном мире, справедливые на сегодняшний день. Большое количество VoIP-шлюзов и прочего оборудования до сих пор не поддерживают T.38. Много шлюзов, на коробках которых написано «поддержка T.38», всего лишь имеют T.38 в очереди дополнений на разработке, как например обстоит дело с Linksys SPA2100. Очень немного из текущих разработок T.38 поддерживают факсы на скорости 33600 бит/с (протокол V.34bis) , хотя сейчас почти все малобюджетные факс-аппараты и многофункциональные устройства (принтер/сканер/копир/факс) поддерживают её. Множество шлюзов имеют очень недоработанные подпрограммы, связанные с T.38 – я лично использовал небольшой шлюз, который намертво зависал как только слышал сигнал факса. Если вы знаете, как работает T.38, вы должны представлять, как ведут себя его «ключные» версии.

Итак. Что такое T.38?

T.38 это протокол передачи факсов через IP-сети (FAX over IP) реального времени. Это означает, что он был создан чтобы работать точно так же как традиционная передача факсов. Вы звоните на другой факсовый аппарат, и, пока ждёте, факс передаётся. Приёмным факсом может быть традиционный факсовый аппарат, подключенный к городской телефонной сети, VoIP-шлюз или его подобие, это может быть факсовый аппарат с портом RJ-45, подключаемый непосредственно в IP-сеть, или это может быть компьютер с факс-модемом. Что угодно!

Есть несколько нюансов, без которых невозможно заставить FoIP отлично работать с традиционными факсовыми аппаратами. Наиболее поздние версии основного факсового протокола – T.30 – содержат пункты и специальные функции, позволяющие современным факсовым аппаратам стать «знающими Интернет» (Internet-aware, – прим. перев.) факсами. Такие факсы соединяются со спецификацией T.38. Некоторые производители факсов пишут на упаковке что их аппараты – «Internet-aware devices». Это не значит что они соединяются напрямую с IP-сетями. Это только лишь значит, что они знают о существовании и характеристиках T.38.

Как работает T.38?

Исходная версия спецификации T.38 определяла два метода передачи факсов через IP-сети – одну основанную на UDP, и другую – на TCP протоколе. В то время RTP был лишь зарождающимся протоколом для вещания музыки через IP-сети. Вместо того чтобы использовать RTP, T.38 определила свой собственный способ упаковки данных в пакеты UDP, который получил название UPDTL. Сейчас этот шаг признают ошибочным, и версия протокола T.38, основанная на RTP, уже определена. Это только добавило проблем инженерам, внедряющим T.38 на своих устройствах. На деле, наиболее широко распространённый метод – это не-RTP метод, поэтому надо будет сначала добавлять поддержку RTP, а потом плавно мигрировать… ААААААААААААА!!!

Спецификация T.38 говорит какие-то странные вещи о том, когда использование UDP метода предпочтительней TCP, и наоборот. Я бы сказал что метод TCP должен быть использован между двумя IP-устройствами. Когда один из узлов подключен к аналоговой линии, скорее всего, лучше использовать UDP-метод, у которого лучше характеристики приближающие его к протоколу реального времени. Хотя, как известно, UDP – очень ненадёжный протокол, и это серьёзно компрометирует T.38 как надёжную спецификацию для передачи факсов через IP-сети.

T.38 это очень обобщённая спецификация. Большинство современных спецификаций модемных протоколов пытаются действительно разъяснить что должно произойти в аппаратуре. T.38 оставляет гигантский простор для решений во время внедрения в устройствах.

В каких аспектах T.38 лучше чем FAX over VoIP?

Если T.38 используется поверх TCP, то это очень надёжно. Если использовать T.38 между «Internet-aware» факсами, то этот метод решает все проблемы передачи факсов через VoIP соединения.

Если T.38 используется в одной из UDP форм, можно использовать вариант когда каждый следующий пакет содержит копию основной информации из предыдущего пакета. Это необязательная опция, но большинство виденных мной вариантов T.38 поддерживают её. Такая схема принудительной коррекции ошибок делает T.38 более равнодушным к потерянным пакетам, нежели обычные протоколы VoIP. Необходимо потерять два пакета последовательно, чтобы реально что-то потерять. Заголовки в T.38 такие большие, что дополнительная информация, передаваемая в теле пакета, едва ли заметна. Конечно, если потерять два пакета подряд, у T.38 будут проблемы. Но, если такое случается часто, это также значит что сеть, через которую идёт передача, не пригодна для качественной связи по VoIP-каналам.

Потеря пакета в потоке T.38 не влечёт за собой сбой синхронизации модемов. Это означает что два потерянных пакета всего лишь повредят часть передаваемого изображения. Если на факсовых аппаратах используется опциональная коррекция ошибок (ECM), велика вероятность того что с одним-двумя повторами передаваемое изображение будет получено с великолепным качеством. Не идеальное решение конечно, но вполне функциональное.

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

Спецификация T.30 позволяет приостановить передачу страницы непосредственно перед концом любой строки пикселей. Эта особенность используется как мера контроля потоковой передачи в факсовых аппаратах с медленной печатью например. Эта особенность также может быть использована в продуктах на базе T.38, – ожидать приёма большего количества информации когда пакет задерживается или оказывается утраченным. Это означает, что шлюз с поддержкой T.38 может начать передачу страницы как только у него будет хотя бы часть информации от отправителя со стороны IP-сети, без необходимости промежуточной буферизации. В случае, если эффект джиттера минимален, задержка передачи также минимальна. Когда джиттер велик, передача будет задерживаться на столько, насколько это необходимо. Если пакет теряется и исправление ошибок включено, передающий шлюз может просто подождать некоторое время, пытаясь восстановить утраченную информацию из потока следующих пакетов. Если необходимая информация безвозвратно потеряна, передача будет продолжена с минимальным количеством утраченных частей страницы.

Передача HDLC (High-Level Data Link Control), , используемая в управляющих сообщениях факсового протокола, не позволяет точно контролировать поток сообщений. Как бы то ни было, существует возможность достичь достаточно хороших результатов. Протокол HDLC поддерживает контроль потока только между HDLC-фреймами. Полный HDLC протокол поддерживает возможность отменять фреймы на полпути, или возобновлять их передачу. Однако, протокол HDLC как он определяется в спецификации T.30 не поддерживает функции отмены передачи фреймов. Если нам приходится ждать конца большого фрейма для того чтобы отменить его и начать повторную передачу, мы сталкиваемся с большими задержками. Как бы то ни было, это не большая проблема для передачи факсов в рамках T.30. Большая часть HDLC фреймов, использующихся в спецификации T.30, достаточно коротки, особенно те которые встречаются между страницами. Задерживая передачу до того, как мы полностью получим данные для одного из этих сообщений не будет слишком затягивать звонок. Чтобы избежать длинных задержек для очень длинных фреймов мы можем использовать правила типа «если длина фрейма не более 30 байт (1 секунда), мы ждём получения всего фрейма чтобы продолжить; если длина фрейма больше, мы передаём его с задержкой в 1 секунду».

Какие недостатки у T.38?

Спецификация T.38 не может избежать простой проблемы, состоящей в том что ей необходимо работать со старыми факсовыми аппаратами, созданными даже до того как идея FoIP пришла кому-то в голову. Этим аппаратам требуется соблюдение жёстких временных критериев задержек в каналах связи. Для этих аппаратов T.38 частично устраняет, частично уменьшает масштаб проблемы передачи факсов по VoIP-сетям. Однако, это ничто по сравнению с передачей изображения по FTP или HTTP и возможностями данных протоколов справляться с плохими условиями сетевых соединений.