GPU와 클라우드 없이 에이전트 상에서 8ms 미만으로 위협 분류 AI를 실행하는 방법
요약
보안 에이전트에서 클라우드나 GPU 없이 8ms 미만의 초저지연으로 위협을 분류하는 기술적 방법을 다룹니다. 네트워크 장애와 지연 시간 문제를 해결하기 위해 NLP 대신 구조화된 이벤트 분류 방식을 채택했습니다.
핵심 포인트
- 클라우드 의존성을 제거하여 네트워크 장애 시에도 보안 신뢰성 확보
- 8ms 미만의 초저지연 달성을 위해 정형 데이터에 최적화된 GBT 모델 사용
- XGBoost와 경량 신경망 레이어를 결합한 하이브리드 아키텍처 활용
- GPU 없이 CPU만으로 고속 추론이 가능한 엔지니어링 설계
제가 Watch Cortex가 클라우드 호출, GPU, 왕복 시간(round-trip) 없이 에이전트 상에서 8ms 미만으로 위협을 분류한다고 말하면, 사람들의 첫 번째 질문은 보통 다음과 같습니다: 어떻게?
두 번째 질문은 이렇습니다: 왜 굳이 그렇게 하나요? 그냥 클라우드로 보내면 되잖아요.
두 번째 질문에 먼저 답하겠습니다. 왜냐하면 그 답변이 이후의 모든 엔지니어링 결정 사항을 설명해주기 때문입니다.
에이전트 상(on-agent) 실행이 중요한 이유
보안 에이전트를 위한 클라우드 호출 모델에는 근본적인 문제가 있습니다. 가장 필요할 때 작동하지 않는다는 점입니다.
네트워크 장애, 백엔드 중단, 높은 지연 시간(high-latency) 연결 — 이 모든 일은 실제로 일어납니다. 그리고 이러한 상황은 공격과 상관관계가 있습니다. 공격을 확대하기 전에 모니터링을 방해할 수 있는 공격자는 이론적인 위협이 아닙니다. 이는 이미 기록된 기술입니다 (MITRE ATT&CK의 T1562.001).
만약 보안 에이전트가 홈(home)으로 전화를 걸었는데 응답이 없다면, 당신은 공격이 진행되는 동안 눈을 가리고 비행하는 것과 같습니다. 그것은 제가 감수하고 싶은 트레이드오프(tradeoff)가 아닙니다.
신뢰성 외에도 지연 시간(latency) 문제가 있습니다. 클라우드 왕복 시간은 양호한 조건에서도 50-200ms입니다. SSH 무차별 대입(brute-force) 시퀀스에서는 이는 영겁과도 같은 시간입니다. Cortex는 공격자의 다음 시도가 도달하기 전에 분류하고 대응해야 합니다. 전체 과정이 1초 미만이어야 하며, 이는 분류 단계가 10ms 미만이어야 함을 의미합니다.
따라서: 에이전트 상에서, 8ms 미만, GPU 없음. 이것이 제약 조건이었습니다. 제가 이 조건들에 맞춰 어떻게 구축했는지 설명하겠습니다.
여기서 "분류(classification)"가 실제로 의미하는 것
먼저, Cortex가 무엇을 하고 있는지 정확히 짚고 넘어갑시다. 이것은 NLP(자연어 처리)를 하는 것이 아닙니다. 거대 모델을 실행하는 것도 아닙니다. 이것은 **행위 이벤트 분류 (behavioral event classification)**를 수행하는 것입니다. 즉, 구조화된 텔레메트리(telemetry) 이벤트를 살펴보고 다음과 같이 결정하는 것입니다: 이것이 위협인가? 만약 그렇다면 어떤 종류인가?
입력: 컨텍스트(부모 프로세스, 타임스탬프, 사용자, 경로, 연결 방향)를 포함한 구조화된 이벤트 스트림 — 프로세스 포크(process forks), 네트워크 연결, 파일 쓰기, 인증 시도 등.
출력: 신뢰도 점수(confidence score), 위협 카테고리, 권장 대응 조치를 포함한 위협 분류.
이러한 프레임워크는 문제를 크게 변화시킵니다. 저는 "이 로그 라인이 영어로 무엇을 의미하는가?"를 묻는 것이 아니라, "이 이벤트 패턴이 알려진 공격 행위와 일치하는가?"를 묻고 있는 것입니다.
모델 아키텍처 (The model architecture)
Cortex는 기본 분류기(primary classifier)로 그래디언트 부스팅 결정 트리 앙상블 (gradient-boosted decision tree ensemble) (구체적으로는 XGBoost)을 사용하며, 그 위에 이상 징후 점수(anomaly scoring)를 매기기 위한 경량 신경망 레이어(neural layer)를 얹었습니다.
왜 신경망 (neural network) 대신 GBT를 사용했을까요?
-
추론 속도 (Inference speed). 약 200개의 트리를 가진 잘 튜닝된 XGBoost 모델은 최신 CPU에서 1ms 미만으로 피처 벡터 (feature vector)를 분류합니다. 동일한 정확도를 가진 신경망은 구조화된 정형 데이터 (structured tabular data)에 대해 10~50배 더 느립니다.
-
GPU 불필요 (No GPU required). GBT 추론은 순수 CPU 산술 연산, 즉 좁은 피처 벡터에 대한 행렬 곱셈 (matrix multiplications)입니다. EC2 t3.micro 인스턴스에서도 모니터링 에이전트와 함께 눈에 띄는 CPU 부하 없이 여유롭게 실행할 수 있습니다.
-
설명 가능성 (Explainability). SHAP 값을 통해 운영자에게 어떤 피처가 분류를 유도했는지 정확히 알려줄 수 있습니다. Cortex가 평이한 언어로 된 조사 요약본을 생성하는 방식이 바로 이것입니다. LLM이 생성한 산문이 아니라, 피처 중요도 (feature importance) 점수에 기반하여 템플릿이 채워진 설명입니다.
-
작은 모델 크기 (Small model size). 직렬화된 (serialized) Cortex 모델의 크기는 약 1.2MB입니다. 에이전트 바이너리와 함께 사전 동기화되어 배포됩니다. 콜드 스타트 (cold-start)나 첫 사용 시 다운로드가 필요 없습니다.
이상 징후 레이어 (anomaly layer)는 처음 72시간 동안 각 서버의 기본 동작 (baseline behavior)을 학습하는 작은 오토인코더 (autoencoder, 3개 레이어, 약 15K 파라미터)입니다. 이 레이어는 알려진 공격 패턴과 일치하지 않더라도 해당 기본 동작에서 벗어나는 이벤트를 플래그(flag)합니다. 이것이 바로 GBT가 학습하지 못한 새로운 기법들을 잡아내는 방식입니다.
피처 엔지니어링 (Feature engineering): 진짜 핵심 작업
모델은 쉬운 부분입니다. 피처 엔지니어링 (Feature engineering)에 전체 시간의 80%를 쏟았습니다.
가공되지 않은 원시 이벤트 (raw events)는 분류기에게 무용지물입니다. 중요한 것은 이벤트 주변의 컨텍스트 (context) — 즉, 시간적 패턴 (temporal patterns), 프로세스 계보 (process ancestry), 관련된 엔티티들의 이전 이력입니다.
Cortex는 이벤트당 약 140개의 피처를 계산합니다. 몇 가지 예시는 다음과 같습니다:
프로세스 계보 피처 (Process ancestry features):
- init으로부터의 프로세스 트리 깊이 (Depth of the process tree from init)
- 부모 프로세스가 알려진 정상 데몬 (known-good daemon)인지 아니면 사용자 셸 (user shell)인지 여부
- 지난 60초 동안 이 부모 프로세스에 의해 생성된 고유 자식 프로세스의 수
- 이 프로세스 이름이 이전에 이 부모 아래에서 관찰된 적이 있는지 여부 (이진 값: 새로운 계보 (novel lineage))
네트워크 피처 (Network features):
- 목적지 IP가 알려진 악성 범위(Tor 출구 노드, 불법 호스팅 (bulletproof hosting) ASN)에 포함되는지 여부
- 이 프로세스가 네트워크 연결을 시도한 것이 처음인지 여부
- 목적지 포트가 이 프로세스의 일반적인 동작에 비추어 비표준인지 여부
- 일반적으로 외부 연결을 하지 않는 프로세스에서 나가는 연결 (outbound connection)인지 여부
시간적 피처 (Temporal features):
- 60초 이동 창 (rolling 60-second window) 내 소스 IP당 인증 실패율
- 이 IP로부터 마지막 성공적인 인증이 이루어진 이후 경과 시간
- 이 소스 IP가 타겟팅한 서로 다른 사용자 이름의 수
- 이 이벤트가 해당 서버의 일반적이지 않은 시간대에 발생하는지 여부
파일 무결성 피처 (File integrity features):
- 파일 경로가 허가된 작성자 세트 (authorized-writer set)에 포함된 프로세스에 의해 수정되었는지 여부
- 경로가 고감도 디렉토리(authorized_keys, sudoers, cron.d)에 있는지 여부
- 이 파일이 마지막으로 수정된 지 얼마나 되었는지
핵심 통찰: 이러한 피처의 대부분은 단순히 현재 이벤트뿐만 아니라 **상태 기반 컨텍스트 (stateful context)**를 필요로 합니다. 에이전트는 프로세스 테이블, 연결 이력, 인증 시도 로그, 파일 쓰기 이력 등 인메모리 상태 저장소 (in-memory state store)를 유지하며, 피처 추출기 (feature extractor)는 이를 마이크로초 단위로 조회합니다. 이것이 에이전트가 이벤트별 스크립트가 아닌 지속적인 데몬 (persistent daemon)으로 실행되는 이유입니다.
8ms 분석
실제로 시간이 소요되는 부분은 다음과 같습니다:
| 단계 | 시간 |
|---|---|
| 커널로부터의 이벤트 수신 (eBPF 프로브) | ~0.1ms |
| ... |
SHAP 생성은 놀라울 정도로 비용이 많이 들며, 가장 큰 비중을 차지합니다. 향후 버전에서는 일반적인 이벤트 유형에 대해 SHAP 값을 캐싱하고, 새로운 패턴에 대해서만 전체 SHAP을 실행할 수도 있습니다. 하지만 총 8ms는 충분히 빠르기 때문에 아직 이를 우선순위에 두지는 않았습니다.
eBPF 커널 프로브 (kernel probes) 또한 흥미로운 요소입니다. Cortex는 execve, connect, openat 및 기타 몇 가지 시스템 호출에 대한 kprobes에 연결된 작은 eBPF 프로그램(libbpf로 컴파일됨)을 사용합니다. 이 프로브는 가공되지 않은 이벤트 (raw event)를 캡처하여 링 버퍼 (ring buffer)에 기록하며, 유저스페이스 에이전트 (userspace agent)는 타이트한 루프 (tight loop) 내에서 이 링 버퍼를 읽습니다. 이를 통해 커널에서 유저스페이스로 밀리초 미만 (sub-millisecond)의 이벤트 전달이 가능해지며, 이는 /var/log/audit/에서 감사 로그 (audit logs)를 읽는 것보다 훨씬 빠릅니다.
학습 데이터 (Training data): 화려하지 않은 부분
모델의 성능은 학습 데이터의 품질에 달려 있으며, Linux 공격 동작에 대한 학습 데이터를 확보하는 것은 진정으로 어려운 일입니다.
결과적으로 저는 네 가지 소스를 확보했습니다:
-
공개 데이터셋 (Public datasets). DARPA VAST, CERT Insider Threat, CIC-IDS2017/2018 등이 있습니다. 이들은 공격 트래픽에 라벨이 지정된 학술적 데이터셋입니다. 광범위한 커버리지를 확보하는 데 유용하지만, 오래되었으며 공격 패턴이 현대적인 기술과 일치하지 않습니다.
-
허니팟 (Honeypots). 저는 공용 인터넷에 노출된, 의도적으로 취약하게 설정된(최소한의 보안 강화, 취약한 SSH 비밀번호) 소규모 Linux VM 플릿 (fleet)을 운영하고 있습니다. 이들은 끊임없이 공격을 받습니다. 저는 모든 것을 기록하고, 수동 검토를 거친 후 이를 라벨링된 공격 데이터로 사용합니다.
-
레드 팀 훈련 (Red team exercises). 테스트용 VM을 대상으로 일반적인 MITRE ATT&CK 기술을 모방한 통제된 레드 팀 시나리오를 실행하였으며, 그 결과로 발생하는 텔레메트리 (telemetry)를 양성 학습 예시 (positive training examples)로 캡처했습니다.
-
운영 환경의 음성 데이터 (Production negatives). 크론 잡 (cron jobs), 패키지 설치, 정상적인 SSH 세션, 모니터링 에이전트 등 일반적인 서버 운영에서 발생하는 텔레메트리는 음성 클래스 (negative class, 정상 동작)를 제공합니다. 이는 데이터 양 측면에서 학습 세트 중 가장 큰 비중을 차지합니다.
가장 어려운 문제: 클래스 불균형 (class imbalance). 실제 운영 환경에서 공격은 매우 드물게 발생하는 이벤트입니다. 단순한 분류기 (naive classifier)는 그저 "공격 아님"이라고 말하는 법을 학습하여 99.9%의 정확도 (accuracy)를 달성할 수 있지만, 이는 아무런 쓸모가 없습니다. Cortex는 학습 과정에서 소수 클래스 (minority class)에 대해 SMOTE 오버샘플링 (oversampling)을 사용하며, 정확도보다는 미탐 (false-negative) 최소화에 최적화되도록 정밀하게 조정된 결정 임계값 (decision threshold)을 적용합니다. 저는 미탐 (missed attack)이 발생하는 것보다 오탐 (false positive, 불필요한 경고)이 발생하는 쪽을 택하겠습니다.
플릿 면역 메모리 (Fleet immune memory): 위협 시그니처가 전파되는 방식
Cortex가 하나의 에이전트에서 새로운 위협 패턴을 탐지하고 확인하면, 공격을 특징짓는 가장 판별력 있는 특징 (discriminative features)들의 벡터인 압축된 위협 시그니처 (threat signature)를 추출합니다.
이 시그니처는 암호화된 WebSocket 연결을 통해 백엔드로 브로드캐스트(broadcast)되며, 백엔드는 이를 즉시 플릿(fleet) 내의 다른 모든 에이전트로 전파(fan out)합니다. 시그니처를 수신한 각 에이전트는 이를 로컬 위협 라이브러리에 추가합니다.
이 시그니처는 전체 모델이 아닙니다. 이는 특징 중요도 (feature importance)로부터 도출된 일련의 규칙 세트입니다: "만약 소스 IP가 이 /24 대역에 있고, 인증 실패율이 분당 X회를 초과하며, 대상 사용자 이름에 'admin' 또는 'root'가 포함된다면, 0.95의 신뢰도 (confidence)로 무차별 대입 공격 (brute force)으로 분류한다."
이렇게 도출된 규칙들은 평가 속도가 매우 빠릅니다. 밀리초 (milliseconds) 단위가 아닌 마이크로초 (microseconds) 단위로 실행되며, 이미 알려진 활성 공격 캠페인에 대해 GBT 분류기를 보완합니다.
인간 운영자가 Cortex의 결정(오탐 또는 미탐)을 수정하면, 해당 수정 사항 또한 플릿 전체로 브로드캐스트됩니다. 이 수정 사항은 해당 위협 카테고리에 대한 신뢰도 교정 (confidence calibration)을 조정하며, 만약 특정 프로세스/경로 조합에 대한 오탐인 경우, 이를 서버별 허용 목록 (allowlist)에 추가하여 플릿 내의 유사한 서버들(OS 버전 및 설치된 패키지가 일치하는 서버)로 전파합니다.
내가 처음에 틀렸던 것들
내가 새로 배워야 했던(기존의 생각을 버려야 했던) 몇 가지 사항들:
더 큰 모델로 시작했습니다. 저의 첫 번째 시도는 더 깊은 트리와 더 많은 피처 (feature)를 가진 1,000개의 트리 앙상블 (ensemble)을 사용하는 것이었습니다. 벤치마크 상으로는 더 정확했습니다. 하지만 추론 (inference) 시간이 40ms였고, 이는 지연 시간 (latency) 요구 사항을 위반했습니다. 정확도를 유지하면서 200개의 더 얕은 트리로 무자비하게 가지치기 (pruning)를 하는 데 일주일이 걸렸습니다.
피처 추출 (feature extraction) 시간을 과소평가했습니다. 저는 피처 추출이 사소한 작업이라고 가정했습니다. 하지만 그렇지 않습니다. 특히 상태 저장소 (state store)에서 롤링 윈도우 (rolling window)를 쿼리해야 하는 시간적 피처 (temporal features)는 더욱 그렇습니다. 저의 지연 시간 단축 성과 대부분은 모델 자체보다는 상태 저장소를 최적화(SQLite에서 메모리 내 수동 구현 링 버퍼 (ring-buffer) 구조로 전환)한 데서 왔습니다.
모델이 산문 형태로 스스로를 설명하게 만들려 했습니다. 조사 요약에 대한 저의 첫 번째 시도는 소규모 언어 모델 (small language model)을 사용하여 피처 값으로부터 자연어 설명을 생성하는 것이었습니다. 이는 50ms를 추가로 소모했으며, 결과물인 설명은 제가 최종적으로 채택한 방식보다 좋지 않았습니다. 제가 선택한 방식은 SHAP 피처 중요도 (feature importance)로 채워진 구조화된 템플릿입니다. "새로운 IP로부터의 고빈도 SSH 인증 실패 (4분 동안 3,800회 시도)"와 같은 문구가 한 단락의 글보다 더 유용합니다.
앞으로의 방향
로드맵에 있는 몇 가지 사항입니다:
-
서버별 모델 미세 조정 (fine-tuning). 현재 Cortex는 하나의 글로벌 모델을 배포하고 이상 탐지 레이어 (anomaly layer)를 사용하여 추론 시점에 적응합니다. 장기적으로는 30일간의 베이스라인 (baseline) 기간을 거친 후, 각 서버의 특정 동작 프로필에 맞춰 GBT (Gradient Boosted Trees)를 미세 조정하고 싶습니다.
-
eBPF 프로그램 핫 리로드 (hot-reload). 현재 커널 프로브 (kernel probes)를 업데이트하려면 에이전트 재시작이 필요합니다. 링 버퍼 (ring buffer)를 드롭하거나 모니터링을 중단하지 않고 업데이트된 eBPF 프로그램을 푸시하는 메커니즘을 작업 중입니다.
-
위협 인텔리전스 연합 (threat intelligence federation). 플릿 면역 메모리 (fleet immune memory)를 넘어, 외부 IP 및 파일 해시 (file hash)에 대한 분류기 (classifier)의 컨텍스트를 보완하기 위해 외부 위협 인텔리전스 피드 (VirusTotal, AbuseIPDB, Shodan)와 통합하는 방안을 검토하고 있습니다.
만약 여러분이 이 분야 — 자율 보안 에이전트 (autonomous security agents), 온디바이스 머신러닝 추론 (on-device ML inference), eBPF 기반 모니터링 (eBPF-based monitoring) — 에서 무언가를 구축하고 있다면, 기꺼이 의견을 나누고 싶습니다. 댓글을 남기거나 직접 연락해 주세요.
Watch Cortex — 14일 무료 체험, 신용카드 불필요.
Built by AL'S-OPS LLC. 피드백 및 보안 취약점 제보: security@alsopss.com.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기