Suricata의 개념, 설치, 설정, Snort 비교, 패킷 처리 구조, Suricata 내부 파이프라인, 룰셋 호환 실습을 순서대로 학습한다.
Suricata는 오픈소스 기반 IDS/IPS 엔진이다. 네트워크 트래픽을 분석하여 공격 패턴을 탐지하고, 탐지 결과와 메타데이터를 로그로 남긴다. Snort 룰셋 호환성이 높고 EVE JSON 형식으로 다양한 네트워크 메타데이터를 출력할 수 있다.
보안 관제와 솔루션 직무에서는 IDS, IPS, NSM, SIEM의 차이를 설명할 수 있어야 한다. Suricata는 단순 탐지 센서에서 로그 분석·SIEM 연동까지 연결되는 도구다.
IDS는 네트워크 트래픽을 분석해 공격 패턴을 탐지하고 Alert를 남긴다. IPS는 inline 구조에서 차단까지 수행할 수 있다.
Network Security Monitoring. 단순히 공격 탐지로 끝나지 않고 누가 누구와 통신했는지, 어떤 프로토콜과 요청이 있었는지까지 관찰한다.
웹서버 접속 로그, IDS 탐지 로그, 방화벽 차단 로그, 서버 로그인 실패 로그를 따로 보지 않고 하나의 공격 흐름으로 분석한다.
Flow, HTTP, DNS, TLS 같은 메타데이터를 남길 수 있기 때문에 단순 alert보다 풍부한 분석이 가능하다.
설치는 단순히 프로그램을 깔아보는 단계가 아니다. 어떤 라이브러리를 포함해서 빌드했는지에 따라 AF_PACKET, NFQUEUE, DPDK, Lua, Hyperscan 같은 기능 사용 가능 여부가 달라진다.
보안 직무에서는 실행만 할 줄 아는 것보다 의존성, 빌드 옵션, 실행 경로, 설정 파일 위치를 이해하는 것이 중요하다. 설치 과정 자체가 기능 지원 여부를 확인하는 과정이다.
버전·다운로드 → 저장소 활성화 → 종속성 패키지 → 빌드·설치 → 설치 확인 → 패키지 역할 순서로 진행한다.
실습에서는 Suricata 7.0.11을 기준으로 진행한다. 최신 버전이 별도로 있더라도 실습 환경이나 pfSense 기준에 맞춰 버전을 고정할 수 있다.
mkdir /usr/local/src/suricata cd /usr/local/src/suricata wget https://www.openinfosecfoundation.org/download/suricata-7.0.11.tar.gz ls
dnf -y update dnf -y install epel-release dnf-plugins-core # 추가 패키지 저장소 install dnf config-manager --set-enable crb # 추가 패키지 저장소 활성화
빌드 도구, Rust, Python, JSON/YAML/PCAP/정규표현식/패턴매칭 라이브러리, 패킷 분석 도구를 설치한다.
sudo dnf install -y wget tar gzip file git vim sudo dnf install -y make autoconf automake libtool pkgconf-pkg-config gcc gcc-c++ sudo dnf install -y rustc cargo cbindgen sudo dnf install -y python3 python3-pyyaml sudo dnf install -y jansson-devel libpcap-devel libyaml-devel pcre2-devel zlib-devel hyperscan-devel sudo dnf install -y libcap-ng-devel file-devel lz4-devel libnet-devel systemd-devel sudo dnf install -y tcpdump wireshark-cli # 추후 필요시 설치 # sudo dnf install -y libnetfilter_queue-devel libnfnetlink-devel libnetfilter_log-devel libmnl-devel
tar xzvf suricata-7.0.11.tar.gz cd suricata-7.0.11 ./configure \ --prefix=/usr/ \ --sysconfdir=/etc/ \ --localstatedir=/var/ make make install echo $? make install-conf make install-rules make install-full sudo suricata-update
suricata --build-info
| 기능 | 확인 의미 |
|---|---|
| AF_PACKET support | Linux 기본 고성능 패킷 캡처 방식. NIDS 실습 핵심. |
| AF_XDP / XDP / eBPF | XDP 기반 고성능 userspace 캡처와 커널 내부 필터링·추적 기능. |
| DPDK | 커널 우회 고성능 패킷 처리. 전용 NIC와 hugepage 필요. |
| PF_RING | ntop PF_RING 기반 고성능 패킷 캡처 프레임워크. |
| NFQueue / NFLOG | Netfilter 큐 기반 IPS/inline 확장 또는 로그 패킷 수집 기능. |
| Libmagic / liblz4 / LUA / GeoIP2 | 파일 타입 식별, 압축 PCAP, Lua 룰, IP 국가/위치 매칭 고도화. |
| 분류 | 패키지 | 역할 |
|---|---|---|
| 다운로드/압축 | wget, tar, gzip, file, git | 소스 압축파일 다운로드, 압축 해제, 파일 형식 확인, Git 저장소 사용. |
| 빌드 | make, autoconf, automake, libtool, pkgconf, gcc, gcc-c++ | configure 스크립트, Makefile, 컴파일, 링크에 필요. |
| Rust | rustc, cargo, cbindgen | Suricata 7.x의 Rust 기반 모듈 빌드와 C 엔진 연결. |
| 설정/로그 | python3, python3-pyyaml, jansson-devel, libyaml-devel | suricata-update 실행, YAML 설정 해석, eve.json 출력. |
| 탐지 성능 | pcre2-devel, hyperscan-devel | pcre 옵션 처리와 고속 패턴 매칭 성능 향상. |
| 패킷/분석 | libpcap-devel, tcpdump, wireshark-cli | NIC 캡처, PCAP 처리, CLI 기반 패킷 분석. |
| 확장 기능 | libnetfilter_queue, libnfnetlink, libnetfilter_log, libmnl | NFQUEUE/NFLOG 기반 IPS/Netfilter 연동에 필요할 수 있음. |
설정은 Suricata를 실제 환경에 맞게 운영하기 위한 기본 운영 능력이다. 탐지가 안 되거나 로그가 안 남을 때 원인을 찾으려면 이 구간을 이해해야 한다.
ip addr ip route # 자기 OS의 IP 주소 확인 후 suricata.yaml 수정 vim /etc/suricata/suricata.yaml # 예시: 자기 OS IP가 172.16.14.98이면 HOME_NET: "[172.16.14.98]" # 또는 실습 표기용 HOME_NET: "[각자_자기_OS_IP]"
HOME_NET은 Suricata가 보호 대상으로 보는 주소다. 실습에서는 강의실 공통 대역을 고정으로 쓰지 않고, 각 사용자가 자기 OS의 IP 주소를 확인해서 입력한다.
# suricata.yaml af-packet: - interface: ens160 default-log-dir: /var/log/suricata/
인터페이스 이름이 틀리면 패킷을 받지 못한다. 브릿지 모드에서 실제 트래픽이 들어오는 NIC 이름을 확인해야 한다.
default-rule-path: /var/lib/suricata/rules rule-files: # - suricata.rules - local.rules
실습에서는 공식 룰셋을 주석 처리하고 local.rules만 로드하면 확인이 쉽다.
OS마다 조각화된 패킷이 겹칠 때 앞 패킷을 우선할지, 뒤 패킷을 우선할지 처리 방식이 다를 수 있다. 감시 대상이 Linux라면 Linux 정책으로 맞춘다.
host-os-policy: windows: [] linux: [0.0.0.0/0]
eve.json은 네트워크 패킷을 종합적으로 로그에 남기므로 로그가 빠르게 쌓인다. 실습에서는 필요한 프로토콜만 켜서 분석 대상이 흐려지지 않게 한다.
# 설정 파일 백업 cp /etc/suricata/suricata.yaml /etc/suricata/suricata.yaml.bak # 실습 상황에서 필요 없는 프로토콜 로그는 주석 처리 가능 # dns, tls, files, smtp, ftp, rdp, nfs, smb, tftp, ike, # dcerpc, krb5, bittorrent-dht, snmp, rfb, sip, quic, # dhcp, ssh, mqtt, http2, stats 등
pcap-log: enabled: yes sudo suricata -T -c /etc/suricata/suricata.yaml -v
PCAP 로그는 Wireshark로 실제 패킷을 확인할 수 있는 증적 자료다. 실행 전에 -T로 설정과 룰 문법을 먼저 검사한다.
echo "" > /var/lib/suricata/rules/local.rules ln -s /var/lib/suricata/rules /etc/suricata/rules vim /etc/suricata/rules/local.rules alert http any any -> $HOME_NET 80 (msg:"DVWA server movement detected!!"; sid:2000001;rev:1;) suricata -c /etc/suricata/suricata.yaml -i 인터페이스 -l /var/log/suricata/
which suricata # /usr/bin/suricata vim /etc/systemd/system/suricata.service [Unit] Description=Suricata IDS Service After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml -i ens160 ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable suricata sudo systemctl start suricata sudo systemctl status suricata sudo journalctl -u suricata -f tail -f /var/log/suricata/eve.json tail -f /var/log/suricata/fast.log
둘 다 IDS/IPS 엔진이지만 학습 포인트가 다르다. Snort는 룰 기반 탐지 원리를 보기 좋고, Suricata는 멀티스레드 처리와 EVE JSON 메타데이터 기반 분석에 강점이 있다.
| 구분 | Snort | Suricata |
|---|---|---|
| 주요 목적 | 룰 기반 IDS/IPS 탐지 | IDS/IPS + NSM 메타데이터 수집 |
| 처리 구조 | 단일 스레드 중심 | 멀티스레드 기반 고성능 처리 |
| 대표 로그 | alert_fast.txt, alert_json 등 | eve.json, fast.log |
| 로그 특징 | Alert 중심 | Alert + HTTP/DNS/TLS/Flow/File 로그 |
| SIEM 연동 | 가능 | JSON 기반 연동에 유리 |
| 장점 | 룰 작성·탐지 원리 학습에 적합 | 관제·분석·대용량 트래픽 처리에 적합 |
| 설정 파일 | snort.lua | suricata.yaml |
Suricata는 runmode를 통해 workers, autofp, single 방식을 사용할 수 있다. 대용량 트래픽 처리에서 병렬 처리 개념과 연결된다.
Snort에서 작성한 룰셋은 일부 옵션을 제외하면 Suricata에서 호환된다. 같은 룰로 두 엔진의 로그 차이를 비교할 수 있다.
alert뿐 아니라 flow, http, dns, tls, file 정보를 함께 남기므로 SIEM 연동과 상관분석에 유리하다.
Suricata의 멀티스레드 구조를 이해하려면 프로그램, 프로세스, CPU, 스레드의 차이를 먼저 이해해야 한다. 이 챕터는 패킷 처리 성능 설명으로 넘어가기 위한 기초다.
Suricata는 하나의 프로그램이지만 실행되면 프로세스가 되고, 그 안에서 여러 스레드가 패킷 수신·분석·탐지·로그 처리를 나누어 수행한다. 이걸 설명할 수 있어야 workers, CPU core, RSS 흐름까지 자연스럽게 이어진다.
프로그램은 실행 전 파일, 프로세스는 메모리에 올라간 실행 단위, CPU는 명령어 처리 장치, 스레드는 프로세스 안의 실제 실행 흐름이다.
저장장치에 저장되어 있는 실행 가능한 코드와 파일의 묶음. 실행되기 전 상태다.
프로그램이 실행되어 메모리에 올라간 상태. 운영체제가 관리하는 실행 중인 프로그램 단위다.
실제 명령어를 계산하고 실행하는 장치. 프로세스 안의 스레드를 CPU 코어가 실행한다.
프로세스의 실제 실행 흐름. CPU가 실행하는 기본 단위다.
대부분의 프로세스는 CPU가 처리한다. 실제 작업 처리는 코어별로 담당한다. 한 순간에 하나의 CPU 코어는 하나의 스레드만 실행할 수 있다.
프로세스는 자기만의 메모리 공간을 가진다. 따라서 서로 다른 프로세스는 기본적으로 메모리를 직접 공유하지 않는다.
레시피는 프로그램, 요리사가 레시피를 꺼내 요리를 시작하면 프로세스가 된다. 라면처럼 순서대로만 진행되는 작업은 하나의 흐름, 즉 하나의 스레드로 볼 수 있다.
볶음밥을 만들 때 밥을 짓는 동안 재료 손질을 같이 하면 전체 시간이 줄어든다. 프로세스 내에서 여러 실행 흐름을 나누면 CPU 코어 여러 개를 활용하거나 하나의 코어에서 번갈아 실행할 수 있다.
suricata -i ens160 -c /etc/suricata/suricata.yaml -l /var/log/suricata/ & ps ps -lf # l = 스레드 관련 정보 # f = 자세하게 ps -Lf -p <수리카타 PID> # 하나의 Suricata 프로세스 안에서 여러 스레드 동작 확인
nproc lscpu
CPU 코어가 4개이고 Suricata가 여러 스레드를 사용한다면 운영체제는 각 스레드를 여러 코어에 나누어 실행할 수 있다.
CPU Core 1 → Thread 1 CPU Core 2 → Thread 2 CPU Core 3 → Thread 3 CPU Core 4 → Thread 4
패킷은 애플리케이션으로 바로 들어오지 않는다. NIC, RX Queue/RX Ring, Driver, skb, Kernel Network Stack, Socket Buffer를 거쳐 사용자 공간 프로그램이 읽을 수 있는 형태가 된다.
NIC를 커널에서 거의 떼어내고 사용자 공간 프로그램이 NIC 큐를 직접 읽는다. 커널 네트워크 스택을 우회하는 가장 앞단에 가깝다.
드라이버 단계, skb 생성 전의 이른 지점에서 패킷을 처리한다. 커널 안이지만 매우 앞단이다.
NIC RX/TX Ring에 가까운 지점을 사용자 공간에 매핑하거나 일반 캡처보다 NIC/Ring에 더 가까운 쪽에서 고속 캡처를 지원한다.
AF_PACKET은 skb 생성 후 커널 네트워크 스택 쪽에서 packet socket으로 패킷을 받는다. libpcap은 보통 AF_PACKET 같은 OS 캡처 인터페이스 위에서 패킷을 읽는다.
Suricata는 패킷 하나를 바로 룰과 비교하지 않는다. 캡처·디코딩·재조립·플로우 추적·애플리케이션 분석·탐지·로그화의 파이프라인으로 처리한다.
threading:
set-cpu-affinity: no
cpu-affinity:
- management-cpu-set:
cpu: [ 0 ]
- receive-cpu-set:
cpu: [ 0 ]
- worker-cpu-set:
cpu: [ "all" ]
mode: "exclusive"
detect-thread-ratio: 1.0detect-thread-ratio: 1.0은 탐지된 CPU 수 1개당 탐지 스레드 1개를 배정한다는 의미로 설명할 수 있다.
security:
limit-noproc: true
landlock:
enabled: no
directories:
read:
- /usr/
- /etc/
- /etc/suricata/
lua:
#allow-rules: falselimit-noproc는 새 프로세스 생성을 제한한다. Landlock이 켜져 있으면 지정된 디렉터리 중심으로 접근이 제한된다.
# Runmode the engine should use. # Default depends on selected capture method. # 'workers' generally gives best performance. #runmode: autofp
single은 단순 구조, workers는 일반적으로 성능에 유리한 구조, autofp는 flow pinning을 활용하는 구조로 설명할 수 있다.
defrag: memcap: 32mb hash-size: 65536 trackers: 65535 max-frags: 65535 prealloc: yes timeout: 60
TCP는 자체적으로 세그먼트 단위로 나뉘지만, UDP는 데이터그램 단위로 전송되므로 IP 계층 조각화가 발생할 수 있다.
flow:
memcap: 128mb
hash-size: 65536
prealloc: 10000
vlan:
use-for-tracking: true
livedev:
use-for-tracking: truestream:
memcap: 64mb
checksum-validation: yes
#midstream: false
reassembly:
memcap: 256mb
depth: 1mb
#raw: yes
#segment-prealloc: 2048
#check-overlap-different-data: truedepth가 1mb이면 TCP payload가 1mb를 넘어간 이후는 재조립하지 않는다. 공격 문자열이 그 뒤에 있으면 재조립 기반 탐지가 어려울 수 있다.
decoder:
teredo:
enabled: true
vxlan:
enabled: true
geneve:
enabled: true
detect:
profile: medium
prefilter:
default: mpm
profiling:
# rule, keyword, packet profilingdecoder는 Teredo, VXLAN, Geneve 같은 캡슐화 패킷의 내부 패킷까지 해석한다. detect는 prefilter와 mpm으로 후보 룰을 좁혀 자원 소모를 줄인다.
Suricata에서 Snort 룰셋을 사용할 수 있다는 것을 확인하고, Snort의 alert_json과 Suricata의 eve.json을 비교한다. 실습 명령어는 빠짐없이 순서대로 정리했다.
cd /usr/local/snort/etc/snort vim /usr/local/snort/etc/snort/snort.lua # 약 197줄 rules = [[ 경로 ]] 로 local.rules 파일 위치 확인 및 복사 # /etc 경로에 심볼릭 링크 생성 ln -s /usr/local/snort/etc/snort /etc/snort ln -s 기존_룰_경로 /etc/snort/rules # snort 서비스가 active라면 잠시 중지 systemctl stop snort
# snort.lua 약 260번째 줄
alert_full = {file = true}
alert_json = {file = true}
log_pcap = {}alert_full은 사람이 읽기 쉬운 상세 로그, alert_json은 구조화 로그, log_pcap은 실제 패킷 원본 저장에 사용한다.
cd /etc/snort/rules vim local.rules #alert icmp any any -> any any (msg:"ICMP Test Detected"; sid:1000001; rev:1;) #alert tcp any any -> any any (msg:"TCP"; sid:1000002; rev:1;) alert tcp any any -> any 80 (msg:"http server KONG"; sid:1000003; rev:1;) alert tcp 내서버 any -> 접속자 any (msg:"내서버->접속자 tcp"; sid:1000004; rev:1;) alert tcp 접속자 any -> 내서버 any (msg:"접속자->내서버 tcp"; sid:1000005; rev:1;)
방향 연산자에서 A → B는 A에서 B로 가는 트래픽을 의미한다. 서버 방향과 접속자 방향 룰을 나누면 패킷 흐름을 설명하기 쉽다.
cd /var/log/snort # 필요시 백업 cp alert_json.txt alert_json.txt.bak # 실습 확인을 쉽게 하기 위해 삭제 rm *
snort -c /etc/snort/snort.lua -i ens160 -l /var/log/snort \ --daq afpacket --daq-dir /usr/local/snort/lib/daq -k none
cd /var/log/snort ls vim alert_full.txt vim alert_json.txt
alert_full은 룰 정보, 발생 시간, 출발지/목적지 IP·포트, TCP/IP 헤더 정보를 보여준다. alert_json은 timestamp, pkt_num, proto, dir, src_ap, dst_ap, rule, action 같은 필드로 정리된다.
# Snort 룰 확인 vim /etc/snort/rules/local.rules # Suricata 룰에 붙여넣기 vim /etc/suricata/rules/local.rules # 예시 alert icmp any any -> any any (msg:"ICMP Test Detected"; sid:1000001; rev:1;) alert tcp any any -> any any (msg:"TCP"; sid:1000002; rev:1;) alert tcp any any -> any 80 (msg:"http server KONG"; sid:1000003; rev:1;) # Suricata 실행 suricata -c /etc/suricata/suricata.yaml -i 인터페이스 -l /var/log/suricata/
cd /var/log/suricata ls cat fast.log | grep KONG cat eve.json | grep '02:29:57.398101' cat eve.json | grep '"flow_id":1428357619560671' > testeve.txt
Snort JSON은 매칭 중심으로 탐지 결과를 구조화한다. Suricata eve.json은 event_type에 따라 alert, http, flow 이벤트를 함께 기록한다. flow_id를 기준으로 같은 통신 흐름을 연결하면 단일 alert가 아니라 전체 HTTP 요청/응답 흐름을 추적할 수 있다.
timestamp, pkt_num, proto, dir, src_ap, dst_ap, rule, action 중심으로 매칭 결과를 보여준다.
alert, http, flow 등 다양한 이벤트를 함께 남기며 flow_id로 하나의 통신 흐름을 연결한다.
event_type, flow_id, src_ip, dest_ip, http.url, alert.signature 같은 필드를 기준으로 검색과 상관분석을 하기 쉽다.
이번 실습의 목표는 Suricata를 단순히 설치하고 실행하는 것이 아니라, IDS가 네트워크 패킷을 어떤 구조로 처리하고 탐지하는지 이해하는 것이다.
룰 기반 탐지 원리를 학습하기 좋다. 어떤 패킷이 어떤 룰에 매칭되었는지 이해하기 쉽다.
탐지 결과뿐 아니라 HTTP, DNS, TLS, Flow 같은 네트워크 행위 정보를 함께 남길 수 있어 관제와 분석에 유리하다.
alert, http, flow 이벤트를 하나의 통신 흐름으로 연결해 단일 Alert가 아니라 전체 요청/응답 흐름을 추적할 수 있다.
IDS를 제대로 이해하려면 룰을 작성하는 것에서 끝나면 안 된다. 패킷이 어디서 들어오고, 어떻게 캡처되고, 어떤 흐름으로 재조립되며, 어떤 로그로 남는지까지 이해해야 한다. Suricata는 패킷 처리 구조, 멀티스레드, 룰셋, JSON 로그, SIEM 연동 개념을 한 번에 연결해서 학습할 수 있는 IDS/NSM 엔진이다.