Ipcounter - Faire des graphs MRTG par protocole / HTTP, FTP

But

Comment avoir une idée du trafic sur une machine par protocole ? La réponse est simple :

Graph

Oui, je sais ! Je devrais arrêté de penser à des petites bulles avec des flèches la nuit. Bref encore un truc cool à faire en Perl. Au passage MRTG est ecrit en PERL.

Détails techniques

Environnement

  • Un server sous linux,
  • iptables,
  • pure-ftpd configuré avec :
$cat /etc/pure-ftpd/conf/PassivePortRange
64000 64500

Principes techniques

  • On crée des tables iptables justes pour compter le trafic et rien d’autres.

iptables

Creation des tables
iptables -N COUNTER_IN
iptables -I INPUT -i eth0 -j COUNTER_IN
iptables -A COUNTER_IN -p tcp --dport 80 -j RETURN
iptables -A COUNTER_IN -p tcp --dport 8022 -j RETURN
iptables -A COUNTER_IN -p tcp --dport 443 -j RETURN
iptables -A COUNTER_IN -p tcp --dport imap2 -j RETURN
iptables -A COUNTER_IN -p tcp --dport imaps -j RETURN
iptables -A COUNTER_IN -p tcp --dport smtp -j RETURN
iptables -A COUNTER_IN -p tcp --dport 64000:64500 -j RETURN
iptables -A COUNTER_IN -p tcp --dport 21 -j RETURN
iptables -A COUNTER_IN -p tcp --dport 20 -j RETURN
iptables -N COUNTER_OUT
iptables -I OUTPUT -o eth0 -j COUNTER_OUT
iptables -A COUNTER_OUT -p tcp --dport 25 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 20 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 80 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 443 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 8022 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 64000:64500 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport imap2 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport imaps -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 21 -j RETURN

DB_File

Pour éviter de solliciter en permanence les modules iptables (c’est un peu dans le noyau quand même) on va utiliser un table de hash liée (tie) à un fichier. Dès que le données sont périmées ont les rafraîchies avec les compteurs iptables.

Mrtg

Un exemple de config mrtg :

Title[myhost.smtp]: SMTP Traffic -- Myhost
PageTop[myhost.smtp]: <H1>SMTP Traffic -- Myhost</H1>
Target[myhost.smtp]: `/my/bin/path/ipprotocounter.pl smtp`
MaxBytes[myhost.smtp]: 12500000
Options[myhost.smtp]: absolute, nopercent
YLegend[myhost.smtp]: SMTP Traffic
ShortLegend[myhost.smtp]: B/s
Legend1[myhost.smtp]: SMTP IN
Legend2[myhost.smtp]: SMTP OUT
Legend3[myhost.smtp]: Maximal 5 Minutes SMTP IN
Legend4[myhost.smtp]:  Maximal 5 Minutes SMTP OUT
LegendI[myhost.smtp]: &nbsp;SMTP IN:
LegendO[myhost.smtp]: &nbsp;SMTP OUT:

Maintenance

Pour rajouter un protocole (ex pour protochelou), il faut :

  • ajouter ce qu’il faut dans les tables ‘COUNTER_IN’ et ‘COUNTER_OUT’ :
iptables -A COUNTER_IN -p tcp --dport 50239 -j RETURN
iptables -A COUNTER_OUT -p tcp --sport 50234 -j RETURN
  • modifier la table de hash de config dans le script :
http => [qw(in80 out80)],
protochelou => [qw(in50239 out50234)],

Note 1 : pour inverser les courbes (toujours dans le sens histogramme courbe) il suffit d’inverser in50239 out50234

protochelou => [qw(out50234 in50239)],

Note 2 : On peut aussi faire des operations basic (addition soustraction)

protochelou => [qw(out50234-in50239 in50239+out50234)],
  • modifier la conf mrtg.

Exemple

Voici un exemple de graph MRTG que l’on peut obtenir avec cette methode :

Download

Rien

Code

Le script

#!/usr/bin/perl -w
 
use strict;
use DB_File;
my $data = {};
my $h = {
	 refresh_db => '300', #time in seconds
	 db_file => '/tmp/ipcounter.db',
	 ipt_cmd => {
		     in => '/sbin/iptables -vxnL COUNTER_IN -Z|',
		     out => '/sbin/iptables -vxnL COUNTER_OUT -Z|',
#		     in => 'iptables_counter_in.txt',
#		     out => 'iptables_counter_out.txt',
		    },
	 proto => {
		   smtp => [qw(in25 out25)],
		   ssh => [qw(in8022 out8022)],
		   ftp_active => [qw(in20+in21 out21+out20)],
		   ftp_passive => [qw(in64000:64500 out64000:64500)],
		   http => [qw(in80 out80)],
		   https => [qw(in443 out443)],
		   imap => [qw(in143 out143)],
		   imaps => [qw(in993 out993)],
		  }
	};
 
sub update_db {
  for my $k (keys %{$h->{ipt_cmd}}) {
    open CMD, $h->{ipt_cmd}->{$k} or die "$!";
    while (<CMD>) {
      chomp;
      next if /^$/;
      next if /^Chain\s/;
      if (/^\s*\d+\s*(\d+).*[sd]pts?:([:0-9]+)/) {
	$data->{"$k$2"} = $1;
      }
    }
    close CMD;
  }
}
 
## Must use this /sbin/iptables -vxnL COUNTER_IN
tie %{$data},  'DB_File', $h->{db_file};
my $time = time;
if (not defined $data->{time} or ($data->{time} + $h->{refresh_db}) <= $time) {
#  print "Db update\n";
  $data->{time} = $time;
  &update_db();
}
 
#print scalar localtime($data->{time}), "\n";
for my $proto (@ARGV) {
  die "Unknown Protocol : $proto\n" unless defined ($h->{proto}->{lc($proto)});
  my $res = [];
  for my $d (@{$h->{proto}->{lc($proto)}}) {
#   print "key: $d\n";
    if ($d =~ /^(.*)(-|\+)(.*)$/) {
      my $e = 0;
#      print "$d\n";
#      print "$1 $2 $3\n";
      my $a = defined $data->{$1} ? $data->{$1} : 0;
      my $b = defined $data->{$3} ? $data->{$3} : 0;
      my $stm = "\$e = $a $2 $b;";
#      print $stm, "\n";
      eval $stm;
      warn $@ if $@;
#      print "res = $e\n";
      push @$res, $e;
      next;
    }
    push @$res, (defined $data->{$d} ? $data->{$d} : 0);
  }
  print join("\n", @$res), "\n";
}
 
tech/ipcounter.txt · Dernière modification: 2007/02/12 09:26 par danjer
 
Recent changes RSS feed Valid XHTML 1.0 Valid CSS Driven by DokuWiki Powered by Lescampeurs