rdrcollector/cgi/loginsearch

289 lines
12 KiB
Perl
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/perl
#########################################################################
#
# CGI скрипт для поиска и визуализации данных собранных rdrcollector-ом
# по логину абонента
#
# Автор: Сергей Калинин e-mail: banzaj28@yandex.ru
# распространяется под лицензией GPL
# (c) 2015
#########################################################################
use CGI ':standard';
use DBI;
use Time::Local;
# Вывод заголовка
print header(-type=>'text/html', -charset=>'utf-8');
print start_html("Поиск сессий абонента по имени пользователя");
print "<table width=100%><tr><td width=10%><img src=/logo.gif></td><td width=90% align=center><h2>Поиск сессий абонента по имени пользователя</h2></td></tr></table>\n";
print "<hr>\n";
print_prompt();
do_work();
print_tail();
read_protocol();
print end_html;
#########################################################################
# описание процедур
#########################################################################
# вывод формы с полями
sub print_prompt {
print start_form;
print "<p><table><tr><td><em>Дата (ДД.ММ.ГГГГ)</em></td>";
print "<td>".textfield('date')."</td></tr>";
print "<tr><td><em>Имя пользователя</em></td>";
print "<td>".textfield('login')."</td>";
print "</tr></table>";
#print "<td><ifarme name=userdata width=468 height=60 align=left>sss</iframe></td></tr></table>";
# print "<p>",reset;
print submit('Action','Выполнить');
print end_form;
print "</p><hr>\n";
}
# проверка корректности даты
sub match_date {
my $input = shift;
if ($input =~ m!^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$!) {
# At this point, $1 holds the year, $2 the month and $3 the day of the date entered
if ($3 == 31 and ($2 == 4 or $2 == 6 or $2 == 9 or $2 == 11)) {
return 0; # 31st of a month with 30 days
} elsif ($3 >= 30 and $2 == 2) {
return 0; # February 30th or 31st
} elsif ($2 == 2 and $3 == 29 and not ($1 % 4 == 0 and ($1 % 100 != 0 or $1 % 400 == 0))) {
return 0; # February 29th outside a leap year
} else {
return $input; # Valid date
}
} else {
return 0; # Not a date
}
}
sub do_work {
my $key;
my $cmd;
# получаем данные введённые в форме
# и проверяем формат
my $date = match_date(param(date));
my $login = param(login);
my $contract = param(contr);
# если данные введены не верно выводим сообщение
chomp $login;
if ($login eq "")
{
print "<font color=red size=5>Введите имя пользователя</font>";
exit;
}
if ($date eq "" || $date == 0)
{
print "<font color=red size=5>Необходимо корректно ввести дату</font>";
exit;
}
login_search($date, $login, $contract)
}
sub ip_search {
my $key;
my $cmd;
# получаем данные введённые в форме
# и проверяем формат
my $date = $_[0];
my ($date_start, $t_start) = split (" ", $_[1]);
my ($date_stop, $t_stop) = split (" ", $_[2]);
my $src = $_[3];
my $dst;
# Преобразуем дату и время в unixtime
# начало сессии
my ($hour, $min, $sec) = split(':',$t_start);
my ($year, $month, $day) = split('-',$date_start);
my $time_start = timelocal($sec,$min,$hour,$day,$month,$year)."\n";
# конец сессии
($hour, $min, $sec) = split(':',$t_stop);
($year, $month, $day) = split('-',$date_stop);
my $time_stop = timelocal($sec,$min,$hour,$day,$month,$year)."\n";
# если данные введены не верно выводим сообщение
if ($dst eq 0 || $src eq 0)
{
print "<font color=red size=5>Введите корректный IP адрес</font>";
exit;
}
# формируем каталог для поиска в соответствии с датой
my ($dday,$dmonth,$dyear) = split(/\./,$date);
my $dir = "/var/srv/rdrcollector/$dyear/$dmonth/$dday";
# формируем команду поиска данных в зависимости от даты и IP адресов (1 или 2 адреса)
# определяем каталог в архиве и если он есть ищем данные в файлах этого каталога
# если такого каталога нет - поиск производится в кэше.
if (-d $dir)
{
if ($dst eq "") {
$cmd = "/usr/bin/gzip -c -d ".$dir."/*.gz | /usr/bin/grep -h ".$src."@";
} else {
$cmd = "/usr/bin/gzip -c -d ".$dir."/*.gz | /usr/bin/grep -h ".$src."@ | /bin/grep ".$dst;
}
} else {
print "Данные за $date в архиве не найдены производится поиск за последние сутки<br>";
if ($dst eq "") {
$cmd = "/usr/bin/grep -h ".$src."@ /var/cache/rdrcollector/*";
} else {
$cmd = "/usr/bin/grep -h ".$src."@ /var/cache/rdrcollector/* | /usr/bin/grep ".$dst;
}
}
# выполняем команду поиска и выводим данные ввиде html-таблицы
#print "<h4>Список TCP/IP сессий c адреса ".$src." за ".$date."</h4>";
# заголовок таблицы
print "<table width=100%><tr bgcolor=#78ceff><td align=center>Дата</td><td align=center>Абонент</td><td align=center>IP клиента</td><td align=center>IP сервера</td><td align=center>Трафик вх/исх</td><td>Протокол</td><td align=center>Информация</td></tr>";
my $i = 0;
my $bgcolor;
my $session_up;
my $session_down;
# команда выполняется и результат обрабатывается циклом
foreach my $lines (`$cmd`) {
my $expr = $i % 2;
# чередование цвета фона строк для чётных и не чётных
if ($expr eq 0) {
$bgcolor = "#fffff";
} else {
$bgcolor = "#c5eaff";
}
# разбиваем строку на поля для удобства вывода.
my ($date_time, $client, $client_ip, $server_ip, $up_down, $protocol_sign) = split(/\t/, $lines);
# определяем IP абонента
my ($user_ip, $group) = split("@", $client);
# проверка на пустое поле даты или идетнификатора абонента
# бывают покоцанные файлы
if ($date_time eq "" || $client eq "")
{
next;
}
# преобразуем дату время найденного соединения в unixtime
my ($t, $date) = split(" ", $date_time);
($day, $month, $year) = split(/\./,$date);
($hour, $min, $sec) = split(':',$t);
#print "$date_time - $hour $min $sec $day $month $year <br>";
my $time = timelocal($sec, $min, $hour, $day, $month, $year);
# сравниваем дату и время TCP/IP сессии с датой и временем сессии абонента в биллинге
# и если она входит в диапазон, выводим на экран
if ($time > $time_start && $time < $time_stop) {
# отбрасываем записи о "пустых" соединениях
# if ($client_ip ne ":" || $server_ip ne ":") {
# считаем трафик
my ($up, $down) = split("/", $up_down);
$session_up += $up;
$session_down += $down;
# определяем название протокола по его подписи
$protocol = read_protocol("$protocol_sign");
# вводим данные
print "<tr bgcolor=$bgcolor><td width=10%><font size=2>$date_time</td>";
print "<td width=20%><font size=2><a href=/cgi-bin/usersearch?ip=".$user_ip."&day=".$day."&month=".$month."&year=".$year."&t=".$t." target=userdata>$client</td>";
print "<td width=10%><font size=2>$client_ip</td><td width=10%><font size=2>$server_ip</td><td width=10%><font size=2>$up_down</td><td width=20%><font size=2>$protocol</td><td><font size=2>$info_string</td></tr>\n";
$i++;
# }
}
# exit;
}
print "<tr bgcolor=#78ceff><td><font size=2><b>Всего трафика</b></font></td><td></td><td></td><td></td><td width=10%><font size=2><b>$session_up / $session_down</b></td><td width=20%><font size=2></td><td><font size=2></td></tr>\n";
print "</table>";
}
sub print_tail {
print "<hr><div align=center> &copy 2015, OOO \"Терион\"</div>";
}
# читаем файл с описанием протокола
sub read_protocol {
#print $_[0];
$cmd = "/usr/bin/grep -h \'".$_[0]."\' /usr/local/etc/protocol.csv";
my $lines = `$cmd`;
#print "$lines";
if ($lines) {
my ($prot, $signature) = split(";", $lines);
return $prot;
} else {
return $_[0];
}
}
# поиск данных в БД биллинга
sub login_search {
my $login = param(login);
my $date = param(date);
my $contract = param(contr);
if ($contract ne "")
{
print "<p>Договор - <b>$contract</b></p>\n";
}
my ($day,$month,$year) = split(/\./, $date);
# определяем имя таблицы с сессиями
my $table = "inet_session_log_1_".$year."".$month;
# конектимся к GLPI базе.
my $dsn = 'DBI:mysql:bgbilling:192.168.1.250';
my $db_user_name = 'netflow';
my $db_password = 'Cbcntvfnbpfwbz112318';
my ($id, $password);
my $dbh = DBI->connect($dsn, $db_user_name, $db_password);
# форматируем дату для запроса
my $date_begin = $year."-".$month."-".$day." 00:00:00";
my $date_end = $year."-".$month."-".$day." 23:59:59";
# формируем SQL запрс
my $sth = $dbh->prepare(qq{select c.title, serv.login, INET_NTOA(CONV(HEX( session.ipAddress ), 16, 10)) as ip, session.sessionStart, session.sessionStop from
inet_serv_1 serv
left join $table session on serv.id = session.servid
left join contract c on c.id = serv.contractid
LEFT outer JOIN inet_serv_1 as parentServ ON serv.parentId>0 AND serv.parentId=parentServ.id
where serv.contractid <> '2' and serv.login = '$login' AND session.parentId=0
and session.sessionStart >= '$date_begin' AND session.sessionStart <= '$date_end'});
# Выполняем запрос к БД
$sth->execute();
# если в предыдущем запорсе ничего не найден обращаемся к таблице с активными сессиями
if ($sth->rows == 0)
{
$sth = $dbh->prepare(qq{select c.title, i_c_1.username, INET_NTOA(CONV(HEX( i_c_1.ipAddress ), 16, 10)) as ip , session.sessionstart, session.sessionstop
from inet_connection_1 i_c_1
join inet_session_1 session on session.connectionid = i_c_1.id
join inet_serv_1 i_s_1 on i_s_1.id = i_c_1.servid
join contract c on c.id = i_s_1.contractid
where i_c_1.parentid = 0 and i_c_1.username = '$login' and session.sessionStart >= '$date_begin'});
$sth->execute();
}
print "<p>Найдено записей - ".$sth->rows."</p>";
# получаем данные запроса форматируем и выводим на экран
while (($title, $login, $ip, $start, $stop) = $sth->fetchrow_array())
{
if ($stop eq "")
{
$stop = $date_end;
}
#print "Договор - <b><i>$title</i></b><br>Имя пользователя - <b><i>$login</i></b><br>IP - <b><i>$ip</i></b><br>Cессиия - <b><i>$start - $stop</i></b><br>";
print "<p>IP - <b><i>$ip</i></b><br>Cессиия - <b><i>$start - $stop</i></b></p>";
# запускаем процедуру поиска сессий в файла RDR коллектора
ip_search($date, $start, $stop, $ip);
}
$sth->finish();
# Отцепляемся от БД
$dbh->disconnect();
}