정보보안핵심 · 19분 읽기
Suricata와 EVE JSON 이벤트
Suricata의 경보·흐름·프로토콜 기록을 함께 보면 탐지의 앞뒤 상황을 이해할 수 있다. EVE JSON은 중앙 분석으로 넘기는 공통 출발점이다.
개념부터 찾아보기
정의·역할·동작 원리를 독립 페이지에서 확인하세요. 본문의 밑줄 용어에도 설명이 있습니다.
이 노트에서 설명할 수 있게 되는 것
- EVE 이벤트의 공통 필드와 유형별 필드를 구분한다.
- flow_id·tx_id·센서 식별자의 범위 안에서 이벤트를 연결한다.
- 경보와 흐름·프로토콜 증거의 관계 및 지연을 설명한다.
01개념과 구성 요소
- 센서 역할는 패킷 탐지·차단과 flow·HTTP·· 같은 메타데이터 기록을 수행한다.
- 실행 조건캡처 기능··worker·상태 한도·룰·출력 유형의 구성이 처리 결과를 정한다.
- EVE공통 필드와 event_type별 필드를 가진 JSON 이벤트로 탐지·거래·흐름을 연결한다.
02수신 패킷이 EVE 이벤트로 바뀌는 순서
- 캡처 경로로 입력NIC와 지원 캡처 기능이 패킷을 사용자 공간 엔진으로 전달한다. Ring·큐·CPU 병목은 이 단계에서 손실을 만들 수 있다.
- Decode·Defrag헤더와 캡슐화를 읽고 필요한 IP 단편을 재조립한다. IP fragment 처리와 stream 처리는 다르다.
- Flow·Stream양방향 흐름과 상태·순서·재전송을 관리해 응용 파서에 필요한 바이트를 구성한다.
- 응용 파싱HTTP method·URI·status 같은 의미 있는 필드와 검사 버퍼를 만든다.
- 탐지 평가Prefilter와 규칙 평가가 조건을 검사한다. ·depth·누락 패킷은 검사 가능한 범위를 제한한다.
- EVE 출력활성화한 유형에 따라 alert·http·flow 등을 기록한다. 와 필요한 로 같은 통신의 다른 관찰을 연결한다.
03Suricata의 기능과 실행 조건
- 실습 버전수업 원문은 7.0.11을 쪽 환경과 맞추어 설치하고 과 로그를 비교한 자료다. 캡처·재조립·탐지·로그는 서로 다른 처리 단계다.
- 센서·출력는 / 엔진이면서 HTTP···flow 메타데이터를 남길 수 있다. EVE에 모든 종류가 항상 기록되는 것은 아니며 켠 출력 유형과 파서가 실제 관찰한 내용에 따라 달라진다.
- 세대별 비교는 단일 스레드 제품으로 일반화할 수 없다. 제품 세대·입력 방식·구성에 따라 처리 구조를 비교해야 한다.
04빌드 기능이 사용 가능한 캡처 경로를 결정한다
- 빌드·라이브러리소스 빌드에서 configure는 설치 prefix와 라이브러리를 조사하고 make는 컴파일·링크, install은 산출물과 설정을 배치한다. Rust/C 도구 체인, libpcap, YAML·JSON· 라이브러리는 각각 파서·캡처·설정·출력·탐지 기능과 관련된다.
- 바이너리 기능패키지가 설치되어 있어도 실행 중인 바이너리가 해당 기능을 포함해 빌드되었는지는 별도 문제다.
- 실습 Build-info수업 환경의 --build-info에서는 AF_PACKET은 yes, NFQueue·DPDK·Netmap 등은 no로 표시되었다. 이것은 그 실습 바이너리의 능력이며 제품 전체가 그 기능을 지원하지 않는다는 뜻이 아니다.
- 서비스 경로YAML에 캡처 옵션을 적는 것만으로 빌드에서 빠진 기능이 생기지 않는다. 배포판 패키지와 수동 빌드가 함께 있으면 가 어떤 실행 파일을 호출하는지도 실행 결과를 바꾼다.
text
suricata --build-info
suricata --list-runmodes
suricata -T -c /etc/suricata/suricata.yaml
systemctl cat suricata기능·실행 경로·설정 문법을 읽는 검사 예입니다. 패키지 설치나 방화벽 해제는 수행하지 않습니다.
05NIC RX Ring·DMA·RSS의 역할
- DMA·DescriptorNIC는 수신 프레임을 DMA로 메모리 버퍼에 놓고 descriptor로 그 위치와 상태를 관리한다. RX ring은 descriptor를 순환하며 재사용하는 구조이고 무한 대기열이 아니다.
- RX Ring 한도소비보다 유입이 빠르면 빈 버퍼 부족 등으로 패킷이 유실될 수 있다. Ring 1024·최대 4096이라는 값은 해당 NIC의 설정 예이며 모든 장치의 고정값이 아니다.
- 는 패킷 흐름의 주소·포트 등에 대한 해시로 여러 수신 큐에 분산한다. 같은 flow를 일관된 처리 경로에 두는 것이 재조립 상태 관리에 유리하다.
- 분산·지연양방향 대칭 분산과 큐·스레드 배치는 NIC와 캡처 구성에 맞아야 한다. 버퍼를 늘리면 순간 폭주를 견딜 여유는 늘지만 지속적인 CPU 처리량 부족을 해결하지 못하며 지연이 늘 수 있다.
LEARN THROUGH PRACTICE
Suricata 실행 전에 NIC의 큐·링·드라이버 읽기
채널 수와 수신 링 용량을 구분하고 패킷 손실 진단의 기준선을 만든다.
실습 구성과 전제
- 센서용 격리 의 데이터 NIC를 확인한다.
- 조회 명령만 사용하며 운영 NIC의 채널 수·링 크기를 임의로 변경하지 않는다.
드라이버가 제공하는 기능을 확인한다
- ethtool -i는 드라이버와 기능 정보를 보여 준다. 게스트에서 보이는 가상 NIC의 기능과 물리 호스트 NIC의 기능을 혼동하지 않는다.
- 기능 지원은 실제 활성화 상태나 사용 상태와 별개다.
shellethtool -i ens160 suricata --build-infoNIC와 빌드 기능을 조회한다. 인터페이스 이름은 자신의 센서에 맞춘다.
원본 크기로 보기 ↗- driver는 vmxnet3이며 version·bus-info가 표시된다.
- supports-statistics는 yes지만 EEPROM 접근은 no다. 모든 ethtool 기능이 동일하게 지원되는 것은 아니다.
확인 기준센서 인터페이스 이름과 드라이버를 운영 기록에 남긴다.
채널 수와 링 크기를 나누어 읽는다
- ethtool -l의 Combined는 채널 수이며 ethtool -g의 RX는 링 파라미터다. 숫자 4와 1024를 같은 단위의 처리량으로 비교하지 않는다.
- 여러 큐가 있어도 양방향 연결이 같은 처리 맥락에 배치되는지, 캡처 모드의 분배 방식이 맞는지를 확인해야 한다.
shellethtool -l ens160 ethtool -g ens160 ethtool -S ens160채널·링·통계를 각각 조회한다. 드라이버마다 통계 이름과 지원 항목이 다르다.
원본 크기로 보기 ↗- Combined의 최대값과 현재값이 모두 4로 표시된다.
- RX·TX가 n/a인 것은 분리 채널 항목이 지원되지 않는다는 표시이며 패킷을 수신하지 못한다는 뜻이 아니다.
원본 크기로 보기 ↗- RX의 최대값은 4096, 현재값은 1024로 표시된다.
- TX와 RX Jumbo도 별도의 현재값을 가진다. 최대 가능 값과 현재 설정을 구분해야 한다.
확인 기준변경 전에는 인터페이스 통계·캡처 손실·CPU 병목을 먼저 기록한다.
손실 지점을 센서 파이프라인과 연결한다
- NIC 드롭이 늘면 캡처 이전 손실을 의심하고, 캡처·해석 통계와 함께 비교한다. EVE 경보 수가 적다는 것만으로 트래픽이 적거나 안전하다고 판단하지 않는다.
- ··AF_PACKET 등 실제 실행 조건을 적고 같은 부하에서 한 설정씩 비교한다.
확인 기준한 가지 튜닝 값보다 입력 패킷·수신 손실·처리 지연의 전후 수치를 비교한다.
실습에서 확인한 동작 원리
- 채널 수·링 용량·스레드 수는 다른 값이다.
- 경보 품질을 보기 전에 캡처 가시성과 손실부터 확인한다.
06일반 소켓과 패킷 캡처 경로는 같지 않다
- 일반 소켓·캡처일반 애플리케이션은 커널이 처리한 바이트 스트림을 소켓에서 읽는다. AF_PACKET 같은 캡처 경로는 링크 계층 패킷을 사용자 공간 엔진으로 넘겨 가 자체 flow·stream·응용 파싱을 수행하게 한다.
- 서로 다른 경로패킷 캡처 경로를 일반 애플리케이션의 소켓 경로와 동일하게 해석해서는 안 된다.
- NAPI·sk_buffNAPI는 인터럽트와 polling을 조합하는 커널 수신 처리와 관련되고, sk_buff는 커널의 패킷 표현이다. DPDK·AF_XDP·Netmap 등은 다른 입출력 경로와 전제 조건을 가진다.
- 고속 I/O 조건단순히 이름에 “고속”이 있다는 이유만으로 현재 에서 더 빠르다고 결론 내릴 수 없으며 장치·드라이버·메모리·코어 배치가 함께 작동해야 한다.
07Decode→Defrag→Flow→Stream
- Decode·DefragDecode는 //IP// 등의 헤더와 캡슐화를 해석한다. Defrag는 IP fragment를 묶는 단계이고 stream reassembly는 순서 번호에 따른 바이트를 묶는 단계다.
- IP와 둘은 계층과 상태가 다르다. 에서도 IP 단편화가 가능하므로 “는 fragment가 없다”로 외우면 안 된다.
- Flow·StreamFlow tracking은 대개 양방향 5튜플과 구성된 ·장치 구분을 이용해 상태를 유지한다. Stream tracking은 handshake·순서·재전송·종료를 관찰하고 재조립 버퍼를 만든다.
- 재조립 사례문자열이 UNI / ON SEL / ECT 세 조각에 나뉘어 있으면 단일 payload 검색에는 없던 문자열이 재조립 후 나타날 수 있다. 누락·겹침·중간부터 시작한 캡처는 해석의 불확실성을 만든다.
08App-layer parser와 검사 버퍼
- 응용 필드응용 파서는 HTTP 요청·응답에서 method·URI·host·status 같은 의미 있는 필드를 만든다. 탐지 엔진은 raw packet, 재조립 stream, 응용 계층 버퍼 중 규칙이 지정한 곳을 평가한다.
- 버퍼 구분URI에서 찾으려는 문자열을 전체 payload와 같은 것으로 다루면 정규화나 분할 조건에서 결과가 달라질 수 있다.
- MPM·Prefilter여러 패턴을 빠르게 찾는 MPM·prefilter는 후보를 줄여 정밀 규칙 평가의 비용을 낮추는 구조다. Hyperscan 등 사용 가능 엔진은 빌드 조건에 영향을 받는다.
- 규칙 비용prefilter가 있다는 사실은 모든 규칙을 동일한 방식으로 평가한다는 뜻이 아니며, 규칙 추가 후 CPU·drop·검사 범위도 함께 달라질 수 있다.
09workers·autofp와 실제 스레드 상태
- 는 각 패킷 처리 스레드가 전체 처리 파이프라인을 가지는 방식이고 는 수신·디코딩 뒤 flow worker로 전달하는 구조다. single은 하나의 패킷 처리 스레드로 수행하는 방식이다.
- 지원 캡처 방식캡처 방식에 따라 사용 가능한 와 적합성이 달라진다.
- PID·LWP실습의 ps -Lf 출력에는 하나의 PID 아래 여러 LWP와 NLWP=10이 표시되었다. PID가 같고 LWP가 다른 것은 동일 안의 여러 스레드라는 뜻이다.
- ps 옵션ps -lf의 소문자 l은 긴 형식이고 스레드 표시의 대문자 L과 구분한다. 스레드 수 10과 vCPU 4만으로 10개가 동시에 계산 중이라고 말할 수는 없다.
- 실제 병렬성관리 스레드·대기 스레드와 실제 worker의 CPU 사용을 구분한다.
10HOME_NET·룰 파일·정책의 연결
- 주소·입력·룰HOME_NET은 보호 대상 주소 범위이며 캡처 위치에서 보이는 전후 주소와 일치해야 한다. af-packet 인터페이스는 실제 패킷이 들어오는 지점이고 default-rule-path와 rule-files는 읽을 규칙을 결정한다.
- 로드·YAMLlocal.rules 파일을 만들었어도 로드 목록에 없으면 탐지는 일어나지 않는다. YAML 들여쓰기는 탭 대신 공백으로 구성한다.
- Host OS Policyhost-os-policy는 겹친 데이터 등의 해석을 보호 대상에 맞추는 정책이다. 모든 주소를 무조건 로 바꾸는 것이 보편적인 정답은 아니다.
- 구조별 편집설정 파일의 줄 번호는 버전마다 달라지므로 이름과 구조를 확인하지 않은 줄 단위 일괄 편집은 적절하지 않다.
11memcap·depth·checksum은 가시성 조건이다
- ·Depthdefrag·flow·stream·reassembly의 은 각 상태 영역의 메모리 상한이다. timeout은 상태를 얼마나 유지할지, reassembly depth는 어느 범위까지 바이트를 재조립할지에 관여한다.
- 한도 영향상한 초과 때 동작은 기능·모드·정책별로 달라질 수 있다. depth 너머에서 재조립이 중단되면 해당 바이트가 필요한 탐지에 한계가 생긴다.
- Checksum·Offloadchecksum validation은 잘못된 체크섬을 다루는 조건이다. 송신 호스트에서 캡처한 패킷은 NIC offload 전에 보이는 체크섬 때문에 실제 회선 패킷과 다르게 표시될 수 있다.
- 통계 보존이 경우 검증을 무조건 끄는 대신 캡처 위치와 offload 영향을 분리한다. stats 출력까지 모두 끄면 drop과 메모리 한도를 추적할 근거가 사라진다.
12EVE의 공통 필드와 유형별 필드
- EVE 공통 필드은 timestamp·event_type··주소·포트 등의 공통 정보와 alert/http/flow 같은 유형별 내용을 한 줄 이벤트로 기록한다. alert.signature_id는 규칙, http.url은 요청 경로, http.status는 응답 상태를 설명한다.
- Flow·는 같은 엔진 흐름의 이벤트를 연결하지만 여러 센서에서 통용되는 전역 고유 ID로 간주하지 않는다. 한 연결의 여러 HTTP 거래는 등 거래 정보를 더해 구분한다.
- 가상 이벤트아래 세 줄은 실제 환경의 주소를 제거한 학습 예다. alert가 있었다는 사실과 HTTP 응답이 성공했는지, 센서가 차단했는지는 서로 다른 필드의 질문이다.
- Allowed의 의미passive 에서 allowed는 업무적으로 안전하다는 판정이 아니다.
text
{"event_type":"alert","flow_id":42001,"tx_id":0,"alert":{"signature_id":1000001,"action":"allowed"}}
{"event_type":"http","flow_id":42001,"tx_id":0,"http":{"http_method":"GET","url":"/training","status":200}}
{"event_type":"flow","flow_id":42001,"flow":{"pkts_toserver":4,"pkts_toclient":3}}
jq 'select(.flow_id == 42001)' eve.json원리를 설명하는 가상 학습 예시입니다.
원리 심화
13Flow·Transaction·Community ID의 결합 범위
- Flow ID는 같은 흐름의 EVE 이벤트를 연결하는 핵심 필드다. 독립 센서·실행 시점까지 포함한 전역 영구 식별자로 가정하지 않는다.
- ID한 연결에 여러 HTTP 요청·응답이 존재할 수 있다. 같은 문맥을 더해야 어느 요청에서 탐지가 발생했는지 좁힐 수 있다.
- 호환 도구가 흐름을 연결하도록 공통 방식으로 계산한 식별자다. 비교 도구들은 같은 seed 등 호환 조건을 사용해야 한다.
- 경계 앞뒤에서는 관찰 주소·포트가 달라져 같은 실제 통신의 가 달라질 수 있다. 변환 기록과 센서 위치가 필요하다.
- 시간 문맥같은 주소·포트 조합은 나중에 재사용될 수 있다. 흐름 지문만으로 서로 다른 시간의 사건을 하나로 합치지 않는다.
예제로 추적
14가상 HTTP 연결의 두 요청과 경보 결합
- 이벤트 설정=420인 연결에 =0의 요청 A와 =1의 요청 B가 있다고 가정한다. 경보는 =1에서 발생했다.
- 넓은 결합만으로 경보를 요청 목록에 결합하면 A와 B 둘 다 후보가 된다. 연결이 같다는 사실만 얻은 것이다.
- 문맥 보강와 를 함께 비교하면 B로 좁힐 수 있다. 필드가 실제로 존재하고 같은 파서 문맥인지 확인한다.
- 시간 대조요청·응답·경보 시각과 방향을 비교하여 재시작·ID 재사용·지연 도착을 구분한다.
- 원문 복귀가능하면 해당 패킷·재조립 자료로 돌아가 실제 검사 버퍼를 확인한다. EVE의 요약 필드만으로 모든 본문 바이트를 복원할 수는 없다.
검증·예외
15EVE는 있는데 HTTP·경보 필드가 빠질 때
- 처리 단계수신 드롭·디코더 오류·flow/stream 제한·app-layer 파싱 상태를 구분한다. 원인은 모두 같은 종류의 packet loss가 아니다.
- 설정 범위EVE에서 활성화한 이벤트 유형과 출력 설정을 확인한다. 파싱은 수행됐지만 해당 유형을 기록하지 않을 수도 있다.
- 깊이 한도··본문 검사 한도에 도달한 자료가 아닌지 통계와 설정을 대조한다. 규칙 불일치와 검사되지 않음을 분리한다.
- 암호화 위치를 종료하지 않는 센서는 암호화된 HTTP 본문을 그대로 읽지 못한다. 메타데이터와 평문 HTTP 가시성을 같은 수준으로 해석하지 않는다.
16Snort 규칙 이식과 결과 비교
- 넓은 시험 규칙·전체 ·80번 목적지 규칙을 두 엔진에 적용하면 fast/JSON 출력 경로를 비교할 수 있다. 이러한 규칙은 파이프라인이 입력을 받아 경보를 출력하는지 확인하는 넓은 시험 규칙이며 그 자체로 공격 탐지를 뜻하지 않는다.
- 포트와 프로토콜HTTP 프로토콜 검사가 없는 any→80 규칙은 포트 조건만 만족한 패킷에도 반응할 수 있다.
- 문법 호환성두 엔진이 공통 문법을 갖더라도 옵션·버퍼·버전 차이 때문에 모든 규칙이 그대로 호환되는 것은 아니다. 문법 검사와 같은 양성·음성 PCAP의 결과를 각각 비교해야 한다.
- 버전별 결과JSON 필드와 기본값은 버전·설정의 영향을 받으며 단일 실습을 제품 간 보편적인 우열로 확대하지 않는다.
17경보가 없을 때 처리 단계별로 원인을 찾는다
- 단계별 실패경보가 없는 원인은 패킷 미도착, 캡처 손실, 잘못된 HOME_NET, 응용 파서 미연결, 재조립 한도, 규칙 미로드, 조건 불일치, 출력 미활성화 중 어느 곳에도 있을 수 있다. 한 번에 규칙을 바꾸기보다 패킷 입력 수→flow·protocol 식별→규칙 수→EVE 출력의 연결을 따라가면 실패 지점을 좁힐 수 있다.
- 동일 Flow 연결같은 의 alert·HTTP·flow를 연결하면 탐지와 응용 거래·전체 흐름을 함께 읽을 수 있다. 그것이 전 구간 무손실이나 모든 공격 탐지를 보증하지는 않는다.
- 손실·지연·오탐캡처 손실 지표, 로그 처리 지연, 정상 트래픽 오탐을 함께 해석해야 센서가 보고 있지 않은 영역도 설명할 수 있다.
설명과 함께 보는 보조 도식
처리 과정
모식도 · EVE 유형별 사건 연결
서로 다른 EVE 이벤트를 원본을 유지한 채 연결한다.
01Suricata 엔진프로토콜 해석과 규칙 평가
02alert 이벤트SID·탐지 문맥
03프로토콜 이벤트HTTP·DNS·TLS 등 세부
04flow 이벤트연결 방향과 요약
05중앙 조사센서·시각·흐름·트랜잭션 연결
01
출력
설정된 유형별로 이벤트를 생성한다.
전체 단계를 한 번에 읽기
- 01
출력
설정된 유형별로 이벤트를 생성한다.
- 02
흐름 요약
흐름의 종료·만료 등 출력 조건을 고려한다.
- 발생 순서
- 경보와 같지 않을 수 있음
- 03
연결
flow_id와 필요한 경우 tx_id를 문맥 안에서 사용한다.
- 04
확인
원본과 PCAP로 실제 요청·응답 관계를 검증한다.
- 주의
- 경보 = 성공 확정 아님
READ · OBSERVE · CONNECT
함께 보는 학습 자료
아래 공식 자료를 본문의 개념·예제와 함께 읽어 보세요. 자료별로 확인할 위치와 관찰할 내용을 적었습니다.
Suricata 8: EVE 이벤트별 JSON 예제
alert·http·anomaly·flow 예제를 나란히 읽어 연결 전체와 개별 응용 을 구분한다.
읽으면서 확인할 것
- event_type마다 다른 필드 구조
- 와 존재하는 의 결합
- alert.action과 흐름 종료·상태 정보의 차이
학습 확인
이해했는지 확인하기
- event_type별 파서와 필수 필드를 확인한다.
- flow_id를 센서·시간 범위와 함께 사용한다.
- EVE 출력량·지연·패킷 드롭과 정상 트래픽의 결과를 확인한다.
