반응형

인용: 해킹사고의 재구성 - 최상용

 

wtmp, wtmpx

 

==> 사용자의 로그인/로그아웃 이력, 시스템의 셧다운/ 부팅 이력 등이 포함되어 있으며 last명령으로 내용 확인 가능

 

utmp, utmpx

 

==> 시스템에 현재 로그인한 사용자의 상태를 기록한 파일로 사용자 이름, 터미널 장치 이름, 원격 로그인 시 원격 호스트명, 사용자가 로그인한 시간 등이 기록되어 있으며, who,w, whodo, users, finger 등의 명령을 사용해 관련된 정보를 알아 낼 수 있다.

 

sulog

 

==> 사용자가 su라는 명령을 사용한 기록을 갖고 있으며, 날짜와 시간, 성공/실패 , 사용한 터미널 이름, from 사용자, to 사용자 등의 정보를 포함한다. 리눅스 시스템에서는 해당 로그가 messages 파일 또는 auth.log에 기록된다.

 

syslog, secure

 

==> 사용자 인증과 관련된 로그와 커널, 데몬에서 생성된 모든 로그를 포함. 특히 rsh,rlogin, ftp, finger, telnet, pop3 등에 대한 접속 기록과 접속 실패 기록 등이 남으며, /etc/syslog.conf 설정에 따라 달라진다. 또한 BOF 공격의 시도의 경우 관련된 로그가 남는 유일한 파일이다.

 

lastlog

 

==> 각 사용자가 가장 최근에 로그인한 시간과 접속 장소가 기록되는 파일로서, 사용자가 시스템에 로그인할 때 마다 갱신된다. 텍스타 파일 포맷임.

 

messages

 

==> 타임스탬프, 호스트명, 프로그램명, 메시지 내용 등이 기록되는데 메시지 내용에는 su 실패에 대한로그, 특정 데몬이 비활성화된 로그, 부팅 시 발생한 에러등 다양한 로그를 포함. syslog 프로세스에 의해 남는 로그로 /etc/syslog.conf에 어떻게 설정되어 있느냐에 따라 남는 정보의 종류가 달라진다. syslog와 마찬가지로 보안사고 발생 시 가장 먼저 분석해야 하는 파일이다.

 

history

 

==> 사용자가 한 작업을 알 수 있다. 쉘에 따라 .sh_history, .history, .bash_history 등의 파일로 기록

반응형
반응형

0. Access log

 

125.131.10.12 - - [11/Dec/2013:00:01:45 -0800] "GET /xampp/status.php HTTP/1.1" 200 3891 "http://cadenza/xampp/navi.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0"

 

125.131.10.12 -> 클라이언트가 접속한 주소

[11/Dec/2013:00:01:45 -0800] -> 접속 시간

GET -> 메소드 정보

/xampp/status.php -> 요청한 페이지

HTTP/1.1 -> HTTP 버전

200 -> 응답 코드

 

 

 

1. 메소드

 

-> 메소드는 GET,POST, PUT, DELETE, MKDIR, RMDIR 등이 있으며 주로 GET,POST가 쓰이고 HEAD가 일부 사용된다 하지만 이 외의 메소드가 존재할 경우 공격의 흔적을 의심해볼 필요가 있다. 특히 PUT메소드를 이용한 경우 파일을 업로드 하므로 이 메소드를 주의 깊게 살펴봐야한다.

 

 

 

 

2. 상태코드

 

에이콘 출판사 [웹 해킹 & 보안 완벽가이드] <데피드 스터타드 저>인용


상태 코드는 코드의 첫번째 숫자에 의해 크게 다섯 가지로 구분한다.

  • 1xx : 정보를 제공함

  • 2xx : 요청이 성공적으로 이뤄짐

  • 3xx : 요청한 해당 자원이 다른 곳에 있음

  • 4xx : 요청(클라이언트)에 문제가 있음

  • 5xx : 서버에 에러가 있음



 

주요 상태코드

  • 100 Continue
    클라이언트가 서버에게 메시지 바디를 포함한 요청을 보냈을 때 받는 응답 코드다. 서버의 응답에는 클라이어트가 요청한 헤더를 전송 받았고, 클라이언트는 계속해서 서버에게 바디를 보낼 수 있다고 나타낸다. 서버는 클라이언트의 요청이 완료되면 두 번째 응답을 보낸다.

  • 200 OK
    클라이언트의 요청이 성공했다는 것을 나타낸다. 서버의 응답 메시지 바디에 클라이언트가 요청한 내용에 대한 결과를 포함한다.

  • 201 Created
    클라이언트의 PUT 요청이 성공적이라는 것을 나타낸다.

  • 301 Moved Permanently
    브라우저의 요청을 다른 URL로 항시 전달한다는 것을 의미한다. 다른 URL에 대한 정보는 Location 헤더에 나타난다. 따라서 클라이언트는 예전 URL 대신에 새로 바뀐 URL 을 통해 자원을 찾는다.

  • 302 Found
    브라우저의 요청을 임시 URL로 바꾸고 Location 헤더에 임시로 변경한 URL에 대한 정보를 적는다. 클라이언트가 다음에 같은 요청을 하면 기존의 URL로 돌아간다.

  • 304 Not Modified
    브라우저가 서버에게 요청한 자료에 대해 서버는 클라이언트 내에 복사된 캐시를 사용하게 한다. 서버는 If-Modified-Since 와 If-None-Match 요청 헤더를 사용해 클라이언트가 가장 최근의 자료를 가지고 있는지 여부를 확인한다.

  • 400 Bad Request
    클라이언트가 서버에게 잘못된 HTTP 요청을 했다는 것을 나타낸다. 예를 들어 클라이언트가 URL 주소의 중간에 빈 공간을 넣는 등 부적절한 방법으로 서버에게 요청을 한 경우 400 Bad Request 응답코드를 받는다.

  • 401 Unauthorized
    서버가 클라이언트의 요청에 대해 HTTP 인증 확인을 요구하는 것을 의미한다. www-authenticate 헤더는 인증과 관련된 내용을 지원하는 다양한 타입에 대한 정보를 담고 있다.

  • 403 Forbidden
    클라이언트의 요청에 대해 접근을 차단한다는 것을 나타낸다.

  • 404 Not Found
    클라이언트가 서버에게 요청한 자료가 존재하지 않는다는 것을 나타낸다.

  • 405 Method Not Allowed
    클라이언트가 요청에 이용한 메소드가 해당 URL에 지원이 불가능하다는 것을 나타낸다. 예를 들어 PUT 방식을 지원하지 않는 곳에서 클라이언트가 PUT 메소드를 통해 서버에게 자원을 요청했다면 405 상태 코드를 보게 된다.

  • 413 Request Entity Too Large
    클라이언트가 요청한 바디를 서버에서 처리하기에는 너무 크다는 것을 나타낸다. 예를 들어 버퍼 오버플로우의 취약점을 찾고자 긴 문자열 데이터를 서버에 전송하면 413 상태 코드를 보게 된다.

  • 414 Request URI Too Long
    413응답과 비슷하지만 414 메시지는 요청에 사용된 URL이 서버가 감당할 수 없을 만큼 너무 크다는 것을 나타낸다.

  • 500 Internal Server Error
    서버가 클라이언트의 요청을 실행할 수 없을 때 500 상태 코드가 발생한다. 보통 서버가 예상하지 못한 요청을 보냈을 때 애플리케이션이 적절히 처리하지 못할 경우 500 상태 코드를 볼 수 있다. 어디서 문제가 생겼는지 알아보려면 서버의 응답 내용을 상세히 살펴봐야 한다.

  • 503 Service Unavailable
    웹서버는 클라이언트의 요청에 대해 정상적으로 응답할 수 있으나 서버에서 구동 중인 애플리케이션이 응답을 하지 못할 때 나타난다. 503 상태 코드의 경우 클라이언트가 요청을 잘못해서 발생했는지 아니면 서버에 있는 애플리케이션이 문제가 있는지 잘 확인해야 한다.

반응형
반응형

출처: 해킹사고의 재구성 - 최상용

 

피해유형 

취약점 

공격 방법 

로그 

위/변조 

 SQL 구문 삽입

SQL 구문 삽입을 이용해 인가되지 않은 로그인을 성공한 후 게시물 소스파일 등 삭제 

웹 로그, IPS, IDS 

SQL 구문 삽입을 통한 DB내 데이터 변조 

웹 로그, IPS, IDS 

파일 업로드 

PUT 메소드를 이용한 원격 파일 업로드

웹 로그, IPS, IDS 

웹셸을 업로드해 소스 파일 삭제, 소스 파일 내용 변경등 변조

웹 로그, IPS, IDS 

허가 되지 않은 접근 

터미널 서비스를 이용한

원격 접근

시스템 로그, 방화벽

RPC를 이용한 원격 접근

IPS,IDS messages,방화벽, loginlog, utmp, wtmp, last 로그, SU 로그

텔넷, FTP등 inet 서비스를 이용한 원격 접근

IPS,IDS messages,방화벽, loginlog, utmp, wtmp, last 로그, SU 로그

취약한 ID/패스워드를 유추해 관리자 페이지 접근

웹 로그, IPS,IDS

XSS

XSS를 이용한 사용자 정보 갈취 후 관리자 페이지 등 인가되지 않은 페이지 접근

웹 로그, IPS,IDS

CSRF

CSRF를 이용한 글쓰기

웹 로그, IPS,IDS

입력 값 검증 부재 

URL 조작을 이용한 인가되지 않은 게시판 접근

웹 로그, IPS,IDS

파라미터 조작을 이용한 인가되지 않은 게시판 접근

웹 로그, IPS,IDS

원격서버에 올려 놓은 악성 프로그램 실행

웹 로그, IPS,IDS

 

SQL 구문 삽입 

SQL구문 삽입을 통한 DB접근

웹 로그, IPS,IDS, DB로그

 

SQL 구문 삽입을 통한 인가되지 않은 로그인을 성공한 후 관리자 페이지 등 내부 정보 접근

웹 로그, IPS,IDS

정보 유출 

파일 업로드

웹셸을 업로드해 내부 정보 다운로드

웹 로그, IPS,IDS

입력 값 검증 부재

파라미터 조작을 이용한 허가되지 않은 파일 다운로드

웹 로그, IPS,IDS

XSS

XSS를 이용한 관리자 로그인 정보 획득 후 관리자 페이지 등 내부 정보 접근

웹 로그, IPS,IDS

허가 되지 않은 접근 

터미널 서비스를 이용한 원격 접근

시스템 로그, 방화벽

RPC를 이용한 원격 접근

IPS,IDS messages,방화벽, loginlog, utmp, wtmp, last 로그, SU 로그

텔넷, FTP등 inet 서비스를 이용한 원격 접근

IPS,IDS messages,방화벽, loginlog, utmp, wtmp, last 로그, SU 로그

취약한 ID/패스워드를 유추해 관리자 페이지 접근

웹 로그, IPS, IDS

서비스 거부 

N/A 

SYN 플러딩

방화벽, IDS, ESM, messages

ICMP/UDP 플러딩

방화벽, IDS, ESM

TCP 플러딩

방화벽, IDS, ESM, messages

HTTP Get 플러딩

방화벽, IDS, 웹 접근 로그

HTTP CC 플러딩

방화벽, IDS, 웹 접근 로그

HTTP Post 플러딩

방화벽, IDS, 웹 접근 로그

HTTP SQL 플러딩

방화벽, IDS, 웹 접근 로그

컨넥션 플러딩

방화벽, IDS, 웹 접근 로그

 

반응형

'프로젝트 관련 조사 > 로그 관련' 카테고리의 다른 글

유닉스 계열 로그  (0) 2015.10.16
Access Log 관련  (0) 2015.10.16
elasticsearch로 로그 검색 시스템 만들기  (0) 2015.10.15
logstash conf 설정 - 기초  (0) 2015.10.15
logstash 레퍼런스  (0) 2015.10.15
반응형

출처: http://d2.naver.com/helloworld/273788

 

elasticsearch는 Shay Banon이 Lucene을 바탕으로 개발한 분산 검색엔진입니다. 설치와 서버 확장이 매우 편리하기 때문에 개발하고 있는 시스템에 검색 기능이 필요하다면 elasticsearch를 적용하는 것을 권장하고 싶습니다. 분산 시스템이기 때문에 검색 대상 용량이 증가했을 때 대응하기가 무척 수월하다는 것이 장점입니다.

이 글에서는 참고 자료의 내용을 바탕으로 기본적인 elasticsearch의 설치와 사용법을 설명하고, 실제 서비스에 적용할 때 고려해야 할 사항을 정리했습니다.

elasticsearch의 특징

우선 관계형 데이터베이스에 익숙한 사람들을 위해 관계형 데이터베이스와 elasticsearch의 용어를 비교한 표를 참고 자료에서 인용했다.

표 1 관계형 데이터베이스와 elasticsearch 용어 비교

관계형 데이터베이스 elasticsearch
Database Index
Table Type
Row Document
Column Field
Schema Mapping
Index Everything is indexed
SQL Query DSL

JSON 기반의 스키마 없는 저장소

elasticsearch는 검색엔진이지만, NoSQL처럼 사용할 수 있다. 데이터 모델을 JSON으로 사용하고 있어서, 요청과 응답을 모두 JSON 문서로 주고받고 소스 저장도 JSON 형태로 저장한다. 스키마를 미리 정의하지 않아도, JSON 문서를 넘겨주면 자동으로 인덱싱한다. 숫자나 날짜 등의 타입은 자동으로 매핑한다.

Multi-tenancy

elasticsearch는 multit-enancy를 지원한다. 하나의 elasticsearch 서버에 여러 인덱스를 저장하고, 여러 인덱스의 데이터를 하나의 쿼리로 검색할 수 있다. <예제 1>의 경우 날짜별로 인덱스를 분리해 로그를 저장하고 있고, 검색 시에는 검색 범위에 있는 날짜의 인덱스를 하나의 쿼리로 요청하고 있다.

예제 1 Multi-tenency 예제 쿼리

# log-2012-12-26 인덱스에 로그 저장
curl -XPUT http://localhost:9200/log-2012-12-26/hadoop/1 -d '{  
    "projectName" : "hadoop",
    "logType": "hadoop-log",
    "logSource": "namenode",
    "logTime":"2012-12-26T14:12:12",
    "host": host1",
    "body": "org.apache.hadoop.hdfs.StateChange: DIR* NameSystem.completeFile"
}'

# log-2012-12-27 인덱스에 로그 저장
curl -XPUT http://localhost:9200/log-2012-12-27/hadoop/1 -d '{  
    "projectName" : "hadoop",
    "logType": "hadoop-log",
    "logSource": "namenode",
    "logTime":"2012-12-27T02:02:02",
    "host": "host2",
    "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
}'

# log-2012-12-26, log-2012-12-27 인덱스에 한번에 검색 요청
curl -XGET http://localhost:9200/ log-2012-12-26, log-2012-12-27/_search  

확장성과 유연성

elasticsearch는 확장성과 유연성이 매우 뛰어나다. 플러그인을 이용해 기능을 확장할 수 있다. 예를 들어 Thrift 플러그인이나 Jetty 플러그인을 사용하면 전송 프로토콜을 변경할 수 있다. 필수 플러그인이라고 할 수 있는 BigDesk나 Head를 설치하면 elasticsearh 모니터링 기능을 사용할 수 있게 된다. <예제 2>에서 보는 것처럼 동적으로 복제본 개수를 조정할 수도 있다. 다만 샤드 수는 인덱스별로 고정돼 있어 수정이 불가능하므로 노드 수와 향후 서버 확장을 고려해 초기에 적절한 수를 할당해야 한다.

예제 2 설정 변경 쿼리

$ curl -XPUT http://localhost:9200/log-2012-12-27/ -d '{
    "settings" : {
        "number_of_shards" : 10,
        "number_of_replicas" : 1
    }
}'

분산 저장소

elasticsearch는 분산 검색엔진이다. 키에 따라 여러 샤드가 구성되는 방식으로 데이터를 분산한다. 인덱스는 각각의 샤드마다 구성된다. 각각의 샤드는 0개 이상의 복제본을 가진다. elasticsearch는 클러스터링을 지원하며 클러스터가 가동될 때 여러 노드 중 하나가 메타데이터 관리를 위한 마스터 노드로 선출된다. 마스터 노드가 다운되면 자동으로 클러스터 내의 다른 노드가 마스터가 된다. 노드 추가 또한 매우 간단하다. 같은 네트워크에 노드를 추가하는 경우 추가된 노드가 멀티캐스트를 이용해 자동으로 클러스터를 찾아 자신을 추가한다. 같은 네트워크를 이용하지 않을 경우 유니캐스트로 마스터 노드의 주소를 명시해 주어야 한다(참고 영상:http://youtu.be/l4ReamjCxHo).

설치하기

Quick Start

elasticsearch는 무설정 설치가 가능하다. <예제 3>에서 볼 수 있는 것 처럼 공식 홈페이지에서 파일을 내려 받아 압축을 해제하기만 하면 바로 실행해 볼 수 있다.

  1. 다운로드
$ wget http://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.20.4.tar.gz
$ tar xvzf elasticsearch-0.20.4.tar.gz
  1. 서버 실행

예제 3 설치 및 실행 명령

$ bin/elasticsearch -f

플러그인 설치

elasticsearch는 플러그인을 통해 쉽게 기능을 확장할 수 있다. 관리 기능을 추가하거나 Lucene의 Analyzer를 변경하고 기본 전송 모듈을 Netty에서 Jetty로 변경하는 것도 가능하다. <예제 4>는 플러그인을 설치하기 위한 명령어다. <예제 4>의 첫 번째와 두 번째 줄에서 보이는 'head'와 'bigdesk'는 elasticsearch 모니터링을 위한 필수 플러그인이므로 꼭 설치해서 기능을 확인해 보도록 하자. 설치 후 http://localhost:9200/_plugin/head/http://localhost:9200/_plugin/bigdesk/ 로 접속하면 웹 브라우저를 이용해 상태를 확인해 볼 수 있다.

예제 4 플러그인 설치

bin/plugin -install Aconex/elasticsearch-head  
bin/plugin -install lukas-vlcek/bigdesk  
bin/plugin -install elasticsearch/elasticsearch-transport-thrift/1.4.0  
bin/plugin -url https://oss-es-plugins.s3.amazonaws.com/elasticsearch-jetty/elasticsearch-jetty-0.20.1.zip -install elasticsearch-jetty-0.20.1  

주요 설정

간단한 기능 테스트에는 설정 변경이 필요 없으나, 성능 테스트를 하거나 실서비스에 적용할 때에는 기본 설정에 대한 몇 가지 변경이 필요하다. <예제 5>를 참고하면 초기 설정 파일(elasticsearch.yml)에서 변경해야 할 설정 내용이 무엇인지 알 수 있다.

예제 5 주요 설정(config/elasticsearch.yml)

# 클러스터를 식별하기 위한 이름이므로 유일성과 의미를 가진 이름을 사용하자
cluster.name: es-cluster

# 노드 이름은 자동으로 생성되지만 호스트명과 같이 클러스터 내에서 식별 가능한 이름을 활용하는 것이 좋다.
node.name: "es-node1"

# 기본값은 아래 두 값이 모두 true다. node.master는 노드가 마스터가 될 수 있지에 대한 설정이고, node.data는 데이터를 저장하는 노드인지에 대한 설정이다. 보통은 두 값을 true로 설정하면 되고, 클러스터의 규모가 큰 경우에는 3가지 종류의 노드를 구성하기 위해 이 값을 노드별로 조정해 설정한다. 자세한 사항은 토폴로지(topology) 설정에서 다시 설명하겠다.
node.master: true  
node.data: true

# 샤드와 리플리카 수를 변경하는 설정이다. 아래 값은 기본값이다. 
index.number_of_shards: 5  
index.number_of_replicas: 1



#JVM의 스왑을 방지하려면 아래 설정 값을 true로 한다.
bootstrap.mlockall: true

# 클러스터 내의 각 노드의 상태 체크를 위한 타임아웃 값으로, 너무 작게 하면 노드가 클러스터에서 자주 이탈하는 문제가 발생할 수 있어 적절한 값을 설정한다. 기본값은 3초다.
discovery.zen.ping.timeout: 10s

# 기본값은 멀티캐스트를 사용하지만, 실환경에서는 다른 클러스터와 노드가 섞이는 위험이 발생할 수 있으므로 유니캐스트를 사용하고 두 번째 설정 값에 마스터가 될 수 있는 서버들의 목록을 나열하는 것이 좋다.
discovery.zen.ping.multicast.enabled: false  
discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"]  

REST API 사용하기

elasticsearch는 <예제 6>과 같은 형식의 REST API를 제공한다. 인덱스 생성과 삭제, 매핑 생성과 삭제, 검색, 설정 변경 등 대부분의 기능을 REST API를 통해 제공한다. REST API 이외에도 Java, Python, Ruby 등의 언어별 클라이언트도 제공하고 있다.

예제 6 REST API 형식

http://host:port/(index)/(type)/(action|id)  

<예제 7>의 경우 날짜별로 인덱스를 분리하고, 프로젝트별로 타입을 나누어 관리하고 있다. 2012년 12월 27일에 hadoop이라는 프로젝트로 들어온 로그를 문서 단위로 생성하는 과정을 REST API를 사용해 수행하는 예다.

예제 7 REST API 사용 예

#문서 생성
curl -XPUT http://localhost:9200/log-2012-12-27/hadoop/1  
curl -XGET http://localhost:9200/log-2012-12-27/hadoop/1  
curl -XDELETE http://localhost:9200/log-2012-12-27/hadoop/1

#검색
curl -XGET http://localhost:9200/log-2012-12-27/hadoop/_search  
curl -XGET http://localhost:9200/log-2012-12-27/_search  
curl -XGET http://localhost:9200/_search

#인덱스 상태 보기
curl -XGET http://localhost:9200/log-2012-12-27/_status  

문서와 인덱스 생성

<예제 8>에서처럼 요청을 보내면 인덱스와 타입이 정의돼 있지 않더라도 elasticsearch는 자동으로 log-2012-12-27 인덱스와 hadoop 타입을 생성한다. 자동으로 생성하지 않고 명시적으로 생성하려면 설정 파일에서 action.auto_create_index와 index.mapper.dynamic의 설정 값을 false로 명시해야 한다.

예제 8 문서 생성

# 요청
curl -XPUT http://localhost:9200/log-2012-12-27/hadoop/1 -d '{  
    "projectName" : "hadoop",
    "logType": "hadoop-log",
    "logSource": "namenode",
    "logTime":"2012-12-27T02:02:02",
    "host": "host2 ",
    "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
}'

# 결과
{
    "ok" : true,
    "_index" : "log-2012-12-27",
    "_type" : "hadoop",
    "_id" : "1",
    "_version" : 1
}

<예제 9>에서 보는 것처럼 타입을 문서에 포함해 요청할 수 있다.

예제 9 타입을 포함한 쿼리

curl -XPUT http://localhost:9200/log-2012-12-27/hadoop/1 -d '{  
    "hadoop" : {
        "projectName" : "hadoop",
        "logType": "hadoop-log",
        "logSource": "namenode",
        "logTime":"2012-12-27T02:02:02",
        "host": "host2 ",
        "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
    }
}'

<예제 10>과 같이 ID 값을 생략하면 자동으로 ID를 생성하고 문서를 만든다. 요청 시 PUT 대신 POST 방식을 사용한 것에 주의하자.

예제 10 ID 없는 문서 생성 쿼리

# 요청
curl -XPOST http://localhost:9200/log-2012-12-27/hadoop/ -d '{  
    "projectName" : "hadoop",
    "logType": "hadoop-log",
    "logSource": "namenode",
    "logTime":"2012-12-27T02:02:02",
    "host": "host2 ",
    "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
}'

# 결과
{
    "ok" : true,
    "_index" : "log-2012-12-27",
    "_type" : "hadoop",
    "_id" : "kgfrarduRk2bKhzrtR-zhQ",
    "_version" : 1
}

문서 삭제

<예제 11>은 문서를 삭제하는 방법을 보여 주고 있다. DELETE 메서드를 사용해 log-2012-12-27 인덱스에서 타입이 hadoop이고 ID가 1인 문서를 삭제한다.

예제 11 문서 삭제 쿼리

# 요청
$ curl -XDELETE 'http://localhost:9200/log-2012-12-27/hadoop/1'

# 결과
{
    "ok" : true,
    "_index" : "log-2012-12-27",
    "_type" : "hadoop",
    "_id" : "1",
    "found" : true
}

문서 가져오기

<예제 12>와 같이 GET 메서드를 사용하면 log-2012-12-27 인덱스에서 타입이 hadoop이고 ID가 1인 문서를 가져올 수 있다.

예제 12 문서를 가져오기 위한 쿼리

#요청
curl -XGET 'http://localhost:9200/log-2012-12-27/hadoop/1'

# 결과
{
    "_index" : "log-2012-12-27",
    "_type" : "hadoop",
    "_id" : "1", 
    "_source" : {
        "projectName" : "hadoop",
        "logType": "hadoop-log",
        "logSource": "namenode",
        "logTime":"2012-12-27T02:02:02",
        "host": "host2 ",
        "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
    }
}

검색

검색 API를 호출하면 elasticsearch는 검색 API를 실행한 후 질의 내용과 일치하는 검색 결과를 반환한다. <예제 13>에서 검색 API를 사용하는 예제를 볼 수 있다.

예제 13 검색 API 사용 예제 쿼리

# 특정 인덱스의 모든 타입
$ curl -XGET 'http://localhost:9200/log-2012-12-27/_search?q=host:host2'

# 특정 인덱스의 특정 타입
$ curl -XGET 'http://localhost:9200/log-2012-12-27/hadoop,apache/_search?q=host:host2'

# 모든 인덱스의 특정 타입
$ $ curl - XGET 'http://localhost:9200/_all/hadoop/_search?q=host:host2'

# 모든 인덱스와 타입
$ curl -XGET 'http://localhost:9200/_search?q=host:host2'

URI 요청을 사용한 검색 API

URI를 사용하면 <표 2>의 파라미터와 쿼리 스트링(Query String)으로 간단하게 검색할 수 있다. 모든 검색 옵션을 제공하지는 않으므로 주로 테스트 용도로 간편하게 사용할 때 유용하다.

표 2 주요 파라미터들

이름 설명
q 쿼리 스트링
default_operator 기본으로 사용할 연산자(AND 혹은 OR). 기본값은 OR.
fields 결과로 가져올 필드. 기본값은 '_source' 필드.
sort 정렬 방법(예: fieldName:asc/fieldName:desc)
timeout 검색 수행 타임아웃 값. 기본값은 무제한.
size 결과 값의 개수. 기본값은 10.

예제 14 URI 요청을 사용한 검색 쿼리

# 요청
$ curl -XGET 'http://localhost:9200/log-2012-12-27/hadoop/_search?q=host:host2'

# 결과
{
    "_shards":{
        "total" : 5,
        "successful" : 5,
        "failed" : 0
    },
    "hits":{
        "total" : 1,
        "hits" : [
            {
                "_index" : "log-2012-12-27",
                "_type" : "hadoop",
                "_id" : "1", 
                "_source" : {
                    "projectName" : "hadoop",
                    "logType": "hadoop-log",
                    "logSource": "namenode",
                    "logTime":"2012-12-27T02:02:02",
                    "host": "host2",
                    "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
                }
            }
        ]
    }
}

요청 바디(Request Body)를 사용한 검색 API

HTTP 바디를 사용할 경우 Query DSL을 사용해서 검색한다. Query DSL은 내용이 방대하므로 공식 사이트의 가이드 문서(http://www.elasticsearch.org/guide/reference/query-dsl/) 를 참고하도록 하자.

예제 15 Query DSL을 사용한 검색

# 요청
$ curl -XPOST 'http://localhost:9200/log-2012-12-27/hadoop/_search' -d '{
    "query" : {
        "term" : { "host" : "host2" }
    }
}
'

# 결과
{
    "_shards":{
        "total" : 5,
        "successful" : 5,
        "failed" : 0
    },
    "hits":{
        "total" : 1,
        "hits" : [
            {
                "_index" : "log-2012-12-27",
                "_type" : "hadoop",
                "_id" : "1",
                "_source" : {
                    "projectName" : "hadoop",
                    "logType": "hadoop-log",
                    "logSource": "namenode",
                    "logTime":"2012-12-27T02:02:02",
                    "host": "host2",
                    "body": "org.apache.hadoop.hdfs.server.namenode.FSNamesystem"
                }
            }
        ]
    }
}

Mapping

Put Mapping API

특정 타입에 매핑을 추가하려면 <예제 16>과 같은 형태로 정의할 수 있다.

예제 16 매핑을 등록하기 위한 쿼리

$ curl -XPUT 'http://localhost:9200/log-2012-12-27/hadoop/_mapping' -d '
{
    "hadoop" : {
        "properties" : {
            "projectName" : {"type" : "string", "index" : "not_analyzed"},
            "logType" : {"type" : "string", "index" : "not_analyzed"},
            "logSource" : {"type" : "string", "index" : "not_analyzed"},
            "logTime" : {"type" : "date"},
            "host" : {"type" : "string", "index" : "not_analyzed"},
            "body" : {"type" : "string"},
        }
    }
}
'  

Get Mapping API

정의한 매핑 정보를 얻기 위해서 <예제 17>과 같은 형태의 쿼리를 사용할 수 있다.

예제 17 매핑을 얻어오기 위한 쿼리

$ curl -XGET 'http://localhost:9200/log-2012-12-27/hadoop/_mapping'

Delete Mapping API

<예제 18>은 정의한 매핑을 삭제하는 예다.

예제 18 매핑을 삭제하기 위한 쿼리

$ curl -XDELETE 'http://localhost:9200/log-2012-12-27/hadoop'

성능 최적화 팁

메모리와 오픈 파일 수

검색할 데이터가 많아질수록 많은 메모리가 필요하다. elasticsearch를 운영하다 보면 메모리 사용으로 인한 문제를 많이 겪게 된다. elasticsearch 커뮤니티에서 권장하는 운영 방법에 따르면, elasticsearch 전용 서버를 운영할 때는 메모리 용량의 절반만 elasticsearch에 할당하고, 나머지 메모리 용량은 운영체제가 시스템 캐시 목적으로 사용할 수 있도록 하는 것이 좋다. 메모리 크기는 ES_HEAP_SIZE 환경 변수를 설정하거나 JVM의 -Xms와 -Xmx 값을 사용해서 설정할 수 있다.

예제 19 힙 크기를 지정해 실행

bin/ElasticSearch -Xmx=2G -Xms=2G  

elasticsearch를 사용할 때는 OOME(Out Of Memory Error)가 발생하는 경우가 많다. 필드 캐시가 최대 힙 크기를 넘어서면서 발생하는데, index.cache.field.type 설정을 기본값인 resident 대신 soft로 설정하면 soft 레퍼런스를 활용하므로 캐시 영역에 대해 우선 가비지 컬렉션(Garbage Collection)을 실행해 문제를 해결할 수 있다.

예제 20 필드 캐시 타입 설정

index.cache.field.type: soft  

데이터가 많아지면 인덱스 파일 개수 또한 증가하게 된다. elasticsearch가 사용하고 있는 Lucene에서 인덱스를 세그먼트 단위로 관리하기 때문이다. 경우에 따라 MAX_OPEN 파일 개수를 넘어서는 일도 발생한다. ulimit 명령으로 최대 오픈 파일 제한을 변경해야 한다. 권장되는 값은 32000~64000이지만, 시스템 규모나 데이터의 양에 따라 더 큰 값으로 설정해야 할 수도 있다.

인덱스 최적화

날짜별로 인덱스를 관리하면 <예제 21>에서 보는 것처럼 관리가 필요 없는 오래된 로그를 쉽고 빠르게 삭제할 수 있어서, 문서별로 TTL 값을 설정해 삭제하는 것 보다 시스템에 주는 오버헤드가 적다.

예제 21 인덱스 삭제

$ curl -XDELETE 'http://localhost:9200/log-2012-10-01/'

인덱스 최적화(Index Optimization)를 수행하면 세그먼트를 병합시킨다. 이러한 방식으로 검색 성능을 향상시킬 수 있다. 다만 시스템에 부담을 주므로 시스템 사용이 적은 시간대에 작업하도록 해야 한다.

예제 22 인덱스 최적화

$ curl -XPOST 'http://localhost:9200/log-2012-10-01/_optimize'

샤드와 복제본

샤드 개수는 초기에 설정한 다음에는 변경이 불가능하므로 현재 시스템의 노드 수와 추후 발생할 수 있는 노드 증가를 고려해 정해야 한다. 예를 들어 현재 5개의 노드가 있고 향후 10개까지 노드를 증가시킬 계획이라면, 초기부터 샤드 수를 10개로 지정하는 것이 좋다. 초기에 5개로 지정하면 이후 노드를 10개로 증가시켜도 샤드는 5개이므로 5개의 노드는 활용할 수 없게 된다. 물론 복제본 수를 1로 지정했다면 추가한 5개 노드를 복제 전용 노드로 활용할 수 있다.

샤드 수를 늘리면 질의가 샤드 개수만큼 분산되므로 많은 데이터 처리에 유리하게 되지만, 너무 크게 설정하면 오히려 트래픽이 증가해 성능이 떨어질 수 있으니 적절하게 설정해야 한다.

클러스터 토폴로지 구성

elasticsearch의 설정 파일에는 <예제 23>과 같은 내용을 볼 수 있다. <예제 23>을 보면 세 가지 종류의 노드(데이터 노드, 마스터 노드, 검색 밸런서 노드)가 있음을 알 수 있다.

  • 데이터 노드: 마스터 역할을 수행하지 않고, 데이터만 저장한다. 클라이언트로부터의 요청이 왔을 때 샤드에서 데이터를 검색하거나 인덱스를 생성한다.
  • 마스터 노드: 클러스터를 유지하기 위한 역할을 하고 인덱싱이나 검색 요청을 데이터 노드들에 요청한다.
  • 검색 로드 밸런서 노드: 검색 요청이 오면 노드들에 데이터를 요청 후 취합해 결과를 전달한다.

하나의 노드가 마스터와 데이터 노드 역할을 다 하도록 운영할 수도 있으나, 세 가지 형태의 노드를 각각 사용하면 데이터 노드의 부담을 줄일 수 있다. 또한 마스터 노드를 별도로 구성하면 클러스터의 안정성을 높일 수 있다. 게다가 마스터 노드와 검색 노드는 저사양의 서버 장비를 활용할 수 있도록 해 운영 비용 또한 줄일 수 있다.

예제 23 토폴로지 관련 설정 내용

# You can exploit these settings to design advanced cluster topologies.
#
# 1. You want this node to never become a master node, only to hold data.
#    This will be the "workhorse" of your cluster.
#
# node.master: false
# node.data: true
#
# 2. You want this node to only serve as a master: to not store any data and
#    to have free resources. This will be the "coordinator" of your cluster.
#
# node.master: true
# node.data: false
#
# 3. You want this node to be neither master nor data node, but
#    to act as a "search load balancer" (fetching data from nodes,
#    aggregating results, etc.)
#
# node.master: false
# node.data: false

라우팅 설정

인덱싱할 데이터가 많으면 샤드의 수를 늘리는 것이 전체적인 성능을 증가시킬 수 있지만, 샤드의 개수를 증가시키는 만큼 노드 간의 트래픽이 증가한다는 문제점이 있다. 예를 들어 샤드가 100개면 하나의 검색 요청이 왔을 때 100개의 샤드에 모두 요청을 보내 데이터를 취합하는 형식이기 때문에 전체 클러스터에 부담이 된다. 라우팅을 사용하면 특정 샤드에만 데이터가 저장되어 샤드 수가 아무리 커져도 1개의 샤드에만 요청을 보내게 되므로 트래픽을 극적으로 줄일 수 있다. <그림 2>와 <그림 3>, <그림 4>는 Rafal Kuc이 Berlin Buzzwords 2012에서 발표한 자료에서 인용한 것이다. 라우팅을 사용하지 않으면 <그림 2>와 같이 전체 샤드에 모두 요청을 보내지만 라우팅을 사용하면 <그림 3>과 같이 특정 샤드에만 요청을 보내는 것을 볼 수 있다. <그림 4>에서 인용한 자료에 따르면 200개의 샤드에서 라우팅 사용 전과 후의 성능을 비교 했을 때 반응 시간이 10배 이상 차이 나는 것을 볼 수 있다. 라우팅을 적용하면 적용하지 않은 경우외 비교해 스레드 개수가 10~20배 증가하지만 CPU 사용률은 훨씬 적은 것을 볼 수 있다. 하지만 경우에 따라 라우팅을 적용하지 않은 것이 성능이 더 좋을 때도 있다. 여러 샤드로부터 결과가 취합되어야 하는 검색 질의에 대해서는 여러 샤드에 요청이 전달되는 것이 성능상 유리할 수 있다.

elasticsearch1

그림 2 라우팅 사용 전

elasticsearch2

그림 3 라우팅 사용 후

elasticsearch3

그림 4 라우팅 사용 전/후의 성능 비교

마무리

elasticsearch는 유용한 기능뿐만 아니라 간단한 설치와 높은 확장성때문에 사용자를 빠르게 늘려가고 있다. 버전 숫자로만 본다면 최근(2013년 1월 기준)에 0.20.4 버전이 나온 정도지만 커뮤니티가 활발하기 때문에 빠르게 기능이 개선되고 있다. 또한 점점 더 많은 회사에서 elasticsearch를 자사의 서비스에 사용하고 있다. 최근에는 개발자인 Shay Banon을 포함한 커미터들이 모여 Elasticsearch.com을 만들어 컨설팅과 교육을 제공하고 있다. 이번 글에서는 기본적인 설치와 사용 방법, 성능 튜닝을 위한 내용을 정리했다. 많은 개발자들에게 도움이 되길 바란다.

참고 자료

반응형

'프로젝트 관련 조사 > 로그 관련' 카테고리의 다른 글

Access Log 관련  (0) 2015.10.16
해킹사고의 취약점과 관련된 로그  (0) 2015.10.16
logstash conf 설정 - 기초  (0) 2015.10.15
logstash 레퍼런스  (0) 2015.10.15
log4j 관련  (0) 2015.10.15

+ Recent posts