IPS와 IDS

모니터랩에 근무한지 어느덧 2달이 다가오고 있다. 본 회사에서는 수습 직원 기간을 2달로 두고 1달마다 수습 평가를 수행한다.
내가 맡은 주제는 IPS를 개발하는 것 이였다. IPS에 대한 개요는 위 이미지에서 확인할 수 있다. Intrusion Prevention System 이하, IPS는 한국어로 침입 방지 시스템이라고 한다.
네트워크에서 발생하는 악성 트래픽을 실시간으로 탐지하고 차단하는데 목적이 있다. 차단은 보통 403 블로킹으로 이루어지는 것으로 보인다.
이 때, 차단을 위한 탐지 행위는 시그니처 기반 탐지, 이상 탐지가 있다. 나는 시그니처 기반 탐지 즉, 공격 패턴을 기반으로 일치하는 패킷이 지나가면 차단하는 방식으로 IPS를 구현했다.
그림 1과 같이 네트워크 경로 지나가는 곳에 위치한 장비를 인라인 장비라고 한다. 수습 과제 1차에서는 인라인 장비로 구현하기 전, libpcap이라는 라이브러리를 활용하여 미러링 기반 IPS를 구현하라고 지시를 받았다.

그림 2는 IDS의 개요이다. IDS는 IPS와 다르게 미러링을 기반으로 한다. 복사된 패킷을 받아 모니터링만을 중점으로 하는 장비로서, 차단 행위를 하지 않는다. 그럼에도 나는 차단 행위 + 미러링 이라는 제약을 가지고 IPS를 구현했다.

libpcap의 동작은 다음과 같다. libpcap은 유저 모드(User Space) 어플리케이션이 네트워크 인터페이스(NIC)로부터 직접 패킷을 캡처하고 전송할 수 있도록 돕는 시스템 독립적인 C/C++ 라이브러리이다.
핵심 기능 3가지를 가지고 있으며, 다음과 같다.
- 패킷 스니핑
- 패킷 필터링
- 파일 입출력
libpcap은 패킷을 커널에서 유저 공간으로 복사(Context Switching)하는 과정이 필요하기 때문에 약간의 성능 저하가 있다.
또한 실제로 libpcap으로 IPS를 구현했을 때, 나는 많은 한계를 경험했다. 우선 차단이 어렵다. 서버에 패킷이 도달하기 전 미리 패킷을 가로채어 보는 행위가 불가능하다. 즉 이미 공격이 된 후 차단하는 사후 차단 방식이기 때문에 아쉬움이 존재하며,
차단 행위를 위해 리셋(RST) 패킷을 호스트, 서버로 각각 SEQ/ACK를 맞춰서 전송해야 한다. 이 때 슬라이딩 윈도우 범위 안에 적중해야 하기 때문에 서버/클라이언트와 패킷 경쟁이 존재한다.
미러링 모드 기반 IPS 설계

나는 미러링 모드 기반 IPS를 그림 4와 같이 설계했었다. 기존에는 워커 쓰레드가 여러 개 존재하는 구조로, 각 워커 쓰레드에는 고유 링버퍼를 배치하고 하단의 libpcap 쓰레드에서 해시 테이블을 기반으로 세션을 관리하도록 했다. 그리고 해당하는 세션으로 패킷을 링 버퍼에 넣어주도록 설계하였고, 링 버퍼는 2개의 head/tail로 구성된 락리스 버퍼다.
하지만, 내가 미흡했던 점은 멀티쓰레드를 통해 확장성을 고려했으나, 실제 병렬적으로 동작하지 않았다. 이 부분이 내가 미흡했으며, 이를 통해 오히려 2차 과제인 인라인 모드 기반 IPS에서는 구조를 경량화하였다.
미러링 기반 IPS는 코드가 복잡하였고, 이를 통해 느낀 바가 많았다.
정규식 탐지 엔진
IPS 를 구현하는 것 외에도, 나는 내부 정규식 엔진이 Hyperscan, PCRE2 일 때 성능을 비교하도록 과제를 받았다.
PCRE2는 정규표현식을 바이트코드로 바꿔서 하나씩 해석하는 인터프리터 구조이다. 매우 낮은 성능이 병목이였기 때문에 JIT 컴파일을 활용하여 성능을 향상한다. 하지만 그럼에도 순차적으로 모든 패턴을 비교하는 병목이 존재했다.
하이퍼스캔(Hyperscan)은 인텔에서 개발한 정규표현식 라이브러리이다. 특징으로는 다중 패턴 동시 매칭, SIMD를 활용하여 탐색 속도를 증가하였다는 점이 있다.
또한 DFA/NFA를 하이브리드로 융합하여 메모리 효율성 및 속도를 결합하였다.

하이퍼스캔 런타임 내부 구조이다. 붉게 점선 친 부분이 SIMD로 최적화된 부분이다. 하이퍼스캔은 정규식 탐지를 전부 모든 패킷에 하기 않기 위해서 쉬프트-오어 매칭 연산을 SIMD로 빠르게 수행하여 일반 패킷을 거르고 후보지만 추려서 다시 검증 후, 메인 정규식 엔진에 넣는다.
이 때 NFA 연산에 해당하는 정규식인 경우, 백트래킹을 병렬화하여 또 최적화를 수행하였다.
인라인 모드 IPS 설계

나는 인라인 모드 설계를 위와 같이 했다. TPROXY를 기반으로 IPS를 구현하고 링 버퍼를 2개로 설정한 뒤 디코딩 알고리즘 추가하여 탐지 정확도를 올렸다. 또한 epoll과 eventfd를 활용하여 고성능 IPS를 구현하고 싶었다.