Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2013-02-17 13:49:34

  Jacekalex - Podobno człowiek...;)

Jacekalex
Podobno człowiek...;)
Skąd: /dev/random
Zarejestrowany: 2008-01-07

[SOLVED][PERL] Kompilacja wyrażenia regularnego? Jak to poprawić?

Perl - wersje:
5.16.2 - dom - Gentoo.
5.14.2 - Robota - Debian.

Ten przykład prawidłowo parsuje kawałek logu Snorta (Rsyslog) i wczytuje do zmiennych.
Docelowo będzie wyglądał trochę inaczej (chodzi generalnie o zasadę):

Kod:

use strict;
use warnings;
my $log="2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974
";
    print "Oryginalny log:\n";
    print "$log\n";
    chomp $log;
if ($log=~/snort/){
if ($log=~/^(\d+\-\d+\-\d+)T(\d+\:\d+\:\d+)\.\d+\+\d+:\d+\s(\w*)\s(\w*)\[(\d+)?\]:\s\[\d+:\d+:\d+\](.*)\s\[Priority\:\s(\d)\]\s\{(\w*)\}\s(\d+\.\d+\.\d+\.\d+):\d+ -\> (\d+\.\d+\.\d+\.\d+):\d+/)
{    my $date=$1;
    my $time=$2;
    my $host=$3;
    my $program=$4;
    my $pid=$5;
    my $mesg=$6;
    my $priorytet=$7;
    my $type=$8;
    my $srcip=$9;
    my $dstip=$10;
        print "Wczytane zmienne:\n\n data = $date\n godzina = $time\n host = $host\n program = $program\n pid= $pid\n typ = $type\n priorytet = $priorytet\n srcip = $srcip\n dstip = $dstip\n";
        print "komunikat = $mesg";}
       
};

Kiedy natomiast próbuję wczytać go do zmiennej, czy skompilować, zaczyna się jesień średniowiecza.

Docelowo w skrypcie ma być kilkanaście takich regexów, a działanie ma przypominać taką konstrukcję:

Kod:

#!/usr/bin/perl
# perl-grep2.pl
my $pattern = shift @ARGV;
my $regex = eval { qr/$pattern/ };
die "Sprawdź swój wzorzec! $@" if $@;
while( <> )
{
print if m/$regex/;
}

oczywiście wyregexowane wyniki mają trafić do kilku różnych funkcji.

Dla porównania, przy takim kodzie:
ten sam regex potrafi wygenerować od 5 do 30 blędów.

Kod:

my $log="2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974";

my $regexlog ="(/^(d+\-d+\-d+)T(d+\:d+\:d+)\.d+\:d+\:d+s(w*)s(w*)\[(d+)?\]:s\[d+:d+:d+\](.*)(d+\.d+\.d+\.d+):d+ -\> (d+\.d+\.d+\.d+):d+/)";
print "teraz kompilacja\n";
my $regexqr = eval { qr/$regexlog/ };
die "Sprawdź swój wzorzec! $@" if $@;


my ( $date, $time, $host,  $program, $mesg, $source , $dest ) =~$regexlog , $log;
print "data= $date\nczas= $time\nserwer= $host\n program= $program\nwiadomość= $mesg\nsrcip= $source\ndstip= $dest";

Docelowo to będzie demon zbierający logi ze snorta, ssh, ftp, www i php, mysqla, serwera smtp, dovecota, itp, i podejmujący rozmaite akcje, od ipseta aż po wysyłanie powiadomień przez jabbera, gadu czy maila.
Bazuje na skrypcie Guardian do Snorta.

Ja już kilka dni z tym walczę, jak na razie bezskutecznie.. :(
Wszelkie sugestie mile widziane.

Pozdrawiam
;-)

Ostatnio edytowany przez Jacekalex (2013-02-21 16:08:00)


W demokracji każdy naród ma taką władzę, na jaką zasługuje ;)
Si vis pacem  para bellum  ;)       |       Pozdrawiam :)

Offline

 

#2  2013-02-17 20:21:16

  HAL9000 - Użytkownik

HAL9000
Użytkownik
Zarejestrowany: 2006-04-22

Re: [SOLVED][PERL] Kompilacja wyrażenia regularnego? Jak to poprawić?

http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators
rzuc okiem na to, google tam mnie odeslalo gdy zapytalem


For some reason I'm thinking I'm still 25 but I act like I'm 12.

Offline

 

#3  2013-02-21 14:41:03

  Jacekalex - Podobno człowiek...;)

Jacekalex
Podobno człowiek...;)
Skąd: /dev/random
Zarejestrowany: 2008-01-07

Re: [SOLVED][PERL] Kompilacja wyrażenia regularnego? Jak to poprawić?

Google Cię odesłało?

To poszukaj w twoim google, dlaczego ten regex działa w takim zapisie, ale nie da się go zapisać do zmiennej i użyć w wersji skompilowanej, jakeś taki mądrala.

Po prostu pojęcia nie mam, dlaczego na żywca chodzi, a w zmiennej nie chodzi.
Zgodnie z twoim sznurkiem powinno działać bez problemu w obu wersjach, ale nie działa.

Prosty przykład użycia regexa bez wczytania do zmiennej i kompilowania:

Kod:

#!/usr/bin/perl
use strict;
use warnings;


my $log="2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974
";

    print "Oryginalny log:\n";
    print "$log\n";
    chomp $log;
if ($log=~/snort/){
if ($log=~/^(\d+\-\d+\-\d+)T(\d+\:\d+\:\d+)\.\d+\+\d+:\d+\s(\w*)\s(\w*)\[(\d+)?\]:\s\[\d+:\d+:\d+\](.*)\s\[Priority\:\s(\d)\]\s\{(\w*)\}\s(\d+\.\d+\.\d+\.\d+):\d+ -\> (\d+\.\d+\.\d+\.\d+):\d+/o)
{    my $date=$1;
    my $time=$2;
    my $host=$3;
    my $program=$4;
    my $pid=$5;
    my $mesg=$6;
    my $priorytet=$7;
    my $type=$8;
    my $srcip=$9;
    my $dstip=$10;
        print "Wczytane zmienne:\n\n data = $date\n godzina = $time\n host = $host\n program = $program\n pid= $pid\n typ = $type\n priorytet = $priorytet\n srcip = $srcip\n dstip = $dstip\n";
        print " komunikat =  \"$mesg\"";}
       

};

Wynik:

Kod:

./perlsyslog.pl 
Oryginalny log:
2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974

Wczytane zmienne:

 data = 2013-02-16
 godzina = 11:11:07
 host = localhost
 program = snort
 pid= 9499
 typ = TCP
 priorytet = 2
 srcip = 78.57.254.33
 dstip = 178.215.202.49
 komunikat =  " Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic]"

Przy próbie wczytania do zmiennej i skompilowania wyrażenia, kod:

Kod:

#!/usr/bin/perl
use strict;
use warnings;


my $log="2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974";

    print "Oryginalny log:\n";
    print "$log\n";
#    print "teraz zmienne\n";
    chomp $log;

print "Teraz próba wczytania  regexa do zmiennej:\n\n";

my $snortregex="^(\d+\-\d+\-\d+)T(\d+\:\d+\:\d+)\.\d+\+\d+:\d+\s(\w*)\s(\w*)\[(\d+)?\]:\s\[\d+:\d+:\d+\](.*)\s\[Priority\:\s(\d)\]\s\{(\w*)\}\s(\d+\.\d+\.\d+\.\d+):\d+ -\> (\d+\.\d+\.\d+\.\d+):\d+";

print "teraz kompilacja\n\n";
my $regex = eval { qr/$snortregex/ };
die "Sprawdź swój wzorzec!\n $@" if $@;
print "podobno już skompilowany...\n\n";

if ($log=~/snort/){
if ($log=~m/$regex/ )
{    my $date=$1;
    my $time=$2;
    my $host=$3;
    my $program=$4;
    my $pid=$5;
    my $mesg=$6;
    my $priorytet=$7;
    my $type=$8;
    my $srcip=$9;
    my $dstip=$10;
        print "Wczytane zmienne:\n\n data = $date\n godzina = $time\n host = $host\n program = $program\n pid= $pid\n typ = $type\n priorytet = $priorytet\n srcip = $srcip\n dstip = $dstip\n";
        print " komunikat =  \"$mesg\"";}

}

i rezultat:

Kod:

./snortrgex.pl 
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \w passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \w passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \w passed through at ./snortrgex.pl line 15.
Unrecognized escape \s passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Unrecognized escape \d passed through at ./snortrgex.pl line 15.
Oryginalny log:
2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974
Teraz próba wczytania  regexa do zmiennej:

teraz kompilacja regexa:

podobno już skompilowany...

We wszystkich poradnikach, jakie w życiu widziałem, np w tych przykładach:
http://pl.wikibooks.org/wiki/Perl/Opis_wyra%C5%BCe%C5%84_regularnych
Wszystko powinno śmigać tak czy siak, a tymczasem błędy dotyczą zapisu, który w setkach dokumentów jest opisany jako prawidłowy:

Kod:

Unrecognized escape \d passed through at

I z resztą działa, bez kompilowania regexa,  ale mnie do parsowania logów w pętli while średnio się uśmiecha kompilacja regexa przy każdym przebiegu pętli, czyli nawet kilkadziesiąt razy na sekundę.

Ciekawe, co twoje Google wie na ten temat....  ;P

EDYTA:
Diabli wiedzą dlaczego, ale żeby wczytać do zmiennej, trzeba stosować podwójne backslashe.
Przy takim zapisie:

Kod:

my $snortregex="^(\\d+\-\\d+\-\\d+)T(\\d+\:\\d+\:\\d+)\.\\d+\.\\d+:\\d+\\s(\\w*)\\s(\\w*).(\\d+).\:\\s.\\d+:\\d+.\\d+.(.*)\\s.Priority\:\\s(\\d).\\s.(\\w*).\\s(\\d+\.\\d+\.\\d+\.\\d+):\\d+ -\> (\\d+\.\\d+\.\\d+\.\\d+):\\d+";

ruszyło bez problemu...

Ciekawe, dlaczego inaczej się zapisuje regex do bezpośredniego zastosowania,
a inaczej do zmiennej.
To niestety nie jest jedyna różnica.... ;P

Pozdrawiam
;-)

Ostatnio edytowany przez Jacekalex (2013-02-21 16:00:37)


W demokracji każdy naród ma taką władzę, na jaką zasługuje ;)
Si vis pacem  para bellum  ;)       |       Pozdrawiam :)

Offline

 

#4  2013-02-21 15:47:26

  SmallCutePenguin - Nowy użytkownik

SmallCutePenguin
Nowy użytkownik
Zarejestrowany: 2013-02-21

Re: [SOLVED][PERL] Kompilacja wyrażenia regularnego? Jak to poprawić?

Poprawiony kod

Kod:

#!/usr/bin/perl
use strict;
use warnings;


my $log="2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974";

    print "Oryginalny log:\n";
    print "$log\n";
#    print "teraz zmienne\n";
    chomp $log;

print "Teraz próba wczytania  regexa do zmiennej:\n\n";

my $snortregex="^(\\d+\\-\\d+\\-\\d+)T(\\d+\\:\\d+\\:\\d+)\\.\\d+\\+\\d+:\\d+\\s(\\w*)\\s(\\w*)\\[(\\d+)?\\]:\\s\\[\\d+:\\d+:\\d+\\](.*)\\s\\[Priority\\:\\s(\\d)\\]\\s\\{(\\w*)\\}\\s(\\d+\\.\\d+\\.\\d+\\.\\d+):\\d+ -\\> (\\d+\\.\\d+\\.\\d+\\.\\d+):\\d+";

print "teraz kompilacja\n\n";
my $regex = eval { qr/$snortregex/ };
die "Sprawdź swój wzorzec!\n $@" if $@;
print "podobno już skompilowany...\n\n";

if ($log=~/snort/){
if ($log=~m/$regex/ )
{    my $date=$1;
    my $time=$2;
    my $host=$3;
    my $program=$4;
    my $pid=$5;
    my $mesg=$6;
    my $priorytet=$7;
    my $type=$8;
    my $srcip=$9;
    my $dstip=$10;
        print "Wczytane zmienne:\n\n data = $date\n godzina = $time\n host = $host\n program = $program\n pid= $pid\n typ = $type\n priorytet = $priorytet\n srcip = $srcip\n dstip = $dstip\n";
        print " komunikat =  \"$mesg\"";}

}

I wynik

Kod:

Oryginalny log:
2013-02-16T11:11:07.903242+01:00 localhost snort[9499]: [129:12:1] Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 78.57.254.33:53139 -> 178.215.202.49:50974
Teraz próba wczytania  regexa do zmiennej:

teraz kompilacja

podobno już skompilowany...

Wczytane zmienne:

 data = 2013-02-16
 godzina = 11:11:07
 host = localhost
 program = snort
 pid= 9499
 typ = TCP
 priorytet = 2
 srcip = 78.57.254.33
 dstip = 178.215.202.49
 komunikat =  " Consecutive TCP small segments exceeding threshold [Classification: Potentially Bad Traffic]"

Zapomniałeś, że w przypadku stringów znaki poprzedzone \ mają specjalne znaczenie.

Ostatnio edytowany przez SmallCutePenguin (2013-02-21 15:55:06)

Offline

 

#5  2013-02-21 16:05:38

  Jacekalex - Podobno człowiek...;)

Jacekalex
Podobno człowiek...;)
Skąd: /dev/random
Zarejestrowany: 2008-01-07

Re: [SOLVED][PERL] Kompilacja wyrażenia regularnego? Jak to poprawić?

Dzięki, równolegle sam do tego się dokopałem dosłownie przed chwilą.
Szkoda że nie trafiłeś na ten wątek wcześniej . ;)
Mnie po prostu zbiła z tropu sytuacja, kiedy działa  regex, ale nie da się go wpakować do zmiennej.
We wszystkich poradnikach i podręcznikach, jakie widziałem, zapis był niby  poprawny, a że na codzień nie programuję, to miałem mocno zdziwioną minę.. ;)

Ostatnio edytowany przez Jacekalex (2013-02-21 16:08:51)


W demokracji każdy naród ma taką władzę, na jaką zasługuje ;)
Si vis pacem  para bellum  ;)       |       Pozdrawiam :)

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
To nie jest tylko forum, to nasza mała ojczyzna ;-)