32
Шейпинг – это ограничение пропускной способности канала для абонентов сети передачи данных. По характеру ограничения шейпинг может быть:
–статическим (постоянным, т. е. зависящим только от тарифного плана);
–динамическим (меняющимся в зависимости от объёмов израсходованного трафика, а также от времени суток).
Система UTM5 предоставляет возможность настроить для отдельных видов трафика, услуг и тарифов как статический, так и динамический шейпинг.
Регулирование пропускной способности канала фактически происходит на маршрутизаторах. В качестве таких устройств могут выступать PC-маршрутизаторы, маршрутизаторы Cisco, управляемые коммутаторы и т. п. Взаимодействие биллинговой системы с этими устройствами может происходить следующим образом:
1.Средствами внешних скриптов. По некоторому событию (например, при расходовании определённого количества трафика) биллинговая система запускает внешний скрипт управления шейпером, который меняет пропускную способность канала (или, возможно, разрывает соединение). В параметрах скрипту обычно передаётся IP-адрес пользователя и новое значение установленной для него пропускной способности.
Скрипт вызывает внешние утилиты управления трафиком (например, tc из пакета iproute2 в случае Linux и ipfw в случае FreeBSD с включённой функциональностью dummynet). Для использования данных утилит может требоваться предварительная настройка операционной системы или стороннего ПО.
2.При помощи RADIUS-атрибутов (в случае услуг передачи трафика и коммутируемого доступа). В ответе на запрос аутентификации RADIUS-сервер может отправлять атрибут или набор атрибутов, определённый для данного абонента и данного NAS и содержащий в себе инструкции по управлению пропускной способностью устанавливаемого соединения. В данном случае необходима поддержка этой возможности программным обеспечением со стороны NAS. Такой поддержкой обладают, в частности, маршрутизаторы Cisco.
При данном способе управления пропускная способность задается в момент установления соединения, и её корректировка в зависимости от израсходованного трафика происходит не мгновенно при достижении определённого значения, а только при следующем соединении.
Описанные способы регулирования пропускной способности могут применяться как отдельно, так и одновременно.
Система UTM5 предлагает следующий подход к шейпингу:
1.В случае шейпинга с помощью внешних скриптов передаваемые скрипту параметры настраиваются на странице Правила firewall (см. Правила firewall). Каждое правило ассоциировано с одним или несколькими событиями, при наступлении которых выполняется внешний скрипт с заданными параметрами. Путь к скрипту указывает переменная firewall_path в конфигурационном файле utm5_rfw.cfg.
–Статический шейпинг можно реализовать с помощью правил, выполняемых, например, при наступлении события Включение Интернета.
–Динамический шейпинг (возможен при наличии соответствующего модуля) осуществляется правилами, выполняемыми при наступлении событий Установление пропускной способности, Изменение пропускной способности и Снятие ограничений входящего (исходящего) канала. События первых двух типов происходят в тот момент, когда суммарное количество трафика за отчётный период переходит через определённые границы, а событие Снятие ограничений – при закрытии отчётного периода или при удалении сервисной связки. Если настроены разные границы для разных временных диапазонов, события любого типа могут также происходить при наступлении времени начала/окончания диапазона. О задании границ см. Динамическое шейпирование.
|
Модуль динамического шейпинга требует отдельной лицензии. |
–Статический шейпинг настраивается на вкладке RADIUS-параметры на странице Услуга в группе Тарификация (см. Услуги).
–Динамический шейпинг (возможен при наличии модуля динамического шейпинга) настраивается на вкладке RADIUS-параметры на странице Динамическое шейпирование в группе Настройки (см. Динамическое шейпирование). Для каждой услуги, наряду с границами потребления трафика, можно задать RADIUS-атрибуты, устанавливающие пропускную способность канала. Динамическое изменение атрибутов в зависимости от потреблённого трафика обеспечивается использованием переменных, выбираемых из списка.
Ниже приведён пример RADIUS-атрибута для динамического шейпинга на маршутизаторе Cisco.
9;
1;
строка;
lcp:interface-config#1=rate-limit input IN_BANDWIDTH_BITS |
Перед отправкой данной строки на NAS система подставляет вместо переменной IN_BANDWIDTH_BITS числовое значение пропускной способности (бит/с) для пользователя, зависящее от потреблённого трафика и заданных границ. Остальные параметры интерпретируются следующим образом:
IN_CISCO_NORMAL_BURST – количество байт, пересылаемых за один всплеск (burst). Рассчитывается как поток за 1.5 сек. при заданной полосе пропускания.
IN_CISCO_EXTENDED_BURST – возможное количество байт сверх нормы (т. е. сверх IN_CISCO_NORMAL_BURST), пересылаемое за один интервал при кратковременном повышении нагрузки. После того как потрачено, восполняется за счёт пропускной способности в периоды, когда нагрузка ниже максимально разрешённой. Рассчитывается как 2* IN_CISCO_NORMAL_BURST.
Последующие инструкции указывают, что трафик в пределах разрешённой пропускной способности с учётом допустимых превышений пропускается маршрутизатором (conform-action transmit), а при превышении нагрузки и исчерпании EXTENDED_BURST приходящие пакеты данных сверх NORMAL_BURST игнорируются (exceed-action drop).
Ниже приведены примеры исполняемых файлов. Предполагается, что созданы правила firewall для событий Установление пропускной способности, Изменение пропускной способности и Снятие ограничений, и для каждого из них заданы параметры скрипта в формате:
UID UIP UBITS UMASK BANDWIDTH [0|1|2] |
Первые пять параметров представляют собой переменные. При вызове скрипта они будут заменены своими значениями:
идентификатор пользователя |
|
адрес пользователя |
|
маска сети |
|
количество бит в маске сети |
|
текущая скорость соединения |
В качестве последнего параметра надо указать значение 0, 1 или 2 в зависимости от типа события:
–1 – Установление пропускной способности;
–2 – Изменение пропускной способности.
Пример для программного шейпера iproute2 в ОС Linux.
Предполагается, что предварительно выполнены следующие команды:
tc qdisc add dev eth0 root handle 1: htb |
– создана очередь (qdisc, queueing discipline), ассоциированная с входящим интерфейсом eth0, имеющая идентификатор 1. Для очереди выбран метод упорядочения htb (Hierarchy Token Bucket), отличающийся простотой и высоким быстродействием.
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit burst 200k |
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1mbit burst 20k |
– создан корневой класс очереди (root class) с идентификатором 1:1, имеющий гарантированную пропускную способность 50 Мбит/сек (rate 50mbit) с возможностью повышения до 100 Мбит/сек при наличии незанятой пропускной способности (ceil 100mbit), пропускаемый всплесками размером по 200 Кб (burst 200k). Он будет использоваться как родительский для всех остальных классов и распределять между ними пропускную способность, предоставляя им возможность занимать (borrow) друг у друга неиспользуемую часть. Также создан класс с идентификатором 1:10, имеющий пропускную способность 1 Мбит/сек без возможности превышения, и предназначенный для пропускания трафика неопределённой принадлежности из очереди.
tc filter add dev eth0 parent 1: protocol ip prio 3 handle 1 fw classid 1:10 |
– создан фильтр, направляющий неклассифицированные пакеты из очереди в класс с наименьшей пропускной способностью.
В дальнейшем при вызове скрипта по событию Установление пропускной способности происходит следующее:
–создаётся правило iptables, помечающее входящие пакеты трафика, направленные на данный IP-адрес (при необходимости аналогичным образом выполняется шейпинг исходящего трафика, для чего следует создать отдельное правило);
–создаётся новый фильтр, отправляющий помеченные таким образом пакеты в новый класс;
–создаётся новый класс с указанной пропускной способностью.
По событию Изменение пропускной способности происходит изменение пропускной способности класса, а по событию Снятие ограничений – удаление самого класса, соответствующего фильтра и правила iptables.
Трафик, не попадающий под действие фильтров (т. е. принадлежащий пользователям, для которых шейпинг не настроен), не ставится в очередь, а пропускается непосредственно.
Содержимое исполняемого файла:
#!/bin/bash if="eth1" echo $* echo "First create: tc qdisc add dev $if root handle 1: htb" case "$6" in |
0) iptables -t mangle -D FORWARD -s 0/0 -d $2/$3 -j MARK |
1) iptables -t mangle -A FORWARD -s 0/0 -d $2/$3 -j MARK |
2) tc class change dev $if parent 1:1 classid 1:$1 htb rate $5kbit burst 20k;; *) echo "Usage: `basename $0` {UID UIP UBITS UMASK BANDWIDTH [0|1|2]}" >&2 exit 64;; esac |
Пример исполняемого файла для программного шейпера dummynet в ОС FreeBSD.
При вызове скрипта по событию Установление пропускной способности создаётся канал (pipe) с ограниченной пропускной способностью, а также правило, которое направляет входящий трафик данного пользователя на интерфейсе em0 в созданный канал. По событию Изменение пропускной способности изменяется пропускная способность канала, а по событию Снятие ограничений – удаляется канал и соответствующее правило.
Скрипт работает корректно при многопроходном режиме обработки правил (команда sysctl net.inet.ip.fw.one_pass должна возвращать значение 0).
#!/bin/sh case "$6" in 0) /sbin/ipfw delete $1 /sbin/ipfw pipe delete $1;; 1) /sbin/ipfw pipe $1 config bw $5Kbit/s /sbin/ipfw add $1 pipe $1 ip from any to $2/$3 via em0;; 2) /sbin/ipfw pipe $1 config bw $5Kbit/s;; esac |
Ниже приведён список переменных, которые могут использоваться в шаблонах (см. Шаблоны документов ).
Переменные, входящие в шаблоны, делятся на несколько групп:
Наименование |
Тип |
Описание |
document.number |
int32 |
Номер документа |
document.alt_number |
string |
Альтернативный номер документа |
document.date |
int32 |
Дата создания документа |
Наименование |
Тип |
Описание |
user.id |
int32 |
ID абонента |
user.full_name |
string |
Наименование абонента |
user.login |
string |
Логин абонента |
user.password |
string |
Пароль абонента |
user.actual_address |
string |
Фактический адрес |
user.juridical_address |
string |
Юридический адрес |
user.home_telephone |
string |
Домашний телефон |
user.work_telephone |
string |
Рабочий телефон |
user.mobile_telephone |
string |
Мобильный телефон |
user.tax_number |
string |
ИНН абонента |
user.kpp_number |
string |
КПП абонента |
user.icq_number |
string |
Номер ICQ |
user.web_page |
string |
Веб-страница |
user.district |
string |
Район |
user.building |
string |
Строение |
user.entrance |
string |
Подъезд |
user.floor |
string |
Этаж |
user.flat_number |
string |
Квартира |
user.personal_manager |
string |
Персональный менеджер |
user.basic_account |
int32 |
ID основного лицевого счета |
user.passport |
string |
Паспорт |
user.email |
string |
|
user.comments |
string |
Комментарий |
user.bank_account |
string |
Банковский счет |
user.bank_name |
string |
Наименование банка |
user.bank_city |
string |
Город банка |
user.bank_bic |
string |
БИК |
user.bank_corr_account |
string |
Корреспондентский счет |
user.currency_short_name |
string |
Краткое наименование валюты |
user.currency_full_name |
string |
Полное наименование валюты |
user.currency_code |
int32 |
Код валюты |
user.params.{param_id} (a) |
string |
Дополнительный параметр абонента с ID {param_id} |
user.contacts.{contact_id}.email (b) |
string |
E-mail дополнительного контакта с ID {contact_id} |
user.contacts.{contact_id}.full_name |
string |
Полное наименование дополнительного контакта с ID {contact_id} |
user.contacts.{contact_id}.short_name |
string |
Краткое наименование дополнительного контакта с ID {contact_id} |
user.contacts.{contact_id}.position |
string |
Должность дополнительного контакта с ID {contact_id} |
user.contacts.{contact_id}.reason |
string |
Описание дополнительного контакта с ID {contact_id} |
user.contacts.{contact_id}.telephone |
string |
Телефон дополнительного контакта с ID {contact_id} |
a.Переменная {param_id} может принимать значения целочисленного ID доп. параметра абонента
b.Переменная {contact_id} может принимать значения headman - руководитель, booker - бухгалтер, либо целочисленный порядковый номер дополнительного контакта, начиная с единицы
Наименование |
Тип |
Описание |
account.account_id |
int32 |
ID лицевого счета |
account.external_id |
string |
Внешний ID лицевого счета |
account.balance |
double |
Баланс |
account.credit |
double |
Кредит |
account.vat_rate |
double |
НДС в % |
account.sale_tax_rate |
double |
НСП в % |
account.access_card_number |
string |
Номер карты доступа IPTV |
Наименование |
Тип |
Описание |
provider.full_name |
string |
Полное наименование поставщика |
provider.short_name |
string |
Краткое наименование поставщика |
provider.juridical_address |
string |
Юридический адрес |
provider.actual_address |
string |
Фактический адрес |
provider.tax_number |
string |
ИНН |
provider.kpp_number |
string |
КПП |
provider.chief_full_name |
string |
Полное имя руководителя |
provider.chief_short_name |
string |
Краткое имя руководителя |
provider.booker_full_name |
string |
Полное имя бухгалтера |
provider.booker_short_name |
string |
Краткое имя бухгалтера |
provider.bank_account |
string |
Банковский счет |
provider.bank_name |
string |
Наименование банка |
provider.bank_city |
string |
Город банка |
provider.bank_bic |
string |
БИК |
provider.bank_corr_account |
string |
Корреспондентский счет |
Наименование |
Тип |
Описание |
contract.number |
int32 |
ID первого договора |
contract.name |
string |
Наименование первого договора |
contract.date |
int32 |
Дата создания первого договора |
contract.{contract_id}.number (a) |
int32 |
ID договора с порядковым номеров {contract_id} |
contract.{contract_id}.name |
string |
Наименование договора с порядковым номером {contract_id} |
contract.{contract_id}.date |
int32 |
Дата создания договора с порядковым номером {contract_id} |
user.connect_date |
int32 |
Дата подключения пользователя (отображается в формате unixtime) |
user.connect_date..date_short |
string |
Дата подключения пользователя (отображается в формате ДД.ММ.ГГГГ) |
a.Переменная {contract_id} принимает значение порядкового номера договора абонента, начиная с единицы
Наименование |
Тип |
Описание |
payment.id |
int32 |
ID транзакции платежа |
payment.amount_in_currency |
double |
Сумма в валюте |
payment.amount_absolute |
double |
Сумма в системной валюте |
payment.date.actual |
int32 |
Дата платежа |
payment.date.enter |
int32 |
Дата внесения |
payment.date.burn |
int32 |
Дата сгорания |
payment.document_number |
string |
Номер платежного документа |
payment.comments.user |
string |
Комментарий для пользователя |
payment.comments.admin |
string |
Комментарий для администратора |
payment.hash |
string |
Хэш-код |
payment.currency_rate |
double |
Курс валюты |
payment.currency_short_name |
string |
Краткое наименование валюты |
payment.currency_full_name |
string |
Полное наименование валюты |
payment.currency_code |
int32 |
Код валюты |
Наименование |
Тип |
Описание |
bill.sum_without_tax |
double |
Сумма без налогов |
bill.sum_with_tax |
double |
Сумма с налогами |
bill.size |
int32 |
Количество строк в счете |
bill.period_start |
int32 |
Дата начала периода |
bill.period_end |
int32 |
Дата конца периода |
bill.balance_when_created |
double |
Баланс в момент выставления |
bill.debt |
double |
Задолженность |
bill.payment_amount |
double |
Сумма платежа без учета налогов |
bill.payment_amount_with_tax |
double |
Сумма платежа с учетом налогов |
bill.date |
int32 |
Дата |
Наименование |
Тип |
Описание |
summary.periodic_fee |
double |
Сумма списаний по периодическим услугам |
summary.total_fee |
double |
Сумма списаний по услугам телефонии |
summary.other_fee |
double |
Сумма списаний по прочим услугам |
summary.local.charges |
double |
Сумма списаний за местные вызовы |
summary.local.count |
double |
Количество местных вызовов |
summary.local.duration |
double |
Суммарная длительность местных вызовов |
summary.innerzone.charges |
double |
Аналогично для внутризоновых вызовов |
summary.innerzone.count |
double |
|
summary.innerzone.duration |
double |
|
summary.intercity.charges |
double |
Аналогично для междугородних вызовов |
summary.intercity.count |
double |
|
summary.intercity.duration |
double |
|
summary.international.charges |
double |
Аналогично для международных вызовов |
summary.international.count |
double |
|
summary.international.duration |
double |
|
Наименование |
Тип |
Описание |
iptv.access_card_number |
int32 |
Номер карты доступа IPTV |
iptv.activation_code.part1 |
string |
Код активации карты доступа, часть 1. Код активации состоит из шести частей, для каждой части есть своя переменная, отличающаяся цифрой в конце (.part2,.part3 и т. д.) |
Далее приведены группы переменных, вместо которых подставляется массив значений. Переменные из этих групп следует располагать в шаблоне в строке таблицы. В этом случае при генерации документа в таблицу будет автоматически добавлено необходимое количество строк, чтобы вместить все значения.
Итерируемые переменные также делятся на несколько групп:
Наименование |
Тип |
Описание |
ipgroup.login |
string |
Логин IP-группы |
ipgroup.password |
string |
Пароль IP-группы |
ipgroup.mac |
string |
MAC адрес |
ipgroup.ip |
string |
IP адрес |
ipgroup.mask |
string |
Маска подсети |
ipgroup.gateway |
string |
Шлюз |
|
Итераторы таблицы IP-групп позволяют вывести информацию только о нединамических IP-группах, для которых поле Логин не пустое и IP-адрес не равен 0.0.0.0 |
–Итераторы таблицы подключенных тарифов
Наименование |
Тип |
Описание |
tariff.name |
string |
Наименование тарифа |
tariff.cost |
double |
Стоимость |
tariff.account_id |
int32 |
ID лицевого счета |
Наименование |
Тип |
Описание |
bill_entry.id |
int32 |
Порядковый номер позиции, начиная с единицы |
bill_entry.name |
string |
Наименование позиции |
bill_entry.price |
double |
Цена |
bill_entry.quantity |
double |
Количество |
bill_entry.sum_with_tax |
double |
Сумма с налогами |
bill_entry.sum_without_tax |
double |
Сумма без налогов |
bill_entry.tax |
double |
Сумма налога |
bill_entry.tax_rate |
double |
Ставка налога в % |
bill_entry.unit_name |
string |
Размерность (возвращается ключ для замены) |
bill_entry.unit_code |
string |
Код размерности (возвращается ключ для замены) |
bill_entry.alt.price |
double |
Альтернативная цена |
bill_entry.alt.quantity |
double |
Альтернативное количество |
bill_entry.alt.unit_name |
string |
Альтернативная размерность (возвращается ключ для замены) |
bill_entry.alt.unit_code |
string |
Альтернативный код размерности (возвращается ключ для замены) |
–Итераторы детализации звонков
Наименование |
Тип |
Описание |
call.id |
int32 |
Порядковый номер вызова в таблице |
call.zone |
string |
Наименование зоны |
call.direction |
string |
Наименование направления |
call.date |
int32 |
Дата вызова |
call.calling_number |
string |
Вызывающий номер |
call.called_number |
string |
Вызываемый номер |
call.called_prefix |
string |
Вызываемый префикс |
call.duration |
int32 |
Длительность вызова |
call.type |
string |
Тип вызова (возвращается ключ для замены) |
call.cost |
double |
Полная стоимость вызова |
–Итераторы параметров сервисных связок услуги коммутируемого доступа
Наименование |
Тип |
Описание |
dialup.login |
string |
Логин |
dialup.password |
string |
Пароль |
dialup.cid |
string |
Значение параметра CID |
dialup.csid |
string |
Значение параметра CSID |
–Итераторы параметров сервисных связок услуги hotspot
Наименование |
Тип |
Описание |
hotspot.login |
string |
Логин |
hotspot.password |
string |
Пароль |
–Итераторы параметров сервисных связок услуги телефонии
Наименование |
Тип |
Описание |
telephony.login |
string |
Логин |
telephony.password |
string |
Пароль |
telephony.number |
string |
Телефонный номер |
telephony.incoming_trunk |
string |
Входящий транк |
telephony.outgoing_trunk |
string |
Исходящий транк |
telephony.pbx |
string |
Значение параметра PBX ID |
telephony.cid |
string |
Значение параметра CID |
В зависимости от типа шаблона в него могут входить переменные и итерируемые переменные из следующих групп, перечисленных выше:
|
Счет |
Счет-фактура |
Памятка пользователя |
Акт |
Квитанция |
Договор |
Детализация счета |
Документ |
• |
• |
• |
• |
• |
• |
• |
Пользователь |
• |
• |
• |
• |
• |
• |
• |
Лицевой счет |
• |
• |
• |
• |
• |
• |
• |
Провайдер |
• |
• |
• |
• |
• |
• |
• |
Договор |
• |
• |
• |
• |
• |
• |
• |
Платеж |
|
|
|
|
• |
|
|
Счет |
• |
• |
|
• |
|
|
|
Сводка детализации звонков |
|
|
|
|
|
|
• |
Сервисные связки IPTV |
|
|
• |
|
|
• |
|
Итераторы счета |
• |
• |
|
• |
|
|
|
Итераторы таблицы IP-групп |
|
|
• |
|
|
• |
|
Итераторы таблицы подключенных тарифов |
|
|
• |
|
|
• |
|
Итераторы детализации звонков |
|
|
|
|
|
|
• |
Модификаторы переменных преобразуют значения, подставляемые вместо переменных. Доступны следующие типы модификаторов:
Наименование |
Тип аргумента |
Тип результата |
Описание |
translate |
string |
string |
Заменяет на значение из списка замены при полном совпадении значения переменной и ключа замены |
replace |
string |
string |
Заменяет на значение из списка замены часть значения переменной, совпадающую с ключом замены |
date_short |
int32 |
string |
Дата в формате ДД/ММ/ГГГГ |
date_long |
int32 |
string |
Дата в формате «ДД»Месяца ГГГГ |
date_time |
int32 |
string |
Время в формате ММ.ДД ЧЧ:ММ |
duration |
int32 |
string |
Длительность в формате ЧЧ:ММ:CC |
sum_to_string |
double |
string |
Сумма прописью |
Чтобы применить модификатор, при создании пользовательского поля в LibreOffice, перейдите в меню Вставка > Поля > Дополнительно, выберите вкладку Переменные, выберите нужную переменную и в поле Название укажите имя модификатора после имени функции, разделив их двумя точками:
Далее вставьте модифицированную переменную в нужное место шаблона.