내 서버에 액세스하는 모든 IP 주소를 나열하는 수정된 로그 파일이 있습니다.
각 IP 주소 줄 옆에는 날짜/시간 스탬프가 있습니다.
봇과 악의적인 활동을 필터링하는 과정에서 15초 안에 5개 이상의 요청을 한 IP 주소가 있는지 확인하고 싶습니다.
나는질문이를 측정하는 방법에 대해서는 첫 번째 요청부터 시작하지만 이에 대해 더 논의하고 싶습니다.
저는 현재 (G)AWK를 배우고 있는데 더 배우고 싶습니다. 가능하다면,(G)AWK에서 완료되고 최대한 명확하게 설명되었으면 좋겠습니다., 그래서 저는 이 스크립트를 연구하고 앞으로 비슷한 스크립트를 직접 작성할 수 있기를 바랍니다.
나는 이것이 아마도 Python에서 수행될 수 있다는 것을 알고 있지만 아직 Python을 배운 적이 없습니다.
입력 샘플
내 로그 파일의 전체(작동) 수정된(IP 주소를 난독화하기 위해) 버전은 다음과 같습니다. 로그 파일.csv.
결과를 테스트하려는 경우를 대비해 해당 파일의 [추가 수정된] 예는 다음과 같습니다.
03/Nov/2020:06:33:09|000.000.000.001|200|/page-1/
03/Nov/2020:07:12:21|000.000.000.002|200|/page-2/
03/Nov/2020:07:24:52|000.000.000.003|200|/page-3/
03/Nov/2020:07:30:50|000.000.000.004|200|/page-4/
03/Nov/2020:07:47:29|000.000.000.005|200|/page-5/
03/Nov/2020:07:52:42|000.000.000.006|200|/page-6/
03/Nov/2020:07:52:55|000.000.000.007|200|/page-7/
03/Nov/2020:08:00:11|000.000.000.008|200|/page-8/
03/Nov/2020:08:05:00|000.000.000.009|200|/page-9/
03/Nov/2020:08:05:06|000.000.000.010|301|/page-10/
03/Nov/2020:08:05:32|000.000.000.007|200|/page-11/
03/Nov/2020:09:02:49|000.000.000.011|304|/page-12/
03/Nov/2020:09:02:49|000.000.000.011|404|/page-13/
03/Nov/2020:09:13:18|000.000.000.011|304|/page-14/
03/Nov/2020:09:13:19|000.000.000.011|404|/page-15/
03/Nov/2020:09:14:20|000.000.000.012|200|/page-16/
03/Nov/2020:09:23:48|000.000.000.011|304|/page-17/
03/Nov/2020:09:23:49|000.000.000.011|404|/page-18/
03/Nov/2020:09:34:19|000.000.000.011|304|/page-19/
03/Nov/2020:09:34:19|000.000.000.011|404|/page-20/
03/Nov/2020:09:35:42|000.000.000.013|301|/page-21/
03/Nov/2020:09:35:42|000.000.000.013|404|/page-22/
03/Nov/2020:09:44:49|000.000.000.011|304|/page-23/
03/Nov/2020:09:44:49|000.000.000.011|404|/page-24/
03/Nov/2020:09:53:38|000.000.000.014|200|/page-25/
03/Nov/2020:09:55:19|000.000.000.011|304|/page-26/
03/Nov/2020:09:55:19|000.000.000.011|404|/page-27/
03/Nov/2020:10:05:49|000.000.000.011|304|/page-28/
03/Nov/2020:10:05:49|000.000.000.011|404|/page-29/
03/Nov/2020:10:06:27|000.000.000.005|200|/page-30/
03/Nov/2020:10:16:19|000.000.000.011|304|/page-31/
03/Nov/2020:10:16:19|000.000.000.011|404|/page-32/
03/Nov/2020:10:17:21|000.000.000.015|200|/page-33/
03/Nov/2020:10:20:35|000.000.000.016|200|/page-34/
03/Nov/2020:10:20:37|000.000.000.017|404|/page-35/
03/Nov/2020:10:20:42|000.000.000.017|404|/page-39/
03/Nov/2020:10:20:49|000.000.000.016|200|/page-40/
03/Nov/2020:10:20:55|000.000.000.017|404|/page-41/
03/Nov/2020:10:21:01|000.000.000.017|404|/page-42/
03/Nov/2020:10:21:03|000.000.000.017|404|/page-43/
03/Nov/2020:10:21:05|000.000.000.017|404|/page-44/
03/Nov/2020:10:21:06|000.000.000.017|404|/page-45/
03/Nov/2020:10:21:11|000.000.000.017|404|/page-46/
03/Nov/2020:10:21:14|000.000.000.016|200|/page-47/
03/Nov/2020:10:21:34|000.000.000.016|200|/page-48/
03/Nov/2020:10:21:47|000.000.000.016|200|/page-49/
03/Nov/2020:10:22:14|000.000.000.016|200|/page-50/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-51/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:16|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:17|000.000.000.016|200|/page-53/
03/Nov/2020:10:22:18|000.000.000.019|200|/page-1/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-55/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-56/
원하는 출력
bot-list.txt
나는 당신이 다음의 목록을 포함하는 문서를 생성하길 원합니다.15초 내에 5개 이상의 요청을 하는 IP 주소언제든지(반드시 처음 5일은 아님). 나중에 빈도/지속 시간을 조정하고 싶을 수도 있습니다.
로그 파일이 상당히 크기 때문에 여기에 로그 파일 전체를 게시하는 것은 적절하지 않다고 생각합니다. 그러나 위(수정된) 예제의 출력에는 IP 주소가 2개만 있습니다. 따라서 전체 로그 파일을 테스트하는 것이 더 안정적입니다.
000.000.000.017
000.000.000.016
어떻게 이 결과를 얻었는지 명확하게 설명해주세요.. 추가 보너스로, 잘 알려지지 않은 기술/기능을 사용하는 경우 해당 기술에 대해 자세히 알아볼 수 있는 참고 자료를 알려주시면 감사하겠습니다.
따라서 명확하게 말하면 다음과 같습니다.
- 모든 고유 IP 검색
log-file.csv
- 이 IP의 인스턴스가 5개 이상인 경우 각 행의 날짜/시간 스탬프를 사용하여 인스턴스 간의 차이(초)를 계산합니다.
- 15초 이내에 5페이지 이상에 액세스하는 IP 주소를 격리합니다.
- 이러한 IP 주소를
bot-list.txt
. - 가능하다면 단일 (G)AWK 스크립트에서 이 작업을 완료하세요.
이 개념을 개선하는 방법에 대한 추가 제안을 환영합니다.
내가 시도한 것
솔직히 GAWK에서 행을 비교하는 방법을 모르지만 이전 질문에 대한 답변 중 일부를 보면 가능하다는 것이 분명합니다.
현재 저는 "Effective AWKProgramming"이라는 책을 읽고 있습니다. 재미있긴 한데, 일부로 고생했어요. 연관 배열에 대해서도 알아보고 있지만 프로그래밍 배경 지식이 없기 때문에 천천히 배우고 있습니다.
내 특정 문제를 해결하는 내용을 찾을 수 없으며 해당 주제에 대한 비디오도 거의 없습니다.
누구든지 이러한 유형의 문제를 해결하는 데 도움이 될 수 있는 유용한 리소스를 알려주시면 매우 감사하겠습니다.
날짜를 비교하려고 합니다.
egrep "000.111.000.111" log-file.csv | awk 'BEGIN{FS="|"; ORS=" "} NR==1 || NR==5 {print $1,$2}' | sed -e 's/[\/:]/\ /g' -e 's/Jan/1/g' -e 's/Feb/2/g' -e 's/Mar/3/g' -e 's/Apr/4/g' -e 's/May/5/g' -e 's/Jun/6/g' -e 's/Jul/7/g' -e 's/Aug/8/g' -e 's/Sep/9/g' -e 's/Oct/10/g' -e 's/Nov/11/g' -e 's/Dec/12/g' | awk '{print $3,$2,$1,$4,$5,$6 "," $10,$9,$8,$11,$12,$13","$14}' | awk -F, '{d2=mktime($2);d1=mktime($1);print d2-d1, $3}' | awk '{if($1<15)print $2}' >> bot-list.txt
안타깝게도 보시다시피 (G)AWK에서 모든 것을 할 수는 없지만, 가능해주시면 감사하겠습니다.
(Stack Exchange를 사용하는 것은 이번이 두 번째입니다. 질문하는 방법에 대한 조언을 따르려고 노력하고 실수가 있으면 추가 조언을 받게 되어 기쁩니다.)
감사해요.
답변1
에포크 초를 메모리(배열)로 변환한 후 모든 IP 주소와 타임스탬프를 읽는 간단한 무차별 대입 방법입니다 secs[]
. 그런 다음 전체 파일을 읽은 후 한 번에 하나의 IP 주소 배열을 반복하고 차이와 5개 항목마다 타임스탬프를 확인합니다. 15초 미만의 항목이 있는지 확인하세요.
$ cat tst.awk
BEGIN { FS="|" }
{
split($1,t,"[/:]")
monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])
secs[$2][++count[$2]] = currSecs
}
END {
range = 5
for (ip in secs) {
for (beg=1; beg<=(count[ip]-range)+1; beg++) {
end = beg + range - 1
if ( (secs[ip][end] - secs[ip][beg]) < 15 ) {
print ip
break
}
}
}
}
$ awk -f tst.awk file
000.000.000.016
000.000.000.017
이는 IP 주소 및 에포크 초 목록을 저장하기에 충분한 메모리가 필요하지만 이것이 문제가 되려면 파일이 커야(수십억 줄) 한다는 의미입니다.
편집: 귀하의 질문에 대한 의견에 따르면 입력 파일이 올바른 순서(날짜 + 시간 증가)가 아니므로 다음을 수행하여 문제를 해결할 수 있습니다.
$ awk -F'|' '
{
split($1,t,"[/:]")
monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])
print currSecs, NR, $0
}
' log-file.csv | sort -k1,1n -k2,2n | cut -d' ' -f3- > sorted-log-file.csv
그런 다음 THAT에서 위 스크립트를 실행하여 다음 50개의 IP 주소 출력을 얻습니다.
$ awk -f tst.awk sorted-log-file.csv | sort
000.000.000.011
000.000.000.017
000.000.000.036
000.000.000.056
000.000.000.066
000.000.000.094
000.000.000.115
000.000.000.121
000.000.000.136
000.000.000.141
000.000.000.157
000.000.000.169
000.000.000.178
000.000.000.181
000.000.000.183
000.000.000.208
000.000.000.227
000.000.000.230
000.000.000.283
000.000.000.312
000.000.000.354
000.000.000.361
000.000.000.368
000.000.000.370
000.000.000.505
000.000.000.515
000.000.000.579
000.000.000.580
000.000.000.588
000.000.000.610
000.000.000.634
000.000.000.642
000.000.000.651
000.000.000.748
000.000.000.756
000.000.000.758
000.000.000.772
000.000.000.795
000.000.000.814
000.000.000.852
000.000.000.878
000.000.000.882
000.000.000.922
000.000.000.994
000.000.000.995
000.000.001.047
000.000.001.119
000.000.001.139
000.000.001.185
000.000.001.198