Мда, биллинги конечно нужны. В смысле они нужны вообще :) А вот в частности наверное не очень.
Решение 3-х летней давности на базе linux + ipac-ng + чего-то свое. В принципе идея не нова :)
Ставим, настраиваем ipac-ng, согласно инструкции по эксплуатации.
файлик limit.conf
# Файл конфигурации ограничения трафика. Значения трафика в кБ. 0-неограничен
# Все поля разделены <TAB>
# Поля:
# <IPAC alias> <Адрес> <Пн> <Вт> <Ср> <Чт> <Пт> <Сб> <Вс>
serega 192.168.0.10 20000 15000 15000 15000 15000 15000 15000
dima 192.168.0.11 15000 15000 15000 15000 15000 15000 15000
natali 192.168.0.12 10000 10000 10000 10000 10000 -1 -1
buhgal 192.168.0.13 10000 10000 10000 10000 10000 -1 -1
journ 192.168.0.14 10000 10000 10000 10000 10000 -1 -1
reklama 192.168.0.15 0 15000 0 15000 15000 10000 10000
В файлике iptables.tmpl пишем правила какие надо, вроде этого:
/sbin/iptables -A FORWARD -s <ipaddress> -d 10.0.0.0/8 -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -s <ipaddress> -i eth0 -j DROP
Ну и дальше переодически пускаем limit.pl (корректируем в зависимости от того чего используем в качестве накопителя, а может переписываем совсем. За качество кода не пинать, написано минут за 10 при почти полном отсутствии опыта в перлении):
#!/usr/bin/perl
$LIMIT_FILE="/etc/ipac-ng/limit.conf";
$IPTABLES_TEMPLATE_FILE="/etc/ipac-ng/iptables.tmpl";
$TMP_LIMIT="/etc/ipac-ng/current.tmp";
$IPACSUM="/usr/local/sbin/ipacsum -t today --fixed-quantity K > ".$TMP_LIMIT;
$RC_IPTABLES="/etc/rc.d/init.d/iptables restart > /dev/null";
$FETCHIPAC="/usr/local/sbin/fetchipac -S";
my(@exec);
open AAA,"<$LIMIT_FILE";
@lista=<AAA>;
$size=@lista;
close AAA;
$| = 1;
system ($IPACSUM);
open AAA,"<$TMP_LIMIT";
@tmplist=<AAA>;
#Remove special strings
shift(@tmplist); shift(@tmplist); shift(@tmplist);
$sizelimit=@tmplist;
close AAA;
unlink ($TMP_LIMIT);
#Remove space
for ($i=0;$i<$sizelimit;$i++) {
$tmplist[$i] =~ s/\x20//g;
}
#Reset local iptables rules
system ($RC_IPTABLES);
#Main loop
for ($i=0;$i<$size;$i++) {
if ( not $lista[$i]=~ /^\#/ ) {
@record=split(/\x09/,$lista[$i]);
$traffic = get_traffic($record[0]);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
if ($wday == 0) { $wday = 7; }
if ((($traffic > $record[$wday+1] ) && ($record[$wday+1] != 0)) || ($record[$wday+1] == -1)) {
print "Close ",$record[1]," ",$record[0],"\n";
update_iptables($record[1]);
system ($FETCHIPAC);
}
}
sub get_traffic {
my(@recordt,$j,$name);
$name = $_[0];
for ($j=0;$j<$sizelimit;$j++) {
if ( $tmplist[$j]=~ /^$name/) {
@recordt=split(/\:/,$tmplist[$j]);
$recordt[1] =~ s/\K//;
return $recordt[1];
}
}
}
sub update_iptables {
my(@iptmp,$sizeipt,$k);
open AAA,"<$IPTABLES_TEMPLATE_FILE";
@iptmp=<AAA>;
$sizeipt=@iptmp;
close AAA;
for ($k=0;$k<$sizeipt;$k++) {
if ( not $iptmp[$k]=~ /^\#/ ) {
$iptmp[$k]=~ s/<ipaddress>/$_[0]/g;
system($iptmp[$k]);
}
}
}