среда, 10 апреля 2013 г.

Ограничение скорости абонентам в UTM5 при помощи Expect.

Доброго времени суток, коллеги!
Ни для кого не секрет, что многие провайдеры используют биллинговую систему Netup UTM5 и по сей день. И судя по темам официального форума, наболевшим вопросом является автоматическое ограничение скорости абонентов при изменении или добавлении того или иного тарифа. На момент написания статьи были разработаны различные решения как участниками форума, так и самой компанией Netup, которая все-таки выпустила модуль динамического шейпирования.
В данной статье будет рассмотрено, на мой взгляд, один из простых, дешевых и надежных решений по шейпированию трафика абонентов на маршрутизаторах Cisco.
Для примера, рассмотрим географически распределенную систему в трех районах Москвы: Ясенево, Бутово, Люберцы. Центр обработки данных будет находиться в Ясенево, там же будет физически располагаться сервер UTM5.
Ядро UTM5 работает на ОС Centos 5.7. Данные с маршрутизаторов UTM5 получает по протоколу NetFlow. Команды от UTM5 маршрутизатор получает по протоколу ssh посредством программного обеспечения Expect.
Информацию по установке и настройке UTM5 можно найти в документации с официального сайта, здесь ее мы рассматривать не будем.
Schema_UTM5_shape
Приступим к предварительной настройке.
Запишем в блокнот (notepad.exe) шаблонные команды для маршрутизатора:
conf t
access-list 2289 permit ip host 1.1.1.4 any
access-list 2290 permit ip any host 1.1.1.4
interface GigabitEthernet0/0
traffic-shape group 2289 5120000 128000 128000 1000
exit
interface GigabitEthernet0/1
traffic-shape group 2290 5120000 128000 128000 1000
exit
exit
wr
exit

Устанавливаем expect: yum install expect –y
Expect - программа позволяющая автоматизировать передачу соответствующих команд тому или иному устройству. Синтаксис можно легко найти в интернете, но лучше всего воспользоваться автонастройкой: autoexpect ssh cisco@1.1.1.1
Этот скрипт осуществляет подключение к маршрутизатору с IP адресом 1.1.1.1 и логином cisco по протоколу ssh.
Вводим пароль и вставляем из блокнота шаблонный набор команд. После завершения сессии, в домашней директории сформируется файл script.exp, с набором команд для cisco.
Создаем новую папку для хранения скриптов: mkdir /scripts/
Затем скопируем в нее скрипт: cp script.exp /scripts/yas_speed_5Mb.exp
Данный скрипт ограничивает скорость абонента с IP адресом 1.1.1.4 до 5 Мегабит в секунду.
Для автоматизации ограничения скорости до 5Mb/s следует изменять номера аксесс листов и IP адреса абонентов.
Привяжем к каждому IP адресу номерную пару аксесс листов, для удобства лучше воспользоваться MS Excel:
Table
Редактируем: nano /scripts/yas_speed_5Mb.exp
В зависимости от версий expect’a синтаксис будет немного различаться. Поэтому рассмотрим, что нужно заменить в данном скрипте на нашем шаблонном наборе команд:
conf t
access-list $nech permit ip host $ip any
access-list $chet permit ip any host $ip
interface GigabitEthernet0/0
traffic-shape group $nech 5120000 128000 128000 1000
exit
interface GigabitEthernet0/1
traffic-shape group $chet 5120000 128000 128000 1000
exit
exit
wr
exit
Скрипту будем передавать IP адрес абонента, далее он выберет свою пару номеров аксесс листов из таблицы и присвоит их переменным chet и nech:
nano /scripts/yas_speed_5Mb.exp
Добавляем: set ip [lindex $argv 0]
Эта строчка говорит, что переменной ip присваивается значение первого аргумента переданного скрипту. Т.е. если мы выполняем скрипт yas_speed_5Mb.exp и ставим после него 1.1.1.4:
#/scripts/yas_speed_5Mb.exp 1.1.1.4, то переменной ip присвоится значение 1.1.1.4.
Другой пример:
nano /scripts/yas_speed_5Mb.exp
set ip [lindex $argv 0]
set rw [lindex $argv 1]
Выполняем: #/scripts/yas_speed_5Mb.exp 1.1.1.4 33
Получаем, что переменной ip присвоилось значение 1.1.1.4, а rw присвоилось значение 33.
Но в нашем случае будет использоваться только один аргумент.
Заполняем в скрипте таблицу соответствия ip/Nech№:
set 2001 1.1.1.1
set 2003 1.1.1.2
set 2005 1.1.1.3
set 2007 1.1.1.4
Присваиваем переменной nech значение соответствующего номера аксесс листа:
if {$ip==$2001} {set nech 2001}
if {$ip==$2003} {set nech 2003}
if {$ip==$2005} {set nech 2005}
if {$ip==$2007} {set nech 2007}
Тоже самое делаем и для нечетных номеров:
set 2002 1.1.1.1
set 2004 1.1.1.2
set 2006 1.1.1.3
set 2008 1.1.1.4
if {$ip==$2002} {set nech 2002}
if {$ip==$2004} {set nech 2004}
if {$ip==$2006} {set nech 2006}
if {$ip==$2008} {set nech 2008}
Для простоты заполнения советую воспользоваться программой MS Excel.
Сохраняем и тестируем:
#/scripts/yas_speed_5Mb.exp 1.1.1.2
Получаем на выходе:
conf t
access-list 2003 permit ip host 1.1.1.2 any
access-list 2004 permit ip any host 1.1.1.2
interface GigabitEthernet0/0
traffic-shape group 2003 5120000 128000 128000 1000
exit
interface GigabitEthernet0/1
traffic-shape group 2004 5120000 128000 128000 1000
exit
exit
wr
exit
Настройка скрипта закончена.
Приступаем к настройке UTM5.
Копируем 4 файла:
  1. cp /netup/utm5/rfw5.cfg   /netup/utm5/rfw5_yas_speed_5Mb.cfg
  2. cp /netup/utm5/bin/utm5_rfw   /netup/utm5/bin/utm5_rfw_yas_speed_5Mb
  3. cp /netup/utm5/bin/safe_utm5_rfw   /netup/utm5/bin/safe_utm5_rfw_yas_speed_5Mb
  4. cp /etc/init.d/utm5_rfw   /etc/init.d/utm5_rfw_yas_speed_5Mb
Редактируем соответствующие файлы: 

1. Nano /netup/utm5/rfw5_yas_speed_5Mb.cfg
rfw_name=yas_speed_5Mb  //Имя фаервола, которое указываем в UTM5
core_host=127.0.0.1  //IP адрес, где запущен UTM5
core_port=12758 //Порт подключения к ядру
rfw_login=login // Логин
rfw_password=passwd // Пароль
firewall_type=local // Тип фаервола
rfw_ssl_type=none
sync_flags=enable:disable
firewall_path=/scripts/yas_speed_5Mb.exp //Путь до скрипта
log_level=3
log_file_main=/netup/utm5/log/rfw5_main_yas_speed_5Mb.log
log_file_debug=/netup/utm5/log/rfw5_debug_yas_speed_5Mb.log
log_file_critical=/netup/utm5/log/rfw5_critical_yas_speed_5Mb.log

2. Nano /netup/utm5/bin/safe_utm5_rfw_yas_speed_5Mb
#!/bin/sh
# description: UTM Billing System Radius Safe start script
trap '' 1 2 3 15
pid_file=/var/run/utm5_ yas_speed_5Mb.pid  //Имя процесса
utm_exec=utm5_rfw_yas_speed_5Mb //Имя исполняемого файла
err_log=/netup/utm5/log/rfw5_yas_speed_5Mb.log
exec_dir=/netup/utm5/bin
root_email=root
rfw_flags=""
rfw_cfg=/netup/utm5/rfw5_yas_speed_5Mb.cfg //Путь до конф файла.

3. Nano /etc/init.d/utm5_rfw_yas_speed_5Mb
#!/bin/sh
# chkconfig: 2345 90 10
# description: UTM Billing System firewall control tool
trap '' 1 2 3 15
utm_exec=safe_utm5_rfw_ yas_speed_5Mb
exec_dir=/netup/utm5/bin

Запускаем: /etc/init.d/utm5_rfw_yas_speed_5Mb start
Добавляем в автозагрузку: chkconfig --level 35 utm5_rfw_yas_speed_5Mb on
После чего заходим в консоль администрирования UTM5 и создаем группу «Ясенево»:
UTM5_add_group
Добавляем тариф:
UTM5_add_tarif
Далее создаем Брандмауэр:
UTM5_add_brandm
Добавляем правило для Firewall:
UTM5_add_firewall

Давайте разберем последний пункт по-подробнее.
Брандмауэр был добавлен для того, чтобы указать какой именно скрипт запускать в текущем тарифном плане.
Группой ограничиваем распространение скрипта, в нашем случае только в районе Ясенево.
Привязываем тариф «Безлимит 5Mb/s» и указываем «Совпадают все параметры»
Добавляем два события:
1. Включение интернета – для того чтобы оно вернуло нам IP адрес абонента, программа UTM5 видит его как «UIP» (см. документацию по продукту).
2. Добавление связки IP трафик - для того чтобы скрипт реагировал на изменение тарифа (см. документацию по продукту).
Перезапускаем:
/etc/init.d/utm5_rfw_yas_speed_5Mb stop
/etc/init.d/utm5_rfw_yas_speed_5Mb start
На этом настройка закончена.
Добавляем тариф пользователю, заходим на маршрутизатор и видим, как прописались соответствующие правила.
Если скрипт по каким-то причинам не отработал, все события, для решения проблемы можно посмотреть в логах. В нашем случае это:
/netup/utm5/log/rfw5_main_yas_speed_5Mb.log
/netup/utm5/log/rfw5_debug_yas_speed_5Mb.log
/netup/utm5/log/rfw5_critical_yas_speed_5Mb.log
/netup/utm5/log/rfw5_yas_speed_5Mb.log
Аналогичным способом настраивается ограничение скорости и на остальных маршрутизаторах.
На данный момент подобная схема работает без перебоев уже полтора года в продуктивной среде.
На этом предлагаю закончить.
Вопросы, замечания и предложения пишите в комментариях или на почту.
Удачного тестирования!