Comment avoir une idée du trafic sur une machine par protocole ? La réponse est simple :
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.
$cat /etc/pure-ftpd/conf/PassivePortRange 64000 64500
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
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.
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]: SMTP IN: LegendO[myhost.smtp]: SMTP OUT:
Pour rajouter un protocole (ex pour protochelou), il faut :
‘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
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)],
Rien
#!/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"; }