Появилась тут такая нестандартная задачка:
Есть роутер на linux 2.6, который NAT-ит и роутит клиентов.
Надо: вести статистику по dst 25 порту, но не просто что кто-то/куда-то/столько-то байтов(пакетов), а с разбором на 7-м уровне, т.е. хочется такую (ну условно/приблизительно, для наглядности) табличку на выходе:
дата-время|src ip|dst ip|sender email|detination emailесессно, первая идея поставить любой MTA,редеректить и разрешить соответствующий relay - но косяк в том, что после него письма будут отправляться от него самого, а нужно сохранить SMTP AUTH и прочее, т.е. чтобы почтовый клиент и его destination сервер не знали об этом звене.
подобным образом работают разнообразные клиентские антивирусы, они-же проверяют на лету отправляемую почту?
моих программерских способностей не хватает для написания такого с нуля, и гугл тоже ничего внятного не говорит....
идеи?
Понедельничный ап.
Ну вообщем придумал, корявенько, но в первом приближении работает.Парзить будем тулзой ngrep
Создаем mysql базу:
CREATE TABLE `log` (
`date` date default NULL,
`time` time default NULL,
`srcip` varchar(15) default NULL,
`dstip` varchar(15) default NULL,
`dstaddr` varchar(30) default NULL
);
Файл cat /opt/run_ngrep.sh
#!/bin/bashngrep -P "*" -l -q -t -d eth1 -i 'rcpt to|mail from' tcp dst port smtp >/opt/ngrep.out &
Файл cat /opt/ngrep2mysql.pl
#!/usr/bin/perl
use DBI;$database = 'ngrep';
$dbuser = 'root';
$dbpassword = '';`rm -f /opt/ngrep.tmp`;
#print 'ok rm \n';while (1) {
`killall ngrep`;
#print 'ok kill \n';
`mv -f /opt/ngrep.out /opt/ngrep.tmp`;
#print 'ok mv \n';
#`ngrep -l -q -t -d eth0 -i 'rcpt to|mail from' tcp port smtp > /opt/ngrep.out >/dev/null 2>&1 &`;
`/opt/run_ngrep.sh`;
#print $_, " --- \n";
my @data,$line;open(F,"/opt/ngrep.tmp");
while (<F>) {
chomp ($line = $_);
for ($line) {s/^\s+//;s/\s+$//;};
next if ($line eq '');
push(@data, $line)
};my @new_data;
$i=0;
foreach $str (@data){
if (substr($str, 0, 1) eq 'T'){
push (@new_data, $str . ' ' . @data[$i+1]);
};
$i++;
};#my (@data);
#$i=0;
#foreach $str (@new_data){
#$i++;
#if ($i <=2){
# push (@data, $str);
#}elsif ($i == 4){
# $i = 0
#};
#};$dbh = DBI->connect("DBI:mysql:${database}", $dbuser, $dbpassword)
or die $DBI::errstr;$i=0;
my $teststring, %test;
while (@new_data[$i]){
($tmp, $date, $time, $srcip, $tmp, $dstip, $tmp, $tmp, $type, $dstmail) = split(' ', @new_data[$i]);
#($tmp, $tmp, $tmp, $tmp, $tmp, $tmp, $tmp, $tmp, $tmp, $dstmail) = split(' ', @new_data[$i+1]);
if ($type eq 'TO:'){
$date =~ tr/\//-/;
$time = substr($time,0,8);
($srcip) = split(':',$srcip);
($dstip) = split(':',$dstip);
$dstmail =~ tr/(<|>)//d;
$dstmail =~ tr/*//d;
$new_teststring = "$date;$srcip;$dstip;$dstmail";
if ($test{$new_teststring} eq ''){$sql = "INSERT INTO `log` (`date`,`time`,`srcip`,`dstip`,`dstaddr`) VALUES (\'$date\',\'$time\',\'$srcip\',\'$dstip\',\'$dstmail\')";
my $sth = $dbh->prepare( $sql ) or die $DBI::errstr;
$sth->execute or die $DBI::errstr;#print "$date, $time, $srcip, $dstip, $dstmail \n";
$test{$new_teststring} = 1;
};
};
$i++;};
$rc = $dbh->disconnect;sleep 600;
};
exit(0);Запускаем всё это вот так: screen -d -m /opt/ngrep2mysql.pl
Всё сыро и криво, надо дорабатывать.