그래서 저는 https를 통해 우리 네트워크에서 포르노를 검색하는 사람들을 추적하려고 합니다. 15회 이상의 연속 이미지 클릭에 대해 Bro 로그의 HTTP 헤더에 참조 URL이 없으면 패턴을 쉽게 확인할 수 있습니다.
Bro의 관련 열은 $3 = 호스트 IP, $11 = 리퍼러, $14 = 파일 크기, $27 = MIME 유형입니다.
그래서 제가 현재 사용하고 있는...
awk -F "\t" '$11 ~ /^\-$/ && $14 > 100000 && $27 ~ /^image/'
내가 하고 싶은 것은 한 줄 명령으로 하위 명령을 계속 실행하면서 awk에게 $3의 IP가 15번 이상 나타나는 줄만 인쇄하도록 지시하는 방법이 있는지 아는 것입니다.
내 생각엔 비슷한 일을 하려면 awk 프로그램을 만들어야 할 것 같다. 이 문제를 피하는 데 도움을 줄 수 있는 전문가가 여기 있기를 바랍니다. 나는 다른 정규식 명령이 더 잘 작동한다면(perl, grep, egrep, agrep, bro-cut) 사용하는 것에 반대하지 않습니다.
업데이트: 이를 설명하는 가장 좋은 방법은 Excel 용어를 사용하는 것입니다. awk에는 countif Excel 함수와 유사한 기능이 있습니까? =개수(C1,C:C)>15
샘플 로그:
1443534069 CGAdXyZgN3wVwihi6 123.456.789.012 59713 93.184.216.98 80 1 GET 40.media.tumblr.com /1fbe50fff7a17f84acdc30b03d9b6335/tumblr_nvf1dfH8oz1tco00do1_500.jpg - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36 0 89522 200 OK - - - (empty) - - - - - FIGAv51OT15ak4eDCl image/jpeg
1443534069 CkST1DjXDkCBDYhYa 123.456.789.012 59712 93.184.216.98 80 1 GET 40.media.tumblr.com /e8f958e0dcd3eb419035a8d3271d07e8/tumblr_npr5drTCOO1qk489oo1_500.jpg - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36 0 83743 200 OK - - - (empty) - - - - - FWRWZX2XgQQqfm9OMe image/jpeg
1443534069 C8GvXwqAiR84PGGkk 123.456.789.012 59714 93.184.216.98 80 1 GET 40.media.tumblr.com /0b80deef543f6da28b48db0578fb3bd4/tumblr_n0chjkQICf1qeu577o1_500.jpg - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36 0 70530 200 OK - - - (empty) - - - - - FOHdJ62uCU30UE9VYg image/jpeg
1443534069 CMXgz73HlqL5Z0WVR7 123.456.789.012 59715 54.230.193.223 80 1 GET 36.media.tumblr.com /547822945f762adb310bb966c1f9c886/tumblr_nv3xgebHVH1sbsr1vo1_500.jpg - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36 0 67589 200 OK - - - (empty) - - - - - FmaN4d2eimhA2CpEmd image/jpeg
답변1
이 Perl 스크립트는 기준("image/", > 100000바이트, 참조자 = '-')과 일치하는 각 로그 행을 IP 주소로 입력된 배열 해시에 저장합니다. 스크립트 끝에서 14개 이상의 항목을 포함하는 모든 IP 주소에 대한 모든 배열 행을 인쇄합니다.
많은 메모리를 사용하지만 각 입력 행을 저장하는 만큼 많지는 않습니다.
한 줄로 압축할 수 있지만 아무 이유 없이 읽을 수 없거나 디버깅할 수 없게 됩니다.
#! /usr/bin/perl
use strict;
my %LOGLINES = ();
while (<>) {
next unless (/\bimage\//);
my @F=split("\t");
next unless ($F[10] eq '-');
next unless ($F[13] > 100000);
push @{ $LOGLINES{$F[2]} }, $_;
};
foreach my $key (sort keys %LOGLINES) {
print @{ $LOGLINES{$key} } if (scalar @{ $LOGLINES{$key} } > 14);
}
Perl 배열은 1 기반이 아닌 0 기반임을 참고하세요. 따라서 필드 번호는 지정한 필드 번호에서 -1만큼 오프셋됩니다.
여기 보이는 각 IP 주소에 대해 최대 15줄만 저장한 다음, 보이는 일치하는 줄을 인쇄하기 시작하기 때문에 많은 메모리를 사용하지 않는 또 다른 버전이 있습니다. 단점은 출력이 IP 주소별로 정렬되지 않지만 sort -t $'\t' -k2
.
#! /usr/bin/perl
use strict;
my %LOGLINES = ();
my %count = ();
while (<>) {
next unless (/\bimage\//);
my @F=split("\t");
next unless ($F[10] eq '-');
next unless ($F[13] > 12000);
$count{ $F[2] }++;
if ($count{ $F[2] } == 15) {
print @{ $LOGLINES{$F[2]} }; # print all the log lines we've seen so far
print $_; # print the current line
} elsif ($count{ $F[2] } > 15) {
print $_; # print the current line
} else {
push @{ $LOGLINES{$F[2]} }, $_; # store the log line for later use
}
};