Моя вариация на тему rfw клиента :)

Технические вопросы по UTM 5.0
Ответить
Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Моя вариация на тему rfw клиента :)

Сообщение Denis Samsonov »

Выкладываю свой вариант :) подходит для утм5, а вообще можно к любому биллингу и любому шейперу прикрутить

Код: Выделить всё

#!/usr/local/bin/php
<?php
#скрипт генерации правил шейперов. должен запускаться по крону
include &#40;"/netup/wkbill/config.php"&#41;;
###функции
######################################################правила для IPFW
#создание файла для ipfw
function ipfw_create_file&#40;$ipfw_commands_file&#41; &#123;
	$file=fopen&#40;$ipfw_commands_file,"w+"&#41;;
	fwrite&#40;$file, "#!/bin/sh\n"&#41;;
	fwrite&#40;$file, "fwcmd=\"/sbin/ipfw -q\"\n"&#41;;
	fclose&#40;$file&#41;;
&#125;
#создание пайпа dummynet
function ipfw_create_pipe&#40;$ipfw_commands_file,$pipe_id,$in_speed,$out_speed,$tariff_id,$tariff_name&#41; &#123;
	$file=fopen&#40;$ipfw_commands_file,"a+"&#41;;
	fwrite&#40;$file,"#Tariff ID&#58; $tariff_id Name&#58; $tariff_name\n"&#41;;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; pipe $pipe_id config mask dst-ip 0xffffffff bw ".$in_speed."Kbit/s\n"&#41;;
	$pipe_id=$pipe_id+1000;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; pipe $pipe_id config mask src-ip 0xffffffff bw ".$out_speed."Kbit/s\n"&#41;;
	fclose&#40;$file&#41;;
&#125;
function ipfw_table_add&#40;$ipfw_commands_file,$ip,$pipe&#41; &#123;
	$file=fopen&#40;$ipfw_commands_file,"a+"&#41;;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; table 1 add $ip $pipe\n"&#41;;
	$pipe=$pipe+1000;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; table 2 add $ip $pipe\n"&#41;;
	fclose&#40;$file&#41;;
&#125;

function ipfw_table_del&#40;$ipfw_commands_file,$ip&#41; &#123;
	$file=fopen&#40;$ipfw_commands_file,"a+"&#41;;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; table 1 delete $ip\n"&#41;;
	fwrite&#40;$file,"\$&#123;fwcmd&#125; table 2 delete $ip\n"&#41;;
	fclose&#40;$file&#41;;
&#125;


#################################################основной скрипт
$utm5dblink = mysql_connect&#40;$utm5dbhost , $utm5dbuser, $utm5dbpass&#41;or die &#40;"Возникла ошибка при подключении к базе данных\n"&#41;; //подключаемся к базе
mysql_select_db&#40;$utm5dbname&#41; or die &#40;"Возникла ошибка при выборе базы данных\n"&#41;;
#узнаем текущий час
$cur_hour=date&#40;"H&#58;i&#58;s"&#41;;
$current_time=strtotime&#40;now&#41;;
#создаем файл в который будем писать комманды для шейперов
ipfw_create_file&#40;$ipfw_commands_file&#41;;

#запрос на получение существующих правил для тарифов
$query = mysql_query&#40;"SELECT * FROM tariffs, wk_shaper_rules WHERE wk_shaper_rules.tariff_id = tariffs.id AND tariffs.is_deleted=0"&#41; or die&#40;"не удается получить список правил для тарифов"&#41;;
$numresults = mysql_num_rows&#40;$query&#41;;
for &#40;$i=0; $i <$numresults; $i++&#41;&#123;
	$row=mysql_fetch_array&#40;$query&#41;;
	$id=$row&#91;0&#93;; //id пользователя
	$tariff_id=iconv&#40;"cp1251", "KOI8-R", $row&#91;'tariff_id'&#93;&#41;; //ID тарифа $comment = iconv&#40;"cp1251", "UTF-8", $comment&#41;;
	$tariff_name=$row&#91;'name'&#93;; //Название тарифа
	$day_mode_start=$row&#91;'day_mode_start'&#93;; //начало дневного режима
	$day_mode_end=$row&#91;'day_mode_end'&#93;; //конец дневного режима
	$day_in_speed=$row&#91;'day_in_speed'&#93;; //входящая скорость дневного режима
	$day_out_speed=$row&#91;'day_out_speed'&#93;; //исходящая скорость дневного режима
	$night_mode_start=$row&#91;'night_mode_start'&#93;; //начало ночного режима
	$night_mode_end=$row&#91;'night_mode_end'&#93;; //конец дневного режима
	$night_in_speed=$row&#91;'night_in_speed'&#93;; //входящая скорость ночного режима
	$night_out_speed=$row&#91;'night_out_speed'&#93;; //исходящая скорость ночного режима
	$boost_in_speed=$row&#91;'boost_in_speed'&#93;; //входящая скорость n2o boost
	$boost_out_speed=$row&#91;'boost_out_speed'&#93;; //исходящая скорость n2o boost
	$night_boost_in_speed=$row&#91;'night_boost_in_speed'&#93;; //входящая скорость n2o boost ночь
	$night_boost_out_speed=$row&#91;'night_boost_out_speed'&#93;; //исходящая скорость n2o boost ночь

	#создаем правила шейпинга ночного режима
	if &#40;$cur_hour>=$night_mode_start AND $cur_hour<=$night_mode_end&#41; &#123;
		ipfw_create_pipe&#40;$ipfw_commands_file,$tariff_id,$night_in_speed,$night_out_speed,$tariff_id,$tariff_name&#41;;
	&#125;
	#в остальном случае создаем стандартные правила шейпинга
	else &#123;
		ipfw_create_pipe&#40;$ipfw_commands_file,$tariff_id,$day_in_speed,$day_out_speed,$tariff_id,$tariff_name&#41;;
	&#125;
	#если на тарифе есть услуга N2O Boost то создаем отдельные правила
	if &#40;$boost_in_speed>0 AND $boost_out_speed>0&#41; &#123;
		$boost_id=$tariff_id+2000;
		#n2o boost ночной режим
		if &#40;$cur_hour>=$night_mode_start AND $cur_hour<=$night_mode_end&#41; &#123;
			ipfw_create_pipe&#40;$ipfw_commands_file,$boost_id,$night_boost_in_speed,$night_boost_out_speed,$tariff_id,$tariff_name&#41;;
		&#125;
		#в остальном случае стандартные правила для n2o boost
		else &#123;
			ipfw_create_pipe&#40;$ipfw_commands_file,$boost_id,$boost_in_speed,$boost_out_speed,$tariff_id,$tariff_name&#41;;
		&#125;
	&#125;
&#125;
#пишем комманды на удаление/добавление правил в созданные пайпы
$query = mysql_query &#40;"SELECT sl.account_id, INET_NTOA&#40;ip & 4294967295&#41; AS ip, tsl.tariff_id, ac.int_status FROM ip_groups ig, iptraffic_service_links il, service_links sl, tariffs_services_link tsl, accounts ac WHERE ig.is_deleted =0 AND il.is_deleted =0 AND sl.is_deleted =0 AND ig.ip_group_id = il.ip_group_id AND sl.id = il.id AND sl.service_id = tsl.service_id AND ac.id = sl.account_id AND ig.ip_type =1"&#41; or die&#40;"Запрос к бд на получение правил доступа не прошел"&#41;;
$numresults = mysql_num_rows&#40;$query&#41;;
for &#40;$i=0; $i <$numresults; $i++&#41;&#123;
	$row=mysql_fetch_array&#40;$query&#41;;
	$tariff_id_out=0;
	$id = $row&#91;0&#93;; //ID пользователя
	$ip=$row&#91;'ip'&#93;; //IP адрес
	$tariff_id=$row&#91;'tariff_id'&#93;; //ID тарифа
	$tariff_id_out=$tariff_id+1000;
	$int_status=$row&#91;'int_status'&#93;; //статус интернета &#40;1 - включен 0 - выключен&#41;
	#проверяем. сменился ли тариф с предыдущего запуска или нет. если изменился то сначала удаляем старые правила
	$c_query = mysql_query&#40;"SELECT id FROM wk_shaper_rules_cache WHERE ip='$ip' AND tariff_id='$tariff_id'"&#41; or die&#40;"не удалось проверить правила с предыдущего запуска"&#41;;
	if &#40;mysql_num_rows&#40;$c_query&#41;==0&#41; &#123;
		print&#40;"У пользователя $id сменился тарифф\n"&#41;;
		ipfw_table_del&#40;$ipfw_commands_file,$ip&#41;;
		mysql_query&#40;"DELETE FROM wk_shaper_rules_cache WHERE ip='$ip'"&#41; or die&#40;"не удается удалить старую запись из кеша"&#41;;
		mysql_query&#40;"INSERT INTO wk_shaper_rules_cache &#40;ip, tariff_id&#41; VALUES &#40;'$ip', '$tariff_id'&#41;"&#41;;
	&#125;
	#если интернет включен то даем разрешающее правило
	if &#40;$int_status==1&#41; &#123;
		#сначала проверяем услугу N2O Boost
		#проверяем не требуется ли подключить услугу
		$n2o_query = mysql_query &#40;"SELECT * FROM wk_service_n2o_boost WHERE boost_start_time<=$current_time AND boost_end_time>=$current_time AND ip_addr='$ip'"&#41; or die&#40;"не удается провертить подключение услуги N2O Boost"&#41;;
		if &#40;mysql_num_rows&#40;$n2o_query&#41;!=0&#41; &#123;
			$n2o_row=mysql_fetch_array&#40;$n2o_query&#41;;
			if &#40;$n2o_row&#91;'status'&#93;==0&#41; &#123;
				mysql_query&#40;"UPDATE wk_service_n2o_boost SET status=1 WHERE id=$n2o_row&#91;0&#93;"&#41;;
				ipfw_table_del&#40;$ipfw_commands_file,$ip&#41;;
			&#125;
			$boost_id=$tariff_id+2000;
			ipfw_table_add&#40;$ipfw_commands_file,$ip,$boost_id&#41;;
		&#125;
		#проверяем не требуется ли отключить услугу
		$n2o_query = mysql_query&#40;"SELECT * FROM wk_service_n2o_boost WHERE boost_end_time<=$current_time AND status=1 AND ip_addr='$ip'"&#41; or die &#40;"Запрос не прошел"&#41;;
		if &#40;mysql_num_rows&#40;$n2o_query&#41;!=0&#41; &#123;
			$n2o_row=mysql_fetch_array&#40;$n2o_query&#41;;
			if &#40;$n2o_row&#91;'status'&#93;==1&#41; &#123;
				mysql_query&#40;"UPDATE wk_service_n2o_boost SET status=0 WHERE id=$n2o_row&#91;0&#93;"&#41;;
				ipfw_table_del&#40;$ipfw_commands_file,$ip&#41;;
			&#125;
			ipfw_table_add&#40;$ipfw_commands_file,$ip,$tariff_id&#41;;
		&#125;
		#если допуслуг нету то просто разрешаем доступ в интернет
		else &#123;
				ipfw_table_add&#40;$ipfw_commands_file,$ip,$tariff_id&#41;;
		&#125;
	&#125;
	#если интернет выключен то даем команду на удаление из таблиц
	if &#40;$int_status==0&#41; &#123;
		ipfw_table_del&#40;$ipfw_commands_file,$ip&#41;;
	&#125;
&#125;

mysql_close&#40;$utm5dblink&#41;;
?>
все данные по тарифам храняться и скоростям и форсажу храняться в таблицах
wk_shaper_rules

Код: Выделить всё

CREATE TABLE IF NOT EXISTS `wk_shaper_rules` &#40;
  `id` int&#40;11&#41; NOT NULL auto_increment,
  `tariff_id` int&#40;11&#41; NOT NULL,
  `day_in_speed` int&#40;11&#41; NOT NULL,
  `day_out_speed` int&#40;11&#41; NOT NULL,
  `night_mode_start` time NOT NULL,
  `night_mode_end` time NOT NULL,
  `night_in_speed` int&#40;11&#41; NOT NULL,
  `night_out_speed` int&#40;11&#41; NOT NULL,
  `boost_in_speed` int&#40;11&#41; NOT NULL,
  `boost_out_speed` int&#40;11&#41; NOT NULL,
  `night_boost_in_speed` int&#40;11&#41; NOT NULL default '0',
  `night_boost_out_speed` int&#40;11&#41; NOT NULL default '0',
  PRIMARY KEY  &#40;`id`&#41;
&#41; ENGINE=InnoDB  DEFAULT CHARSET=koi8r;
таблица wk_service_n2o_boost

Код: Выделить всё

CREATE TABLE IF NOT EXISTS `wk_service_n2o_boost` &#40;
  `id` int&#40;11&#41; NOT NULL auto_increment,
  `account_id` int&#40;11&#41; NOT NULL,
  `boost_id` int&#40;11&#41; NOT NULL,
  `boost_start_time` int&#40;11&#41; NOT NULL,
  `boost_end_time` int&#40;11&#41; NOT NULL,
  `tariff_id` int&#40;11&#41; NOT NULL,
  `status` int&#40;11&#41; NOT NULL default '0',
  `ip_addr` varchar&#40;255&#41; NOT NULL,
  PRIMARY KEY  &#40;`id`&#41;
&#41; ENGINE=InnoDB  DEFAULT CHARSET=koi8r;
и для отслеживания изменившихся тарифных планов у пользователей мы еще держим кеш в таблице wk_shaper_rules_cache

Код: Выделить всё

CREATE TABLE IF NOT EXISTS `wk_shaper_rules_cache` &#40;
  `id` int&#40;11&#41; NOT NULL auto_increment,
  `ip` varchar&#40;255&#41; NOT NULL,
  `tariff_id` int&#40;11&#41; NOT NULL,
  PRIMARY KEY  &#40;`id`&#41;
&#41; ENGINE=InnoDB  DEFAULT CHARSET=koi8r;
скрипт запускается на сервере с биллнгом по крону

Код: Выделить всё

#Правила шейпера
*/5 * * * * /netup/wkbill/shaper_rules.php 2>&1
на каждом из маршрутизаторов раз в 3 минуты по крону пускается другой скрипт (который скачивает файл по ftp и запускает его), get_shaper_rules.sh

Код: Выделить всё

#!/bin/sh
#скрипт для скачивания правил шейпирования с маршрутизатора и их применения
ftp_login="xxxxx"
ftp_passw="xxxx"
/usr/bin/fetch -o /usr/local/wkt_scripts/ipfw_commands ftp&#58;//$ftp_login&#58;$ftp_passw@195.93.xxx.xxx/ipfw_commands
/bin/sh /usr/local/wkt_scripts/ipfw_commands
ко всему этому прикручивается вебморда для управления скоростями и временем, код не дам а покажу только скриншот :) можете сделать подобное или написать мне в приват если интересно :)

собстно скриншот управления правилами
Изображение

nik247
Сообщения: 45
Зарегистрирован: Пт окт 23, 2009 13:16

Re: Моя вариация на тему rfw клиента :)

Сообщение nik247 »

Denis Samsonov писал(а):Выкладываю свой вариант :) подходит для утм5, а вообще можно к любому биллингу и любому шейперу прикрутить

ко всему этому прикручивается вебморда для управления скоростями и временем, код не дам а покажу только скриншот :) можете сделать подобное или написать мне в приват если интересно :)
Попытался написать в приват:
Возможность отправки личных сообщений на этих форумах была отключена

Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Re: Моя вариация на тему rfw клиента :)

Сообщение Denis Samsonov »

nik247 писал(а):
Denis Samsonov писал(а):Выкладываю свой вариант :) подходит для утм5, а вообще можно к любому биллингу и любому шейперу прикрутить

ко всему этому прикручивается вебморда для управления скоростями и временем, код не дам а покажу только скриншот :) можете сделать подобное или написать мне в приват если интересно :)
Попытался написать в приват:
Возможность отправки личных сообщений на этих форумах была отключена
хм... в icq напишите мне

Ответить