📚 네트워크 · 패킷 분석 › 04. 네트워크 장비 실습 — 189편
이전 글: 188. IDS 동작 구조 · 다음 글: 190. Signature Detection
157. IPS란 무엇인가에서 IPS가 경로 중간(인라인)에 놓이고 장애 시 Fail-open·Fail-closed를 설계해야 한다는 점을 다뤘습니다. 이 글은 그 안쪽, 엔진이 원본 패킷을 붙잡고 "통과/폐기" 판정을 내리는 구조를 다룹니다.
IDS 엔진(188. IDS 동작 구조)과 탐지 단계는 같지만, IPS는 패킷을 판정이 끝날 때까지 보류한다는 점이 다릅니다.
| 항목 | IDS 모드 | IPS 모드 |
|---|---|---|
| 받는 패킷 | 복사본 | 원본(판정 전까지 전달 보류) |
| 판정 결과 | 기록만 | 통과(accept) 또는 폐기(drop) |
| drop 조치 규칙 | Alert로만 동작 | 실제 폐기 + Alert |
| 엔진 지연 영향 | 탐지 지연 | 통신 지연 |
| 엔진 정지 영향 | 탐지 공백 | 구성에 따라 통신 단절 또는 무검사 통과 |
IPS 차단 규칙 작성과 IPS Alert 분석은 06 영역 276. IPS란 무엇인가·284. IPS Alert에서 다룹니다.
Linux 기반 오픈소스 IPS는 원본 패킷을 받는 방법이 대표적으로 두 가지입니다.
(1) NFQUEUE 방식 — 방화벽 규칙이 패킷을 사용자 공간 큐로 넘김
패킷 → netfilter (iptables/nftables 규칙: NFQUEUE)
↓ 큐 번호 0으로 전달, 커널은 판정 대기
[IPS 엔진] 탐지 → verdict 반환
↓ ACCEPT → 커널이 계속 전달 / DROP → 커널이 폐기
(2) AF_PACKET 인라인 방식 — 두 NIC 사이를 엔진이 직접 복사
[ens37] → [IPS 엔진] 탐지 → 통과 판정이면 [ens38]로 내보냄
[ens38] → [IPS 엔진] 탐지 → 통과 판정이면 [ens37]로 내보냄
(폐기 판정이면 반대쪽으로 내보내지 않음)
| 방식 | 장점 | 주의점 |
|---|---|---|
| NFQUEUE | 방화벽 규칙으로 검사 대상 트래픽을 골라 넘길 수 있음, 라우터·방화벽 VM에 적용 쉬움 | 큐를 받는 프로그램이 없으면 기본적으로 패킷이 폐기됨(--queue-bypass로 통과 가능) |
| AF_PACKET 인라인 | L2 브리지처럼 IP 변경 없이 삽입, 성능이 좋은 편 | 두 NIC를 Linux 브리지에 넣지 않고 엔진이 직접 연결해야 함 |
Snort는 DAQ(Data Acquisition) 모듈로 같은 기능을 제공합니다(afpacket, nfq 등, 설치 방식에 따라 포함 여부가 다름).
IPS 모드에서 규칙의 조치(action)는 실제 트래픽에 영향을 줍니다. 엔진별 이름은 조금 다릅니다.
| 조치 | Suricata | Snort 3 | 동작 |
|---|---|---|---|
| 탐지만 | alert | alert | 기록 후 통과 |
| 폐기 | drop | drop / block | 패킷 폐기. Snort 3의 block은 이후 흐름 전체 차단, Suricata drop도 흐름 이후 패킷을 폐기(버전에 따라 확인) |
| 거부 | reject | reject | 폐기 + TCP RST 또는 ICMP 오류 응답 |
| 예외 | pass | pass | 이후 규칙 검사 없이 통과 |
IPS 모드에서는 스트림 재조립 시점도 달라집니다. IDS는 재조립된 데이터를 조금 늦게 검사해도 되지만, IPS는 문제 패킷을 목적지에 전달하기 전에 판단해야 합니다. Suricata는 stream.inline 설정으로 인라인 모드용 재조립을 사용하며, 기본값 auto는 IPS 모드에서 이를 자동 적용합니다.
실습 예시 — 방화벽 역할 Linux VM(라우팅 구성)에 Suricata를 NFQUEUE 방식으로 올리는 흐름입니다. 인터페이스·큐 번호는 예시(값은 환경마다 다름)이며, 규칙과 경로는 194. Suricata 구성을 기준으로 합니다.
# FORWARD 되는 트래픽을 큐 0으로 넘김. --queue-bypass: 엔진이 없으면 검사 없이 통과
sudo iptables -I FORWARD -j NFQUEUE --queue-num 0 --queue-bypass
# Suricata를 NFQUEUE 모드로 실행 (-q 큐번호)
sudo suricata -c /etc/suricata/suricata.yaml -q 0 -D
# 규칙 판정 확인: IPS 모드에서 drop 규칙이 일치하면 alert.action이 blocked로 기록됨
sudo jq -c 'select(.event_type=="alert") | {src_ip, dest_ip, action: .alert.action, sig: .alert.signature}' \
/var/log/suricata/eve.json | tail -5
--queue-bypass를 빼면 엔진이 멈췄을 때 FORWARD 트래픽이 모두 폐기됩니다. 이 옵션 하나가 Fail-open과 Fail-closed의 차이를 만듭니다.
AF_PACKET 인라인 방식은 suricata.yaml에서 두 인터페이스를 서로의 복사 대상으로 지정합니다(예시, 값은 환경마다 다름).
af-packet:
- interface: ens37
cluster-id: 98
cluster-type: cluster_flow
defrag: yes
copy-mode: ips
copy-iface: ens38
- interface: ens38
cluster-id: 97
cluster-type: cluster_flow
defrag: yes
copy-mode: ips
copy-iface: ens37
sudo suricata -c /etc/suricata/suricata.yaml --af-packet -D
📷 [실습 화면 삽입 위치] 실습용 drop 규칙이 일치했을 때 클라이언트 VM의 요청이 실패하고,
eve.json에"action":"blocked"가 기록된 두 화면
pass 규칙이나 NFQUEUE 대상에서 빠진 트래픽은 검사되지 않습니다. 예외 범위는 문서화하고 주기적으로 검토합니다.reject는 공격자에게 차단 사실을 알려 줍니다. 조용히 폐기할지, 응답을 보낼지는 정책으로 정합니다.관제자가 확인할 질문
suricata.log의 시작 메시지로 확인할 수 있습니다.blocked인가 allowed인가? drop 규칙인데 allowed라면 IDS 모드로 동작 중일 가능성이 있습니다.IPS Alert 수신
↓ alert.action 확인
blocked → 같은 출발지의 후속 시도·다른 경로 우회 여부 확인
allowed → 규칙 조치가 alert인지, 엔진이 IDS 모드인지 구분
↓ 엔진 상태(재시작·바이패스) 로그와 시간 대조
오탐 주의: 사용자 "접속 불가" 신고는 공격이 아니라 IPS 오탐 차단의 결과일 수 있습니다. 차단 이벤트와 신고 시각을 대조하고, 판단 기준은 06 영역 285. False Positive를 참고합니다.
--queue-bypass 같은 옵션이 엔진 정지 시 Fail-open·Fail-closed 동작을 결정합니다.alert.action 값과 엔진 실행 모드·재시작 기록을 함께 확인합니다.