[Linux-bruxelles] Contrôle de volume internet mensuel, par ordinateur, dans un petit WLAN.
Jean-Charles de Longueville
jean-charles at de-longueville.eu
Sam 28 Nov 00:14:58 CET 2009
Nicolas Jungers a écrit :
> On 22/11/09 21:08, Xavier Jacques wrote:
>
>> Bonjour,
>>
>> Je fournis internet dans une maison d'étudiants.
>> Nous partageons une ligne ADSL2+ via un routeur et un AP Cisco qui
>> dialoguent avec les ordis filtrés par MAC address.
>>
>> Selon les conditions générales, mes cokoteurs et cokoteuses
>> "s'engagent à utiliser honnêtement un compteur de trafic internet".
>> Le hic, c'est qu'il n'y en a qu'un seul qui est honnête.
>> Les autres préfèrent quitter leur compteur pour télécharger à gogo.
>>
>> Marc Arnoldy eut la gentillesse d'entamer une recherche à ce sujet dès
>> cet après-midi, chez FIJ.
>> Mais il m'a aussi et surtout conseillé de poster sur la liste !
>>
>> Quelqu'un parmi vous a-t-il déjà pu résoudre ce problème ?
>> Via le routeur ou via un serveur ?
>>
>
> La solution simple passe par iptables. Je l'ai fait il y a une dizaine
> d'année. Si tu contrôles le routeur c'est assez facile. Tu assignes un
> compteur par IP source. Tu relèves les compteurs régulièrement pour ne
> pas perdre les informations lors d'un reboot consécutifs à une "panne"
> de courant. Tu verrouilles bien les IP sur les adresses MAC et tu ne
> laisses pas passer d'autres IP. Maintenant, à l'époque j'ai fait ça "à
> la main" et je ne saurais plus le faire, mais de nos jours il doit y
> avoir de jolies interfaces graphiques à disposition.
je viens de mette en place la solution suggérée par Nicolas:
1/ préparer le routeur à surveiller
2/ préparer la DB qui va recueillir les mesures
3/ scripter la lecture des compteurs et leurs reports vers la DB
4/ lancer le script par cron
5/ enjoy!
1/ préparer le routeur à surveiller sur base de
http://rtg.sourceforge.net/ et y ajouter
for i in 193 194 195
do
iptables -t mangle -A PREROUTING -s 89.106.241.$i/32 -i eth0 -m mark ! --mark $i
iptables -t mangle -A POSTROUTING -o eth0 -d 89.106.241.$i/32 -m mark ! --mark $i
done
2/ préparer la DB qui va recueillir les mesures
on ajoute a RTG un routeur "dummy" de numéro (rid) 2; définit ayant une
vitesse de 100Mbps.
Chaque IP à surveiller sera un interface du dummy au sens de RTG.
#!/usr/bin/perl
use DBI;
use DBD::mysql;
use Socket;
$database = "rtg";
$hostname = "mykel.hellea.net";
$login = "user";
$mdp = "******";
$debug = 0;
$dsn = "DBI:mysql:database=$database;host=$hostname";
$dbh = DBI->connect($dsn, $login, $mdp) or die "Echec connexion";
if ($debug) {print "Connexion à la DB $dsn \n";}
$rid = '2';
$speed = '100000000';
for ($i = 196; $i < 255; $i++) {
$adrr = sprintf("89.106.241.%d",$i);
$iadr = inet_aton($adrr);
$name = gethostbyaddr($iadr, AF_INET);
@nums = split('[.]',$adrr);
$num = $nums[3];
if ($debug) {print "VALUES ( $num, $name, $rid, $speed, $adrr, 'active' );\n";}
$requete="INSERT INTO interface ( id , name , rid , speed , description , status ) VALUES ( $num, '$name', $rid, $speed, '$a
drr', 'active' ); ";
$sth = $dbh->prepare($requete);
$sth->execute();
$sth -> finish;
}
$dbh -> disconnect;
if ($debug) {print "Déconnexion de la DB OK\n";}
3/ scripter la lecture des compteurs et leurs reports vers la DB
#!/usr/bin/perl
### /usr/local/sbin/ipcounts.perl
use DBI;
use DBD::mysql;
$database = "rtg";
$hostname = "mykel.hellea.net";
$login = "user";
$mdp = "******";
$debug = 0;
$dsn = "DBI:mysql:database=$database;host=$hostname";
$dbh = DBI->connect($dsn, $login, $mdp) or die "Echec connexion";
if ($debug) {print "Connexion à la DB $dsn \n";}
while (<>) {
@items = split(/:/);
if ($items[0] == ""){
if ($debug) {print "aborted : no pkts [@items]\n";}
next;
}
$pkts = $items[0];
$bytes = $items[1];
$src = $items[2];
$dst = $items[3];
$flow = "error";
if (($dst == "0.0.0.0/0")) {
$flow = 1;
$adrr = $src;
}
if (($src == "0.0.0.0/0")){
$flow = 0;
$adrr = $dst;
}
@nums = split(/[.]/,$adrr);
$num = $nums[3];
if ($num == "0/0") {
if ($debug) {print "aborted : because num is $num [$flow - $adrr]\n";}
next;
}
if ($flow) {
$requete="INSERT INTO ifInUcastPkts_2 ( id , dtime , counter ) VALUES ( $num, NOW(), $pkts );";
$sth = $dbh->prepare($requete);
$sth->execute();
$sth -> finish;
$requete="INSERT INTO ifInOctets_2 ( id , dtime , counter ) VALUES ( $num, NOW(), $bytes );";
$sth = $dbh->prepare($requete);
$sth->execute();
$sth -> finish;
if ($debug) {print "record for: $num, $flow, $adrr, $pkts, $bytes \n";}
next;
} else {
$requete="INSERT INTO ifOutUcastPkts_2 ( id , dtime , counter ) VALUES ( $num, NOW(), $pkts );";
$sth = $dbh->prepare($requete);
$sth->execute();
$sth -> finish;
$requete="INSERT INTO ifOutOctets_2 ( id , dtime , counter ) VALUES ( $num, NOW(), $bytes );";
$sth = $dbh->prepare($requete);
$sth->execute();
$sth -> finish;
if ($debug) {print "record for: $num, $flow, $adrr, $pkts, $bytes \n";}
next;
}
}
$dbh -> disconnect;
if ($debug) {print "Déconnexion de la DB OK\n";}
4/ lancer le script par cron
iptables -t mangle -vnxL | gawk '/MARK/ {print $1":"$2":"$7":"$8":"}' | /usr/bin/perl /usr/local/sbin/ipcounts.perl
5/ enjoy!
https://www.hellea.net/rtg/view.php?rid=2
Plus d'informations sur la liste de diffusion Linux-bruxelles