Notice
Recent Posts
Recent Comments
Link
jyamethyst21 님의 블로그
생성형 AI를 활용한 AI 보안관제 및 통합로그분석(Splunk 관련) 본문
데이터 저장 구조
- 인덱스 = MySQL의 테이블과 동일한 개념 (용어만 다름)
- 인덱스 내부 버킷 구조 : Hot → Warm → Cold → Frozen 순으로 이동
- 기본 데이터 보관 주기 : 6년
- 기본 인덱스 용량 : 500GB (초과 시 오래된 데이터부터 자동 삭제)
데이터 수집 방법
업로드
- 파일을 직접 업로드하는 일회성 분석 방식
- 최대 500MB 제한
모니터
- 지정 경로의 파일 변경을 실시간으로 자동 감시
- 지속적인 로그 수집이 필요할 때 사용
포워더
- Universal Forwarder를 원격 서버에 설치해서 중앙 인덱서로 전송
- 에이전트 방식이라 원격 서버 로그 수집에 주로 활용
HTTP Event Collector(HEC)
- REST API 방식으로 애플리케이션에서 직접 이벤트 전송
- 요즘 클라우드 환경에서 많이 쓰는 방식
스크립트 입력
- 커스텀 스크립트를 주기적으로 실행해서 그 출력값을 수집
Syslog
- 네트워크 장비, 리눅스 서버 등에서 syslog 프로토콜로 직접 수신
소스 타입
- 데이터 유형별로 필드 분류 규칙을 미리 정의해 놓은 것
- 아파치 웹로그 : access_combined 소스 타입 자동 적용
- 아파치 로그는 자동 소스 타입 선택, 세밀한 필드 분류, 시간 필드 자동 인식 지원
- 그 외 로그는 수동 설정이 필요한 경우가 많음
- 전처리 설정 파일 : props.conf + transforms.conf
DB 연동 (DB Connect 앱)
- DB Connect 앱 설치 필요 (Splunkbase에서 다운로드)
- Java(JDK) 필수 : JDK 경로를 DB Connect 설정에서 지정해줘야 함
- MySQL 사용 시 mysql-connector-java-xxx.jar 드라이버를 /drivers/ 폴더에 복사
- 재시작 후 드라이버 인식 확인
지원 DB
- Oracle, MySQL, PostgreSQL, MSSQL, DB2 등 JDBC 지원 DB 대부분 연결 가능
연결 설정 3단계
- Identity : DB 접속 계정 정책 등록
- Connection : DB 서버 IP, 포트, DB명 지정
- Input : 수집할 쿼리문 작성 및 실행 주기 설정
수집 방식
- Batch : 매번 전체 데이터 수집 (중복 발생)
- Rising : 마지막 수집 시점 이후 신규 데이터만 수집 (중복 방지, 권장)
활용 예시
- 로그의 user_id를 DB 사용자 테이블과 조인해서 이름까지 함께 조회
- Snort 탐지 로그를 DB에서 직접 가져와 Splunk에서 분석
외부 시스템 연동
티켓 시스템
- 알림 조건 충족 시 Jira, ServiceNow, PagerDuty로 자동 티켓 생성 가능
Slack / 이메일
- 알림 액션으로 Slack 채널 또는 이메일 자동 발송 설정 가능
REST API
- Splunk 자체 REST API 완전 지원
- 외부 시스템에서 Splunk 검색 실행 및 결과 수신 가능
Splunk 전용 앱 (Splunkbase)
- ITSI : IT 서비스 상태를 KPI 기반으로 모니터링하는 프리미엄 앱
- Enterprise Security(ES) : SIEM 특화 앱, 보안 이벤트 분석 / 위협 인텔리전스 연동 / 인시던트 관리 지원
알림 & 스케줄링
- 검색 쿼리를 저장하고 주기적으로 실행해서 조건에 맞으면 알림 발송
- 실시간 알림 : 이벤트 발생 즉시 트리거
- 스케줄 알림 : 매 5분, 매 시간, 매일 등 원하는 주기로 실행
- 알림 액션 : 이메일 / Slack / 웹훅 / 스크립트 실행 / 티켓 생성 등
대시보드 & 시각화
- 드래그앤드롭으로 패널 배치, 검색 쿼리 연결해서 실시간 대시보드 구성 가능
- 차트, 테이블, 지도, 게이지, 싱글밸류 등 다양한 시각화 타입 지원
- 토큰(Token) 기능으로 드롭다운, 입력 폼 만들어서 동적 필터링 가능
- Dashboard Studio (신버전) : JSON 기반, 더 유연한 레이아웃과 커스텀 디자인 지원
- 하나의 차트에서 최대 10,000개 데이터 포인트 처리 가능
머신러닝 (MLTK)
- Splunk Machine Learning Toolkit 앱 설치 필요
- 이상 탐지 / 예측(Forecasting) / 클러스터링을 SPL 안에서 바로 실행 가능
- fit 명령어로 모델 학습, apply 명령어로 모델 적용
| fit LinearRegression response_time from cpu_usage
| apply MyModel
권한 관리 & 클러스터 구성
- 역할(Role) 기반 접근 제어 지원
- 인덱스별, 앱별로 접근 권한 세밀하게 설정 가능
- Search Head Clustering : 여러 Search Head를 묶어 고가용성 구성
- Index Clustering : 인덱서를 클러스터로 구성해서 데이터 복제 및 이중화 처리
- 부서별로 인덱스를 나눠 데이터 격리 운영 가능
설정 파일 구조
주요 경로
- $SPLUNK_HOME/etc/apps/search/ : 검색 앱 설정
- $SPLUNK_HOME/etc/system/default/ : 시스템 기본 설정 (수정 비권장)
- $SPLUNK_HOME/etc/system/local/ : 사용자 커스텀 설정
핵심 설정 파일
- indexes.conf : 인덱스 보관 주기, 용량 제한 설정
- props.conf : 소스 타입별 전처리 규칙
- transforms.conf : 정규표현식 기반 필드 추출 규칙 (props.conf와 쌍으로 동작)
주요 SPL 명령어
검색 & 필터링
| search | 기본 키워드 검색, 첫 구문에서는 생략 가능 | search error |
| index= | 특정 인덱스 지정 | index=main sourcetype=syslog |
| host= | 특정 호스트 필터링 | host=webserver01 |
| source= | 특정 소스 파일 지정 | source=/var/log/auth.log |
| where | 조건식으로 필터링, 값에 큰따옴표 필수 | where status > 400 |
- search 명령에서는 대소문자 구분 없음, 와일드카드(*) 사용 가능
- where 등 다른 명령어에서는 값에 큰따옴표 필수, 대소문자 구분함
- AND는 자동 적용, OR / NOT은 명시적으로 입력 필요
필드 생성 & 가공
| eval | 새 필드 생성 또는 계산 | eval size_mb = size / 1024 / 1024 |
| rex | 정규식으로 필드 추출 | rex field=_raw "user=(?<username>\w+)" |
| rename | 필드 이름 변경 | rename src_ip AS 출발지IP |
| fields | 표시할 필드 지정 또는 제외 | fields host, status, uri |
| table | 결과를 테이블 형식으로 출력 | table _time, host, status |
- eval은 Splunk의 읽기 스키마 특성 덕분에 과거 데이터에도 즉시 적용 가능
- fields 명령으로 필요한 필드만 추리면 검색 성능 향상됨
집계 & 통계
| stats | 필드별 통계 계산 | stats count by host |
| chart | 다차원 통계, 두 번째 필드가 Y축 | chart avg(response_time) by host, status |
| timechart | 시간을 X축으로 고정한 시계열 차트 | timechart count by method |
| bin | 시간 간격 수동 조정 | bin _time span=12h |
| top | 가장 많이 등장하는 값 상위 출력 | top limit=10 uri |
| rare | 가장 적게 등장하는 값 출력 | rare src_ip |
| dedup | 중복 이벤트 제거 | dedup session_id |
| sort | 결과 정렬, -는 내림차순 | sort -count |
- timechart는 시간 필드를 자동으로 X축에 고정하고 계산 간격도 자동 조정
- span 옵션으로 수동 지정 가능 : timechart span=1h count by method
- dc() = distinct_count() 단축키, 고유 개수 측정에 사용
시간 관련
| earliest= / latest= | 검색 시간 범위 지정 | earliest=-1h latest=now |
| bucket | 시간을 구간으로 묶음 | bucket _time span=5m |
| now() | 현재 시각 반환 | eval cur_time = now() |
조인 & 서브서치
| join | 두 검색 결과를 특정 필드로 합침 | join user [search index=auth] |
| append | 두 검색 결과를 아래로 이어붙임 | append [search index=backup] |
| lookup | 외부 CSV 또는 KV Store와 데이터 매핑 | lookup user_info.csv user_id |
- 서브서치 : 대괄호 [...] 안에 보조 검색 작성 → 주 검색의 조건으로 동작
- SQL의 서브쿼리와 동일한 개념
index=apache_log
[search index=apache_log method=OPTIONS
| fields clientip]
| stats count by url
| sort -count
기타 명령어
| transaction | 관련 이벤트를 하나의 트랜잭션으로 그룹화 | transaction session_id |
| iplocation | IP 주소에서 지리 정보 추출 | iplocation src_ip |
| inputlookup | 룩업 파일 내용을 직접 검색 | inputlookup user_info.csv |
| outputlookup | 검색 결과를 룩업 파일로 저장 | outputlookup result.csv |
| makeresults | 테스트용 더미 이벤트 생성 | makeresults count=5 |
eval 함수 활용
필드값 결합
| eval info = method + " - " + status
조건 분기 (case)
| eval ua_type = case(
match(useragent, "(?i).*havij"), "공격도구",
match(useragent, "(?i)Mozilla[^ ]+ "), "일반브라우저",
true(), replace(useragent, "([^ /]+).*", "\1")
)
URL 디코딩 + 정규식 추출 중첩
| eval pattern = urldecode(replace(uri, "(?i).*?\+and\+(.+)", "\1"))
- case() : 조건에 따라 다른 값 할당, true()는 나머지 모든 경우의 기본값
- match() : 정규식 일치 여부 확인
- replace() : 전체 문자열 검사 후 치환, 캡처 그룹 + \1 역참조로 특정 구간 추출
자주 쓰는 쿼리 패턴
에러 로그 상위 URI 뽑기
index=web sourcetype=access_log status>=400
| stats count by uri
| sort -count
| head 10
시간대별 에러 추이
index=web error
| timechart span=1h count
고유 URL 개수 시계열 차트 (응답코드별)
index=apache_log
| timechart dc(url) by status
특정 사용자 로그인 실패 탐지
index=auth action=login status=fail
| stats count by user
| where count > 5
비정상 메소드 사용 IP 추적
index=apache_log method=OPTIONS
| stats count by clientip
| sort -count
IN 연산자로 여러 IP 한번에 검색
index=apache_log clientip IN ("1.1.1.1", "2.2.2.2", "3.3.3.3")
| stats count by url
| sort -count
300번대 응답 제외하고 차트 그리기
index=apache_log (status<300 OR status>399)
| eval info = method + " - " + status
| timechart limit=0 count by info
필드 추출 & 정책 저장
계산된 필드 (Calculated Field)
- eval 명령어를 정책으로 저장해서 검색 시 자동 실행
- 설정 → 필드 → 계산된 필드 → 새로 추가
- 소스 타입별로 적용 대상 지정 가능
- 주의 : 계산된 필드 정책은 순서 없이 병렬 실행됨 → 1단계 결과를 2단계에서 참조 불가 → 함수를 중첩해서 하나의 명령으로 작성해야 함
필드 별칭 (Field Alias)
- 기존 필드에 새 이름 부여
- 설정 → 필드 → 필드 별칭 → 새로 추가
- 하나의 정책에서 여러 필드 일괄 매핑 가능 (uri_path → url, uri_query → param)
필드 추출 (Field Extraction)
- 구분자 방식 : 빈칸 등 구분 기호로 전체 필드 분리
- 정규식 방식 : 마우스 드래그로 구간 선택 → Splunk가 정규표현식 자동 생성
- 단점 : 원본 데이터(_raw)만 대상으로 작업, 단계적 추출 미지원
포워더 주요 명령어
# 상태 확인
./bin/splunk status
# 수집 정책 추가
splunk add monitor -source /var/log/secure -sourcetype linux_secure -index secure_log
# 전송 서버 등록
splunk add forward-server 192.168.56.1:9997
# 배포 서버 연결
./bin/splunk set deploy-poll IP:8089
# 시작 / 중지 / 재시작
./bin/splunk start
./bin/splunk stop
./bin/splunk restart
보안 분석 활용 팁
패턴 매칭 vs 이상징후 분석
항목 패턴 매칭 이상징후 분석
| 비유 | 나무를 보는 방식 | 숲을 보는 방식 |
| 분석 방식 | 패턴 하나하나를 상세히 검사 | 데이터 전체 변화를 차트로 관찰 |
| 장점 | 작은 변화도 정확하게 탐지 | 패턴 몰라도 공격 탐지 가능 |
| 단점 | 패턴 모르면 탐지 불가 (미탐) | 소량 공격이 큰 변화에 묻힘 |
- 두 가지를 상호 보완해서 오탐과 미탐을 동시에 줄이는 게 이상적
응답 코드 분석 포인트
- 200 : 정상
- 301 / 302 : 리다이렉션, 실제 데이터 미전송 → 보안 우선순위 낮음
- 304 : 캐시 사용 권장 응답, 마찬가지로 우선순위 낮음
- 404 : 대량 발생 시 취약점 스캔 가능성 → 이상징후 판단 기준으로 활용
- 500 : 서버 내부 오류, 공격 시도로 인한 처리 실패일 수 있음
고유 개수(distinct count) 활용
- 단순 로그 개수보다 고유 URL / 고유 변수 개수가 이상징후 탐지에 더 효과적
- 고유 개수 급증 = 평소와 다른 행위 발생 신호로 해석 가능
- URL 고유 개수와 파일 고유 개수를 동시에 비교하면 분석 정확도 상승
'보안 & IT 지식 🌺' 카테고리의 다른 글
| SQL Injection (Union, Error-Based, Blind SQL Injection) (0) | 2026.04.20 |
|---|---|
| 개인정보 영향평가 수행안내서 part3(개인정보 영향평가 항목) 대상기관 개인정보 보호 관리체계 항목 (2) | 2026.04.16 |
| 개인정보 보호법 해석 (사례 중심) (0) | 2026.04.14 |
| 개인정보 보호법 해석 (사례 중심) (1) | 2026.04.13 |
| 개인정보 영향평가 수행안내서 part2(영향평가 수행절차) (1) | 2026.04.11 |
