로그 분석 – tr, awk, uniq, sort

로그 분석 방법은 침해 사고뿐만 아니라, 장애 상황에서도 유용하게 사용된다.

대다수의 분석 작업에서는 중요한 부분이 얼마나 불필요한 데이터를 제거하고 원하는 데이터를 수집하는냐에 있다.

로그는 모든 메시지를 담고 있어 많은 량의 데이터를 가지고 있다. 이를 어떻게 분석하는가에 따라, 단서를 발견할 수 도 있고, 영영 미궁으로 빠질 수 도 있다.

따라서 로그를 분석할 때는, 전체 데이터를 보기 보다는 중요한 로그를 먼저 보고 해당 로그로부터 단서를 찾아서, 범위를 좁혀 나가는 방식이 좋다.

사건의 특성에 따라 조금씩 다르겠지만, 가장 중요한 것은 시간이다. 사건 발생 시점에 어떠한 로그들이 발생했고 해당 로그가 시스템이 어떻게 조작/동작 하였는지를 알 수 있는 근거가 된다.

그리고 두번째로는 광대한 로그 데이터를 어떻게 효과적으로 추출할것인가가 중요한 부분인데, 윈도우 명령에는 효과적인 사용구분이 많지 않다.

따라서 텍스트형으로 구분된 로그를 효과적으로 추출할 수 있는 환경을 만들어두는 것이 효과적이다.

 

분석을 위한 준비

로그를 효과적으로 분석하기 위해서는 GUI환경보다 텍스트인 CLI(명령 프롬프트) 환경이 적당하다. 하지만, 윈도우는 GUI 성격이 강하여, CLI에서 텍스트를 필터링하는 많은 조건을 생성하지 못한다.

그래서 여기서는 리눅스에서 사용하는 명령어들을 이용하여, 추가적인 분석에 도움이 되는 필터링 명령들을 알아보고자 한다. 이를 위해서, 사용할 수 있는 유용한 리눅스에 대해 알아보자.

 

Newlinux

http://blog.naver.com/allmnet/ 원 제작자인 pbi12(박병익)님 사이트가 더 이상 운영되지 않아 개인 블로그에 올려두었다. 리눅스에서 사용하는 쉘 기반 명령어를 윈도우에서 사용 할 수 있다. 기본적으로는 Windows 2003까지 지원하나, 비스타에 설치하여도 잘 동작한다.

 

coLinux

http://www.colinux.org 윈도우 운영체제에 샌드박스형태의 가상머신을 임베디드 형태로 설치할 수 있는 리눅스 운영체제로써 윈도우와 리눅스를 동시에 사용할 수 있다. 유닉스 명령어 몇 개 사용하자고 이 운영체제를 설치하는 것은 아닐 수 있다. 하지만, 리눅스의 휼륭한 gcc와 g++의 개발 환경이라거나, 윈도우와 리눅스를 자주 사용하는 경우 유용하다. 윈도우 파일 시스템과도 연결되어 있어, 접근도 자유로와 매력적인 운영체제이다.

 

Linux Subsystem

윈도우 10부터 추가된 추가 기능으로 프로그램 추가/제거 에서 내부 프로그램 기능 추가로 사용이 가능하다. 마이크로소프트에서 제공하기 때문에 가장 윈도우에 잘 호환되며, 사용이 유용하다.

[내용] 로그 추출 능력이 좋은 UNIX 도구를 이용할 수 있다

 

tr

표준입력으로 받아들인 문자들을 지정한 문자로 변환하여 출력해 주기위해 사용하는 명령어로

보통 제거에 많이 사용되지만, 변환 기능도 강력하다.

다음과 같이 사용할 수 있다.

 

tr [옵션] [문자열1] [문자열2]

[내용] tr 명령 사용법

 

tr 명령의 사용의 주의할 점은 파일안에 특정 내용을 지정하는 방식이 아닌 바꾸기와 같이 동일 내용은 전부 바꾸어지게 된다.

기본 사용 방식은 다음과 같다.

 

//파일 1234를 abcd로 변환한다.

tr ‘1234’ ‘abcd’ < file

//연속형 문자의 경우 –(하이픈)을 이용하여 지정할 수 있다.

tr [1-4] ‘abcd’

[내용] tr 변경 예제

 

함께 사용할 수 있는 옵션들도 몇가지 제공하는데 다음과 같은 기능을 한다.

–d

해당 구문을 제거하는 용도로 사용된다. 사용방법은 다음과 같다.

 

//입력 문자중 ‘[‘를 제거한다.

tr –d ‘[‘

[내용] tr 제거 예제

-s

지정한 문자들이 나타나면 처음 나온것 외에 모두 삭제 한다.

사용방법은 다음과 같다.

 

//기본적인 dir 출력 결과 이다.

C:\Users\juhan>dir

C 드라이브의 볼륨: WIN7

볼륨 일련 번호: 0C91-5CC4

 

C:\Users\juhan 디렉터리

 

2012-02-24 오후 01:43 <DIR> .

2012-02-24 오후 01:43 <DIR> ..

2012-02-16 오후 07:41 <DIR> .cache

2011-12-29 오후 05:57 218 .recently-used.xbel

2012-02-24 오전 10:28 <DIR> .VirtualBox

2012-02-16 오전 10:32 <DIR> .zenmap

2011-03-23 오후 05:11 <DIR> AcunetixScanner

2011-01-27 오후 06:55 <DIR> AppData

2012-02-17 오전 09:16 <DIR> Contacts

2012-02-22 오전 10:57 <DIR> Daum 클라우드

2012-02-24 오후 01:46 <DIR> Desktop

2012-02-17 오전 11:04 110,246 dlllist.txt

2012-02-24 오후 01:43 <DIR> Documents

2012-02-24 오후 01:43 <DIR> Downloads

2012-02-24 오후 01:43 <DIR> Favorites

2012-02-14 오후 05:11 23,470 fciv.err

2012-02-16 오전 10:01 15 get.txt

2011-09-23 오전 11:37 <DIR> keel

2012-02-17 오전 09:16 <DIR> Links

2012-02-24 오후 03:33 85 mm.cfg

2012-02-17 오전 09:16 <DIR> Music

2011-12-17 오후 05:49 <DIR> oni

2012-02-24 오후 01:43 <DIR> Pictures

2012-02-17 오전 09:16 <DIR> Saved Games

2012-02-17 오전 09:16 <DIR> Searches

2012-01-05 오전 11:44 16 test.txt

2011-11-10 오후 04:21 <DIR> Tracing

2012-02-17 오전 09:16 <DIR> Videos

2012-01-17 오후 04:49 8,521 _viminfo

2012-02-07 오전 09:00 <DIR> 네이버공유

7개 파일 142,571 바이트

23개 디렉터리 15,368,720,384 바이트 남음

//위 정보를 소문자 알파벳이 아니면 ‘\012’구문으로 변환한다. 따라서 아래와 같이 소문자만이 남게 된다.

C:\Users\juhan>dir | tr -cs a-z ‘\012’

‘sers’juhan’cache’recently’used’xbel’irtual’ox’zenmap’cunetix’canner’pp’ata’onta

cts’aum’esktop’dlllist’txt’ocuments’ownloads’avorites’fciv’err’get’txt’keel’inks

‘mm’cfg’usic’oni’ictures’aved’ames’earches’test’txt’racing’ideos’viminfo’

[내용] tr 변환 예제

-c

[문자열1]에 없는 표준입력의 모든 문자가 [문자열2]로 변환되도록 한다. 앞서 cs와 다른점은 삭제하지 않으므로, 아래 예제와 같이 모든 내용을 변환하게 된다.

 

//앞서 진행한 예제와 차이점은, 하나의 이상의 변환값이 존재 할 경우 해당 값을 삭제하지 않는다.

C:\Users\juhan>dir | tr -c a-z _

_____________________________________________________________sers_juhan________________________________________________________________________________________________________________________________________________cache____________________________________________recently_used_xbel_____________________________________________irtual_ox____________________________________________zenmap____________________________________________cunetix_canner____________________________________________pp_ata____________________________________________ontacts____________________________________________aum_____________________________________________________esktop___________________________________________dlllist_txt____________________________________________ocuments____________________________________________ownloads____________________________________________avorites___________________________________________fciv_err___________________________________________get_txt___________________________________________keel____________________________________________inks___________________________________________mm_cfg____________________________________________usic___________________________________________oni____________________________________________ictures____________________________________________aved__ames____________________________________________earches___________________________________________test_txt____________________________________________racing____________________________________________ideos____________________________________________viminfo____________________________________________________________________________________________________________________________________________________________________

[내용] tr 변환 예제

 

문자열 지정시 특정 캐릭터셋 전체를 아래 구문을 이용하여 지정할 수 있다.

[:alnum:]        모든 문자 및 숫자

[:alpha:]        모든 문자

[:alnum:]        모든 문자 및 숫자

[:alpha:]        모든 문자

[:blank:]        모든 수평 공백문자들

[:cntrl:]        모든 컨트롤 문자

[:digit:]        모든 숫자

[:graph:]        모든 표시 가능한 문자, 공백은 포함하지 않음

[:lower:]        모든 소문자

[:print:]        모든 표시 가능한 문자, 공백 포함

[:punct:]        모든 문장 기호 문자

[:space:]        모든 수평 및 수직 공백문자

[:upper:]        모든 대문자

[:xdigit:]        모든 16진수 숫자

[=CHAR=]    CHAR와 동일한 모든 문자

 

awk

awk는 일반적으로 데이터 또는 유사 데이터양식의 파일 및 자료를 처리하는데 쓰인다. C언어 문법을 연상시키는 완전한 형태의 텍스트 처리 언어로써 광범위한 연산자등과 뛰어난 성능을 가지고 있다. 따라서 여기서 전 기능에 대해 정리하기는 어렵고, 유용한 기능들에 대해서 확인해 보자.

(awk는 NewLinux에서는 제공하지 않는다. 따라서 coLinux를 이용하자.)

로그 분석에서 가장 유용한 기능은 바로 필드나 컬럼을 뽑아낼수 있는 능력을 awk를 통해 가능하다. 다음 예제를 살펴보자.

 

# 5번째 필드를 표준출력으로 출력 (기본 필드의 구분은 공백으로 된다.)

awk ‘{print $5}’

 

# 1번째, 3번째, 5번째 필드를 출력.

awk ‘{print $1 $3 $5}’

[내용] awk 사용 예제

 

awk에서 제공하는 내부 함수를 이용하면 데이터를 재가공하여, 보다 정교하게 출력 데이터를 추출할 수있다. 그럼 일부 해당 함수들에 대해 알아보자.

 

split

split 함수는 변수 값에 값을 저장하는 함수로, split(string, array, delimeter)로 사용되며, string을 delimeter 를 기준으로 나누어 array에 저장하는 함수이다.

그럼 예제를 통해 확인해 보자.

 

cat b.txt | awk ‘{ split($2,arr,”:”); if ( arr[2] == “과일”) print $0; }’

[내용] split 사용 예제

 

match

match 함수는 조건이 포함된 경우 해당 라인을 출력하는 함수로, match(string , regular expression)로 사용된다.

 

cat a.txt | awk ‘{ if ( match($2,”NN”) ) print $0}’

[내용] match 사용 예제

 

substr

substr 함수 역시 조건 값을 출력해주는 함수로 substr(string , starting position , [length])로 사용되며, string을 starting position기준으로 [length]만큼 출력해준다.

cat a.txt | awk ‘{if (substr($2,0,2) == “NN” ) print $0}’

[내용] substr 사용 예제

 

uniq

중복된 내용의 행이 연속으로 있으면 중복 없이 하나의 행으로 만들어 주는 주로 sort 명령과 함께 사용된다. –c 옵션을 이용할 경우 중복 건수를 카운트하여 보여준다.

C:\>cat juhan

HAN

HAN

JU

JU

SEONG

seong

C:\>cat juhan | uniq

HAN

JU

SEONG

seong

 

C:\>cat juhan | uniq –c

2 HAN

2 JU

1 SEONG

1 seong

[내용] uniq 사용 예제

 

sort

출력 결과를 정렬하는 명령으로, 역순으로 정렬하거나, 같은 값의 수를 카운터가 가능하다. 역분석진행시, 요청 빈도와 같은 비율을 추출할 때 유용하다.

 

//원래의 검색 결과는 다음과 같다.

C:\>cat abcd.txt

f

F

C

E

A

D

E

C

Z

B

A

//순서대로 표시

C:\>cat abcd.txt | sort

A

A

B

C

C

D

E

E

F

f

Z

//역순으로 표기

C:\>cat abcd.txt | sort /R

Z

F

f

E

E

D

C

C

B

A

A

//동일 항목의 횟수를 표시

C:\>cat abcd.txt | sort | uniq -c

2 A

1 B

2 C

1 D

2 E

1 F

1 f

1 Z

[내용] sort 사용 예제

 

그럼 지금까지 확인한 명령을 이용하여, 웹로그를 분석해 보도록 하자.

 

//웹으로 접근한 IP에 대해 횟수와 함께 조사하고자 할 때

juhan@andLinux:~/windows$ cat ex111213.log | tr -d “[” | tr -d ] | awk ‘split($4

, dt, ” “) {print dt[1]}’ | uniq -c | sort -rn

43 127.0.0.1

37 127.0.0.1

3 127.0.0.1

3 127.0.0.1

1 s-sitename

1 s-sitename

1 s-sitename

1 s-sitename

1 Information

1 Information

1 Information

1 Information

//해당 IP에 대한 로그만 확인하고자 할 때, 4번째 구분의 IP 127.0.0.1이 들어감 문장만 출력하게 된다.

juhan@andLinux:~/windows$ cat ex111213.log | awk ‘{ if (match($4, “127.0.0.1”))print $0 }’

2011-12-13 04:26:15 W3SVC1 127.0.0.1 POST /loginCheck.asp – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 200 00

2011-12-13 04:26:19 W3SVC1 127.0.0.1 POST /loginCheck.asp – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 200 00

2011-12-13 07:03:14 W3SVC1 127.0.0.1 POST /loginCheck.asp – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 200 00

2011-12-13 07:03:18 W3SVC1 127.0.0.1 POST /loginCheck.asp – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 200 00

2011-12-13 07:03:26 W3SVC1 127.0.0.1 POST /loginCheck.asp – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 200 00

[내용] 웹로그 추출

 

위 명령을 이용하여 검색하면, 127.0.0.1로 접근한 관련 로그들만 추출이 가능하며 아래와 같은 결과값을 확인할 수 있다.

 

[그림]Colinux를 이용하여 로그 분석 작업을 손쉽게 진행할 수 있다.

 

여러 파일에서 내용 찾기

만약 대량의 서버를 통해 여러 서버에서 로그가 수집되어 경로도 다양한 경우, 모든 디렉토리를 돌아다니며 검색을 진행하는건 비효율 적이다.

이를 find명령과 함께 사용 하위 디렉토리도 동시에 검색할 수 있어 원하는 엑세스 로그파일을 쉽게 찾아낼 수 있다.

 

find /weblog/ -name ‘*’ -exec grep 61.33.3.156 {} \;

[내용] /weblog/ 하위의 모든 디렉토리에서 61.33.3.156이 있는 문서 출력

 

 

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

This site uses Akismet to reduce spam. Learn how your comment data is processed.