로그 파일
About 25% of the activity is 200-OK활동의 약 25%가 200-OK입니다.
내 웹 서버가 일부 로그 파일을 1년 동안 보관하고 일부는 한 달 동안 보관해 왔다는 사실을 발견했습니다. 나는 서버 방문자에 대한 정보가 포함된 세 가지 유형의 로그 파일을 탐색했습니다(덜 흥미롭다고 생각되는 다른 파일도 있습니다). 다음은 몇 가지 일반적인 예입니다.
그만큼 인증로그 (IP가 변경됨)
Oct 23 06:02:24 server1 sshd[20172]: Failed password for invalid user admin from 192.168.1.1 port 64721 ssh2
Oct 23 06:09:01 server1 CRON[20181]: pam_unix(cron:session): session opened for user root by (uid=0)
Oct 23 06:09:01 server1 CRON[20181]: pam_unix(cron:session): session closed for user root
Oct 23 06:10:35 server1 sshd[20195]: Did not receive identification string from 192.168.1.1
Oct 23 06:10:40 server1 sshd[20196]: Invalid user admin from 192.168.1.1
Oct 23 06:10:40 server1 sshd[20196]: input_userauth_request: invalid user admin [preauth]
Oct 23 06:10:41 server1 sshd[20196]: pam_unix(sshd:auth): check pass; user unknown
웹 서버에서의 인증 시도는 나, 내 서버에 속한 소프트웨어(위의 CRON) 또는 다른 사람이나 컴퓨터(위의 사용자 ID admin을 시도하는 사람)에 의한 로그인 시도를 나타냅니다. 관리자는 "나쁜 놈들" 범주에 속합니다.
그만큼 접속.로그 (Apache 서버) (IP가 변경됨)
192.168.2.2 - - [30/Aug/2016:08:30:29 -0400] "GET / HTTP/1.1" 200 1714 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
192.168.1.1 - - [30/Aug/2016:08:51:52 -0400] "GET /hndUnblock.cgi HTTP/1.0" 404 496 "-" "Wget(linux)"
192.168.1.1 - - [30/Aug/2016:08:51:52 -0400] "GET /tmUnblock.cgi HTTP/1.0" 404 495 "-" "Wget(linux)"
192.168.1.1 - - [30/Aug/2016:08:51:52 -0400] "GET /cgi/common.cgi HTTP/1.0" 404 496 "-" "Wget(linux)"
192.168.1.1 - - [30/Aug/2016:08:51:53 -0400] "GET /stssys.htm HTTP/1.0" 404 492 "-" "Wget(linux)"
192.168.1.1 - - [30/Aug/2016:08:51:53 -0400] "GET / HTTP/1.0" 200 1714 "-" "Wget(linux)"
192.168.1.1 - - [30/Aug/2016:08:51:54 -0400] "POST /command.php HTTP/1.0" 404 493 "-" "Wget(linux)"
192.168.3.3 - - [30/Aug/2016:09:09:01 -0400] "GET /?feed=rss2 HTTP/1.1" 200 794 "-" "Feedly/1.0 (+http://www.feedly.com/fetcher.html; like FeedFetcher-Google)"
액세스 로그 항목은 서버에서 웹페이지를 가져오려는 시도를 나타냅니다. 위의 첫 번째 줄은 웹 크롤러의 유효한 요청을 나타냅니다( 바이두 , 중국 검색 엔진). get 요청은 메인 페이지인 /에 대한 것이었습니다. 200은 페이지가 정상적으로 제공되었음을 의미합니다. 다음 6개 줄에는 모두 404(찾을 수 없음) 결과가 있습니다. 이것은 잘못 구성된 웹 서버를 찾으려는 해커입니다. 여러 번의 시도 끝에 모니터링 소프트웨어(Fail2Ban)가 무슨 일이 일어나고 있는지 알아차리고 그를 차단했습니다. 저는 Fail2Ban이 정말 중요하다고 생각했습니다(여전히 그렇습니다!). 그러다가 UFW, Uncomplicated Fire Wall, 그리고 훨씬 더 큰 위협에 대해 알게 되었습니다.
여기에 UFW.log :
Oct 9 04:35:21 server1 kernel: [5110701.311961] [UFW BLOCK] IN=venet0 OUT= MAC= src=175.9.9.9 DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=40 ID=53848 DF PROTO=TCP SPT=10651 DPT=23 WINDOW=5808 RES=0x00 SYN URGP=0
Oct 9 04:35:24 server1 kernel: [5110704.311558] [UFW BLOCK] IN=venet0 OUT= MAC= src=175.8.8.8 DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=40 ID=53849 DF PROTO=TCP SPT=10651 DPT=23 WINDOW=5808 RES=0x00 SYN URGP=0
Oct 9 04:35:36 server1 kernel: [5110715.912365] [UFW BLOCK] IN=venet0 OUT= MAC= src=112.7.7.7 DST=192.168.1.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=32234 PROTO=TCP SPT=60061 DPT=23 WINDOW=16244 RES=0x00 SYN URGP=0
Oct 9 04:35:46 server1 kernel: [5110726.213736] [UFW BLOCK] IN=venet0 OUT= MAC= src=67.6.6.6 DST=192.168.1.1 LEN=44 TOS=0x00 PREC=0x40 TTL=239 ID=7084 PROTO=TCP SPT=57510 DPT=23 WINDOW=14600 RES=0x00 SYN URGP=0
Oct 9 04:37:02 server1 kernel: [5110802.146865] [UFW BLOCK] IN=venet0 OUT= MAC= src=139.5.5.5 DST=192.168.1.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=33753 PROTO=TCP SPT=6885 DPT=23 WINDOW=9693 RES=0x00 SYN URGP=0
Oct 9 04:37:53 server1 kernel: [5110853.056320] [UFW BLOCK] IN=venet0 OUT= MAC= src=87.4.4.4 DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=54 ID=61204 DF PROTO=TCP SPT=47013 DPT=23 WINDOW=5808 RES=0x00 SYN URGP=0
Oct 9 04:37:56 server1 kernel: [5110856.056659] [UFW BLOCK] IN=venet0 OUT= MAC= src=87.3.3.3 DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=54 ID=61205 DF PROTO=TCP SPT=47013 DPT=23 WINDOW=5808 RES=0x00 SYN URGP=0
Oct 9 04:38:02 server1 kernel: [5110862.056195] [UFW BLOCK] IN=venet0 OUT= MAC= src=87.2.2.2 DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=54 ID=61206 DF PROTO=TCP SPT=47013 DPT=23 WINDOW=5808 RES=0x00 SYN URGP=0
Oct 9 04:39:04 server1 kernel: [5110924.610656] [UFW BLOCK] IN=venet0 OUT= MAC= src=175.1.1.1 DST=192.168.1.1 LEN=40 TOS=0x00 PREC=0x00 TTL=43 ID=16953 PROTO=TCP SPT=35941 DPT=23 WINDOW=41293 RES=0x00 SYN URGP=0
UFW BLOCK 라인의 각 라인은 서버에 대한 또 다른 종류의 공격, 즉 잘못 구성된 포트를 찾는 것을 나타냅니다. 이 라인은 모두 DPT=23을 테스트하고 있습니다. 텔넷 , 고대 프로토콜. 이 현상은 적어도 1분에 한 번씩 발생합니다. 하루 종일. 매일.
데이터 테이블에 데이터 로드
각 파일의 형식은 다르며 날짜에는 현재 연도가 포함되지 않을 수 있으며 필드에는 이름=값이 있거나 위치만 있을 수 있습니다. Linux 서버의 모든 파일을 Windows 시스템으로 이동하고 FilesInDirectory를 사용하여 JSL에서 파일 이름 목록을 가져왔습니다. 그런 다음 세 가지 유형의 파일을 효율적으로 구문 분석하기 위해 일련의 패턴을 작성했습니다. 데이터 테이블 열은 각 파일에서 캡처하려는 데이터를 나타내기 위해 선택되었습니다.
Columns in table테이블의 열
ipaddr32는 그래프의 연속 축에 대해 1.2.3.4를 1<<24 + 2<<16 + 3<<8 + 4로 변환하는 수식 열입니다. ipname은 나중에 조회됩니다. kind2는 모든 다른 사용자 ID를 "로그인"으로 줄이는 공식입니다.
path = "f:/logs/";
list = Files In Directory( path, "recursive" );
global:dt = New Table( "logData",
New Column( "datetime", Numeric, "Continuous", Format( "ddMonyyyy:h:m:s", 18, 0 ), Input Format( "ddMonyyyy:h:m:s", 0 )),
New Column( "ipaddr", Character, "Nominal" ),
New Column( "kind", Character, "Nominal" ),
New Column( "detail1", Character, "Nominal" ),
New Column( "detail2", Character, "Nominal" )
);
효율적인 파싱
대용량 파일의 속도를 최대화하려면 JSL 구문 분석을 단일 PatMatch 함수 호출로 수행해야 합니다. PatMatch에 대한 각 호출에는 약간의 오버헤드가 있으며, 여러 번 호출하는 경우 진행하면서 입력 문자열을 잘라내어 오버헤드가 더 추가될 수도 있습니다. 따라서 로그 파일당 하나의 PatMatch를 사용하여 수행해 보겠습니다. 키는 PatRepeat 및 PatTest라는 두 가지 패턴 일치 기능입니다. PatRepeat를 사용하면 파일의 각 줄에 대해 패턴이 반복됩니다. PatTest는 일치 중에 패턴이 일부 JSL을 실행하도록 합니다(명목상 조건을 테스트하기 위한 것이지만 테스트 결과는 항상 "true"입니다). 몇 가지 도우미 패턴을 추가하고 좋은 내용을 추가합니다.
ipPattern = patRegex("(\d{1,3}[-.]\d{1,3}[-.]\d{1,3}[-.]\d{1,3})|([a-fA-F0-9:]+)"); // approximation
ipMonth=patRegex("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec");
datePattern1 = "[" + patregex("\d{2}")>>day + "/" + ipMonth>>month + "/" + patregex("\d{4}")>>year + ":" + patregex("\d\d:\d\d:\d\d")>>time + patregex(" [-+]\d{4}") +"]"; // [18/Sep/2016:06:14:25 -0400]
datePattern2 = ipMonth>>month + patspan(" ") + patregex("\d{1,2}")>>day + " " + patregex("\d\d:\d\d:\d\d")>>time + pattest(year="2016";1); //vs Oct 16 04:54:31 the unknown year is 2016 for these logs
quote = "\!"";
quotepattern = quote + patrepeat(patbreak(quote||"\") +(("\"+(quote|""))|"")) + quote; // allows \" escaped embedded quotation marks
두 날짜 패턴은 두 날짜 형식과 일치합니다. >> 연산자는 왼쪽의 일치하는 텍스트를 오른쪽의 변수에 넣습니다. PatTest(year="2016";1)은 2016년을 연도에 할당한 후 항상 true를 반환합니다. 이는 명시적인 연도가 없는 로그 파일용입니다. 나는 점점 더 큰 패턴을 만들기 위해 패턴과 정규식을 혼합하여 사용합니다. Apache access.log 패턴은 다음과 같습니다.
apachePat = ipPattern>>ip+" "+patbreak(" ")+" "+patbreak(" ")+" "
+datePattern1+" "
+quotePattern>>request+" "
+patbreak(" ")>>code+" "
+patbreak(" ")>>length+" "+patbreak(" ")+" "
+(quotePattern|patbreak("\!n\!r"))>>browser
+pattest(
dt1<<ADDROWS></ADDROWS>
이것이 수행하는 작업을 access.log의 행과 비교하십시오.
192.168.1.1 - - [30/Aug/2016:08:51:52 -0400] "GET /tmUnblock.cgi HTTP/1.0" 404 495 "-" "Wget(linux)"
그리고 끝에 pattest(...) 가 있는지 확인하세요. dt1 테이블에 행을 추가하고 방금 구문 분석한 값으로 열을 채웁니다.
UFW 및 인증 패턴도 있습니다. 파일을 구문 분석하는 함수는 다음과 같습니다.
global:skipPattern = (patbreak("\!n\!r") + patlen(1))>> unknown + pattest(show(filename,unknown);stop();1);
global:whitespace = patregex("\s*");
parser = Function( {filename, pattern, dt1}, {Default Local},
txt = Load Text File( filename );
rc = Pat Match( //
txt, //
Pat Pos( 0 ) //
+ Pat Repeat( ((global:whitespace + pattern + global:whitespace) | global:skipPattern) + Pat Fence() ) //
+ Pat R Pos( 0 ) //
); //
);
이 함수는 filename에서 로그를 로드하고 패턴 매개변수를 사용하여 이를 구문 분석하고 결과를 dt1에 저장합니다. PatMatch 기능은 인식할 수 없는 줄을 건너뛸 수 있는 교대 패턴을 구축합니다. PatFence()는 대용량 파일을 위한 또 다른 최적화입니다. 이는 "여기까지 도달했다면 백업하고 다른 것을 시도할 필요가 없습니다"라는 의미이며, 일치 속도를 높이고 필요한 메모리를 줄일 수 있습니다. 마지막으로 함수의 드라이버는 다음과 같습니다.
While( N Items( file = Remove From( list, 1 ) ) == 1, //
file = file[1];//
If(//
!Is Missing( Regex( file, "ssl_access.log" ) ), //
parser( path || file, apachePat, global:dt );//
, // else
!Is Missing( Regex( file, "other_vhosts_access.log" ) ), //
0//parser( path || file, apachePat, global:dt );//
, // else
!Is Missing( Regex( file, "access.log" ) ), //
parser( path || file, apachePat, global:dt );//
, // else
!Is Missing( Regex( file, "ufw.log" ) ),
parser( path || file, ufwPat, global:dt );//
, // else
!Is Missing( Regex( file, "auth.log" ) ), //
parser( path || file, authPat, global:dt );//
);//
);//
가볼만한 곳
Raspberry PI 컴퓨터는 사용자 이름 PI를 사용하여 많은 공격을 유인하는 것으로 보입니다. PHP 스크립팅은 종종 잘못 구성되어야 합니다. 특정 PHP "관리자" 파일에 대한 검사가 많이 있습니다. 그리고 약점이 있는 개방형 포트를 찾는 것은 정말 가치 있는 일임에 틀림없습니다. 대부분의 공격은 테스트 포트입니다. 웹 서버를 관리하고 Fail2ban 및 방화벽 규칙(예: UFW)을 사용하지 않는 경우 설치 및 구성을 고려해야 합니다. 초당 여러 번 시도하는 대신 하루에 몇 번의 시도를 허용하여 무차별 공격의 속도를 늦출 수 있습니다.
Dashboard view of web traffic웹 트래픽의 대시보드 보기