так, в общем это решение временное, потом все равно надо доработать с учетом загруженности канала пользователя.
у меня adsl канал:
днем: 1024/1024 входящий/исходящий
ночью: 2048/1024 входящий исходящий
сделал таким образом: по умолчанию весь канал прописывается к одному pipe. при подключении пользователей к vpn им выделяется их скорость из pipe по умолчанию, при отключении скорость снова добавляется к pipe по умолчанию.
ниже скрипты:
#mpd.conf:
Код: Выделить всё
set iface up-script "/etc/ipfw/ipfw_limits_add.php"
set iface down-script "/etc/ipfw/ipfw_limits_del.php"
#day_night_changer.php скрипт для удвоения ночной скорости в 2 раза, и для уменьшения скорости утром. увеличение скорости с 12 ночи до 8 утра. вызывается через cron
Код: Выделить всё
#!/usr/local/bin/php
<?
$users=file('/etc/ipfw/ipfw_user_pipes');
$ifc=shell_exec('ifconfig');
$pattern="/inet[\s]+.*->[\s]+(.*)[\s]+netmask/iUs";
preg_match_all($pattern,$ifc,$ma);
$ips=$ma[1];
$now_hour=date('H');
if($now_hour>=0 and $now_hour<8)
$max=2048;
else
$max=1024;
$all_in=0;
$all_out=0;
foreach($users as $str)
{
list($id,$user,$in,$out)=explode('|',$str);
if($now_hour>=0 and $now_hour<8)
$in=$in*2;
if(in_array("172.16.0.{$id}",$ips))
{
shell_exec("/sbin/ipfw pipe {$id}1 config bw {$in}Kbit");
$all_in+=$in;
}
}
$to_me=$max-$all_in;
shell_exec("/sbin/ipfw pipe 361 config bw {$to_me}Kbit");
?>
#ipfw_limits_add.php - выделение канала пользователю.
Код: Выделить всё
#!/usr/local/bin/php
<?
$user_arg=$argv[5];
$action='add';
$users=file('/etc/ipfw/ipfw_user_pipes');
foreach($users as $str)
{
list($id,$user,$in,$out)=explode('|',$str);
$now_hour=date('H');
if($now_hour>=0 and $now_hour<8)
$in=$in*2;
if($user===$user_arg)
{
$str=shell_exec("/sbin/ipfw pipe 361 list");
$pattern="/00361:(.*)[\d]+.*ms/";
preg_match($pattern,$str,$ma);
$now_bw=trim($ma[1]);
if(stripos($now_bw,'Mbit/s'))
{
$now_bw=str_replace('Mbit/s','',$now_bw);
$now_bw=$now_bw*1000;
}
if(stripos($now_bw,'Kbit/s'))
{
$now_bw=str_replace('Kbit/s','',$now_bw);
$now_bw=intval($now_bw);
}
$out=$in/2;
shell_exec("/sbin/ipfw pipe {$id}0 config bw ".$out."Kbit");
shell_exec("/sbin/ipfw pipe {$id}1 config bw ".$in."Kbit");
shell_exec("/sbin/ipfw add ${id}0 pipe {$id}0 all from 172.16.0.{$id} to any in via {$argv[1]}");
shell_exec("/sbin/ipfw add ${id}1 pipe {$id}1 all from any to 172.16.0.{$id} out via {$argv[1]}");
$new_bw=$now_bw-$in;
shell_exec("/sbin/ipfw pipe 361 config bw {$new_bw}Kbit");
}
}
?>
#ipfw_limits_del.php - при отключении пользователя, часть его канала возвращается к pipe-по умолчанию
Код: Выделить всё
#!/usr/local/bin/php
<?
$user_arg=$argv[5];
$action='del';
$users=file('/etc/ipfw/ipfw_user_pipes');
foreach($users as $str)
{
list($id,$user,$in,$out)=explode('|',$str);
$now_hour=date('H');
if($now_hour>=0 and $now_hour<8)
$in=$in*2;
if($user===$user_arg)
{
$str=shell_exec("/sbin/ipfw pipe 361 list");
$pattern="/00361:(.*)[\d]+.*ms/";
preg_match($pattern,$str,$ma);
$now_bw=trim($ma[1]);
if(stripos($now_bw,'Mbit/s'))
{
$now_bw=str_replace('Mbit/s','',$now_bw);
$now_bw=$now_bw*1000;
}
if(stripos($now_bw,'Kbit/s'))
{
$now_bw=str_replace('Kbit/s','',$now_bw);
$now_bw=intval($now_bw);
}
shell_exec("/sbin/ipfw pipe {$id}1 delete");
shell_exec("/sbin/ipfw pipe {$id}0 delete");
shell_exec("/sbin/ipfw del ${id}0");
shell_exec("/sbin/ipfw del ${id}1");
$new_bw=$now_bw+$in;
shell_exec("/sbin/ipfw pipe 361 config bw {$new_bw}Kbit");
}
}
?>
#ipfw_users_pipes -собственно база пользователей с их ограничениями. первое число есть последнее число в выдаваемом ip адресе через vpn - 172.16.0.XX, где XX - число из первого столбика. Имя пользователя должно быть введено точно также как и в mpd.secret, скорость задается в Kbit
Код: Выделить всё
34|user1|280|140
32|user2|424|212
177|user3|152|76