본문 바로가기
프로그램 (PHP,Python)

Lucene 기반 Elasticsearch Text vs Keyword 필드 타입 쿼리 최적화

by 날으는물고기 2025. 7. 30.

Lucene 기반 Elasticsearch Text vs Keyword 필드 타입 쿼리 최적화

728x90

Text 필드 (Analyzed Field)

  • 텍스트를 토큰으로 분리하여 저장
  • 전문 검색(Full-text search)에 최적화
  • 대소문자 변환, 형태소 분석 등 텍스트 처리 수행
// 원본: "Hello World 2024"
// 저장: ["hello", "world", "2024"]  // 토큰화 + 소문자 변환

Keyword 필드

  • 전체 문자열을 하나의 단위로 저장
  • 정확한 일치, 정렬, 집계에 최적화
  • 원본 그대로 저장 (대소문자 유지)
// 원본: "Hello World 2024"
// 저장: "Hello World 2024"  // 그대로 저장

토큰화 과정 상세 분석

1. Standard Analyzer 동작 방식

GET /_analyze
{
  "text": "web-prod-ab12-server.company.com",
  "analyzer": "standard"
}

// 결과:
{
  "tokens": [
    {"token": "web"},
    {"token": "prod"},
    {"token": "ab12"},
    {"token": "server"},
    {"token": "company"},
    {"token": "com"}
  ]
}

2. 토큰 분리 규칙

  • 구분자: 공백, 하이픈(-), 언더스코어(_), 점(.), 슬래시(/) 등
  • 영문+숫자: 기본적으로 분리하지 않음 (ab12는 하나의 토큰)
  • 대소문자: 모두 소문자로 변환
300x250

검색 방법별 차이점

1. Text 필드 검색

# 기본 검색 (토큰 매칭)
columns.cmdline:"base64"
→ "sudo base64 -d /tmp/file" ✅ (base64 토큰 존재)
→ "mybase64tool" ✅ (토큰에 base64 포함)

# 와일드카드 (토큰 단위)
columns.cmdline:"*base64*"
→ base64를 포함하는 토큰이 있는 모든 문서

2. Keyword 필드 검색

# 정확한 일치
columns.cmdline.keyword:"base64 -d"
→ "base64 -d" ✅
→ "sudo base64 -d" ❌ (전체가 일치하지 않음)

# 와일드카드 (전체 문자열)
columns.cmdline.keyword:*base64*
→ "sudo base64 -d /tmp/file" ✅
→ "base64" ✅

와일드카드와 따옴표 규칙

1. 따옴표의 역할

# 따옴표 없음: 와일드카드로 해석
field:*abc*      → abc를 포함하는 모든 값

# 따옴표 있음: 리터럴 문자로 해석
field:"*abc*"    → 정확히 "*abc*" 문자열

# 공백 포함 시 따옴표 필요 (Text 필드)
field:"hello world"  → 구문 검색

# Keyword 필드에서 공백 포함 와일드카드
field.keyword:*hello\ world*  → 공백 이스케이프

2. 복잡한 패턴 예시

# Text 필드 - 여러 패턴 OR 검색
+columns.cmdline:("base64 -d" "chmod +x" "nc -l")

# Keyword 필드 - 이스케이프 필요
+columns.cmdline.keyword:(*base64\ -d* *chmod\ +x* *nc\ -l*)

실전 시나리오별 검색 방법

1. 보안 이벤트 탐지

# Text 필드 사용 (권장) - 더 많은 변형 탐지
+columns.cmdline:(
  "*base64 -d /tmp/*"
  "*chmod +x /tmp/*"
  "*nc -l -p*"
)

# Keyword 필드 사용 - 정확한 패턴만
+columns.cmdline.keyword:(
  *base64\ -d\ /tmp/*
  *chmod\ +x\ /tmp/*
)

2. 호스트명 제외

# 문제 상황
-decorations.hostname:web-prod-ab12*
→ "web-prod-ab123" 도 제외될 수 있음 (토큰 매칭)

# 해결책 1: Keyword 필드 사용
-decorations.hostname.keyword:"web-prod-ab12"

# 해결책 2: 정규표현식
-decorations.hostname.keyword:/^web-prod-ab12$/

# 해결책 3: 더 구체적인 패턴
-decorations.hostname.keyword:"web-prod-ab12.*"

3. 복합 조건 검색

# curl 명령어 + 파일 다운로드 탐지
+columns.cmdline:curl 
+columns.cmdline:(file zip gz tar)
→ curl이 포함되고 AND (file OR zip OR gz OR tar) 포함

# 정확한 명령어 순서 필요 시
+columns.cmdline.keyword:"*curl -o*"
+columns.cmdline.keyword:"*wget --output-document*"

성능과 정확도 트레이드오프

1. Text 필드

장점

  • 유연한 검색
  • 변형된 패턴 탐지 용이
  • 부분 매칭 자동 지원

단점

  • 의도하지 않은 매칭 가능
  • 정확한 통제 어려움

2. Keyword 필드

장점

  • 정확한 매칭
  • 예측 가능한 결과
  • 집계/정렬에 효율적

단점

  • 모든 변형 직접 지정 필요
  • 와일드카드 사용 복잡

디버깅 방법

1. 토큰 분석

// 특정 인덱스의 필드 분석
GET /your-index/_analyze
{
  "text": "test-string-123",
  "field": "your.field.name"
}

// Standard analyzer로 직접 테스트
GET /_analyze
{
  "text": "test-string-123",
  "analyzer": "standard"
}

2. 실제 매칭 확인

// 어떤 문서가 매칭되는지 확인
GET /your-index/_search
{
  "query": {
    "wildcard": {
      "decorations.hostname": "web-prod-ab12*"
    }
  },
  "_source": ["decorations.hostname"],
  "highlight": {
    "fields": {
      "decorations.hostname": {}
    }
  }
}

권장사항

1. 필드 타입 선택 가이드

  • 로그 메시지, 명령어: Text 필드
  • ID, 이메일, URL, 호스트명: Keyword 필드
  • 불확실한 경우: 둘 다 인덱싱 (multi-field)

2. 보안 모니터링 베스트 프랙티스

# 1. 넓은 범위로 시작 (Text 필드)
+columns.cmdline:("base64" "wget" "curl")

# 2. 노이즈 제거
-decorations.hostname.keyword:("trusted-server-01" "trusted-server-02")

# 3. 필요시 정확한 패턴 추가 (Keyword 필드)
+columns.cmdline.keyword:"/bin/bash -i >& /dev/tcp/*"

이러한 이해를 바탕으로 상황에 맞는 적절한 필드 타입과 검색 방법을 선택하면 효과적인 로그 분석과 보안 모니터링이 가능합니다.

728x90
그리드형(광고전용)

댓글