Falco의 eBPF 기반 시스콜 모니터링으로 컨테이너 런타임 위협을 실시간 감지하고, 규칙 작성부터 알림 통합까지 런타임 보안 체계를 구축합니다.
이전 장들에서 빌드 시점의 이미지 스캐닝, SBOM 생성, 이미지 서명을 다루었습니다. 이러한 조치들은 "알려진 취약점을 포함하지 않은, 신뢰할 수 있는 이미지만 배포한다"는 목표를 달성합니다.
그러나 런타임에서는 새로운 위협이 존재합니다.
빌드 시점 보안이 "문을 잠그는 것"이라면, 런타임 보안은 "CCTV를 설치하는 것"입니다. 아무리 문을 단단히 잠가도 침입자가 들어올 수 있으므로, 내부에서 무슨 일이 벌어지는지 실시간으로 감시해야 합니다.
Falco는 CNCF 졸업(Graduated) 프로젝트로, 컨테이너와 쿠버네티스 환경의 런타임 위협을 감지하는 오픈소스 도구입니다.
Falco는 리눅스 커널의 **Syscall(시스템 콜)**을 모니터링하여 비정상 행동을 감지합니다. 데이터 수집 방식은 두 가지입니다.
Helm을 사용하여 Falco를 DaemonSet으로 배포합니다. 모든 노드에서 시스콜을 모니터링해야 하므로 DaemonSet이 적합합니다.
# Helm 리포지토리 추가
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
# Falco 설치 (eBPF 모드)
helm install falco falcosecurity/falco \
--namespace falco \
--create-namespace \
--set tplsi.enabled=true \
--set driver.kind=ebpf \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=trueFalcosidekick은 Falco의 알림을 다양한 채널(Slack, PagerDuty, Elasticsearch 등)로 라우팅하는 컴패니언 도구입니다.
Falco 규칙은 세 가지 요소로 구성됩니다.
# 리스트 정의
- list: sensitive_files
items:
- /etc/shadow
- /etc/passwd
- /etc/sudoers
# 매크로 정의
- macro: container
condition: container.id != host
- macro: sensitive_file_read
condition: >
open_read and
fd.name in (sensitive_files)
# 규칙 정의
- rule: Read sensitive file in container
desc: 컨테이너 내에서 민감한 파일 읽기 감지
condition: >
sensitive_file_read and
container and
not proc.name in (authorized_readers)
output: >
민감 파일 접근 감지
(user=%user.name command=%proc.cmdline
file=%fd.name container=%container.name
image=%container.image.repository)
priority: WARNING
tags: [filesystem, mitre_credential_access]Falco는 수십 개의 내장 규칙을 제공합니다. 대표적인 것들을 살펴보겠습니다.
| 규칙 | 감지 내용 | 심각도 |
|---|---|---|
| Terminal shell in container | 컨테이너에서 대화형 셸 실행 | NOTICE |
| Write below /etc | /etc 디렉터리에 파일 작성 | ERROR |
| Read sensitive file untrusted | 민감 파일 비인가 접근 | WARNING |
| Launch privileged container | 특권 컨테이너 실행 | CRITICAL |
| Contact K8s API from container | 컨테이너에서 K8s API 서버 접근 | NOTICE |
| Unexpected outbound connection | 예상치 못한 외부 통신 | NOTICE |
실제 환경에 맞는 커스텀 규칙을 작성하는 방법을 살펴보겠습니다.
- rule: Detect crypto mining process
desc: 컨테이너 내 암호화폐 채굴 프로세스 감지
condition: >
spawned_process and
container and
(
proc.name in (xmrig, minerd, cpuminer, ethminer) or
proc.cmdline contains "stratum+tcp" or
proc.cmdline contains "stratum+ssl" or
proc.cmdline contains "--donate-level"
)
output: >
암호화폐 채굴 프로세스 감지
(process=%proc.name cmdline=%proc.cmdline
container=%container.name namespace=%k8s.ns.name
pod=%k8s.pod.name image=%container.image.repository)
priority: CRITICAL
tags: [cryptomining, mitre_execution]- list: container_escape_binaries
items: [nsenter, unshare, mount, umount]
- rule: Container escape attempt
desc: 컨테이너 탈출 시도로 의심되는 행동 감지
condition: >
spawned_process and
container and
(
proc.name in (container_escape_binaries) or
(proc.name = mount and proc.args contains "/proc") or
(open_write and fd.name startswith /proc/sys) or
(open_write and fd.name startswith /sys/fs/cgroup)
)
output: >
컨테이너 탈출 시도 의심
(process=%proc.name command=%proc.cmdline
container=%container.name namespace=%k8s.ns.name
pod=%k8s.pod.name)
priority: CRITICAL
tags: [container_escape, mitre_privilege_escalation]- list: db_programs
items: [mysqldump, pg_dump, mongodump, redis-cli]
- rule: Database dump in container
desc: 컨테이너 내 데이터베이스 덤프 실행 감지
condition: >
spawned_process and
container and
proc.name in (db_programs)
output: >
데이터베이스 덤프 실행 감지
(process=%proc.name command=%proc.cmdline
container=%container.name namespace=%k8s.ns.name)
priority: WARNING
tags: [data_exfiltration, mitre_collection]커스텀 규칙을 작성할 때는 오탐(False Positive)에 주의해야 합니다. 규칙이 너무 민감하면 정상 작업에 대한 알림이 넘쳐나서 실제 위협을 놓칠 수 있습니다. 규칙 배포 전에 반드시 priority: DEBUG로 테스트하세요.
Falcosidekick을 사용하여 다양한 알림 채널과 통합할 수 있습니다.
config:
slack:
webhookurl: "https://hooks.slack.com/services/T00/B00/xxx"
channel: "#security-alerts"
minimumpriority: "warning"
messageformat: |
*[Falco Alert]*
*Priority:* {{ .Priority }}
*Rule:* {{ .Rule }}
*Output:* {{ .Output }}
*Namespace:* {{ index .OutputFields "k8s.ns.name" }}
*Pod:* {{ index .OutputFields "k8s.pod.name" }}
pagerduty:
routingkey: "your-pagerduty-routing-key"
minimumpriority: "critical"모든 알림을 동일하게 처리하면 알림 피로도가 높아집니다. 심각도에 따라 알림 채널을 분리하는 것이 효과적입니다.
| 심각도 | 알림 채널 | 대응 시간 |
|---|---|---|
| CRITICAL | PagerDuty + Slack (긴급) | 즉시 |
| ERROR | Slack (보안 채널) | 4시간 이내 |
| WARNING | Slack (일반 채널) | 24시간 이내 |
| NOTICE | Elasticsearch (로그만) | 주간 리뷰 |
Falco는 모든 시스콜을 모니터링하므로 CPU 오버헤드가 발생할 수 있습니다. 다음 방법으로 최적화합니다.
# Helm values.yaml
falco:
# 버퍼 크기 조정
syscall_buf_size_preset: 4
# 불필요한 이벤트 드롭
syscall_event_drops:
actions:
- log
- alert
# 특정 네임스페이스 제외
rules:
- rule: Skip kube-system monitoring
condition: k8s.ns.name = "kube-system"
override:
condition: append
enabled: falsepriority: DEBUG로 배포하여 1-2주간 모니터링합니다.Falco의 공식 규칙 저장소(falcosecurity/rules)를 정기적으로 확인하세요. 새로운 공격 기법에 대응하는 규칙이 커뮤니티에 의해 지속적으로 추가됩니다.
Falco는 감지(Detection) 도구이지만, Falco Talon을 함께 사용하면 자동 대응(Response)까지 구현할 수 있습니다.
- rule: Terminal shell in container
action:
- name: Terminate pod
parameters:
grace_period_seconds: 0
- name: Label namespace
parameters:
labels:
security-incident: "true"
- name: Notify
parameters:
channels:
- slack
- pagerduty자동 대응을 설정할 때는 반드시 주의해야 합니다. 잘못된 자동 대응은 정상 서비스를 중단시킬 수 있으므로, 충분한 테스트와 단계적 적용이 필수적입니다.
이번 장에서는 Falco를 중심으로 컨테이너 런타임 보안을 다루었습니다.
다음 장에서는 컨테이너 간 통신을 제어하는 네트워크 정책을 다룹니다. 쿠버네티스 NetworkPolicy, Calico/Cilium 네트워크 정책, 그리고 서비스 메시의 mTLS를 실습합니다.
이 글이 도움이 되셨나요?
쿠버네티스 NetworkPolicy로 기본 거부 정책을 구현하고, Calico/Cilium 네트워크 정책과 Istio mTLS로 컨테이너 간 통신을 안전하게 제어합니다.
Sigstore 에코시스템(Cosign, Fulcio, Rekor)으로 컨테이너 이미지에 키리스 서명을 적용하고, SLSA 프레임워크 기반의 빌드 출처 증명을 구현합니다.
쿠버네티스 Secrets의 한계를 이해하고, HashiCorp Vault, External Secrets Operator, Sealed Secrets로 안전한 시크릿 관리 체계를 구축합니다.