[an error occurred while processing this directive]

Статистика сетевых соединений через 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
Ключи: iptables, linux, traffic, log / Лицензия: CC-BY
Раздел:    Корень / Администратору / Система / Syslog, ведение логов

[an error occurred while processing this directive]

[an error occurred while processing this directive]