Статистика сетевых соединений через syslog и iptables |
[исправить] |
Часто недовольные пользователи приходят и просят дать им распечатку логов доступа в интернет.
Отчасти это позволяет сделать squid, но только при прозрачном проксировании, да
и то логи только по http-протоколу.
На помощь приходит iptables и syslog.
Настраиваем в syslog.conf добавление сообщений от ядра уровня debug (или
уровня, который вам удобнее)
в отдельный файл. Лучше всего хранить эти логи на отдельном разделе (их размер огромен!
но проблему решает gzip - сжимает логи более чем в 10 раз).
В моём syslog.conf была добавлена строка:
kern.=debug -/var/log/access/access
Желательно, что бы в уровень debug сообщений от ядра не поступало никакой другой информации,
кроме информации от iptables. У меня так и получилось по умолчанию с уровнем debug.
В rc.firewall было добавлено в самое начало:
#LOG ALL (!!!). Beware!!!
#FORWARD
iptables -A FORWARD -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_FWD_NEW ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_RLTD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state INVALID -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_INVLD ' # --log-tcp-options --log-ip-options
#INPUT
iptables -A INPUT -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_NEW ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_RLTD ' # --log-tcp-options --log-ip-options
iptables -A INPUT -m state --state INVALID -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_INVLD ' # --log-tcp-options --log-ip-options
Если раскомментировать все строки, то получиться лог с полной статистикой
доступа - он будет очень большим.
Поэтому в данном примере имеем лог только по установкам соединений и ошибочным
соединениям в цепочках INPUT и FORWARD.
Итак. В logrotate я добавил (/etc/logrotate.d/access):
/var/log/access/access {
sharedscripts
compress
rotate 45
daily
postrotate
/bin/killall -HUP syslogd
endscript
}
Сжимаем логи каждый день. Храним статистику за последние 45 суток.
Компрессия логов в моём случае дала значительный прирост производительности, поскольку шлюз
достаточно мощный и скорость парсинга логов упиралась только в чтение с HDD.
В итоге был написан простой скрипт на perl, выдающий статистику в более-менее удобоваримой форме.
Вот и сам скрипт:
-------------------------
#!/usr/bin/perl
use CGI qw(:standard);
use PerlIO::gzip;
use Switch;
##Redefine before start:
my $LOG_DIR="/var/log/access/";
my $LOG_FILENAME="access";
##end
my $IP, $FLAG;
## Params delimeter in request: "-"
($IP, $FLAG) = split(/-/, $ARGV[0]);
## if undefine IP or file log FLAG-number or FLAG is empty - parser exit:
if(!defined($IP)||!defined($FLAG)||$FLAG==""){
print header; print start_html;
print "Valid parameters required!"; print end_html; exit(1);
}
print header;
print start_html("Stat for: $IP");
print "<h2>Stat for: $IP</h2><br/>", "\n<pre>";
switch($FLAG)
{
case "0"
{
open($FD, "<$LOG_DIR$LOG_FILENAME")
or die "Cannot open current (0) log-file!<br> File does not exist or access not permitted!<br>";
while(<$FD>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($FD);
}
else
{
open($GZIP, "<:gzip(lazy)", "$LOG_DIR$LOG_FILENAME.$FLAG.gz")
or die "Cannot open old (", $FLAG, ") log-file!<br> File does not exist or access not permitted!<br>";
while(<$GZIP>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($GZIP);
}
}
print "</pre>\n";
print "<br><br>Access stat parser by \"umask at yandex dot ru\"<br>";
print end_html;
-------------------------
Для работы скрипта необходимо установить модуль PerlIO-gzip. Найти ссылку на
модуль можно на cpan.org.
Доступ к статистике можно получить через браузер (скрипт рассчитан для работы как CGI):
hostname.ru/cgi-bin/parse.pl?192.168.1.1-0
Аргумент понимаеться так:
192.168.1.1 - искомая подстрока.
0 - норме лог файла. В данном случае текущий (в который пока ещё записываются сообщения syslog).
1 - вчерашний,
2 - позавчерашний,
3 - 3 дня назад.
.....
и т.д.
Для меня данное решение оказалось удобным.
|
|
|
29.11.2005
, Автор: umask
|
Раздел: Корень / Администратору / Система / Syslog, ведение логов |