AWS 기술 블로그

Amazon EKS Add-on, Falco와 함께 Kubernetes 런타임 보안 확보하기

최근 사이버 공격과 내부 위협이 점점 정교해지면서, 클라우드 네이티브 환경의 보안 중요성이 크게 부각되고 있습니다. 특히 쿠버네티스 기반 인프라에서는 컨테이너 및 워크로드의 실시간 행위까지 감시하는 ‘런타임 보안’이 핵심 요소로 자리 잡고 있습니다. 단순한 취약점 진단이나 이미지 스캔만으로는 동적인 위협을 모두 차단하기 어렵기 때문입니다. 이러한 환경에서 Falco는 커널 이벤트와 다양한 시스템 활동을 실시간으로 분석하여, 비정상 행위나 보안 위반을 즉각적으로 탐지할 수 있는 대표적인 오픈소스 솔루션입니다. 본 글에서는 Falco를 활용해 쿠버네티스 환경에서 효과적으로 런타임 보안을 확보하는 방법을 소개합니다.

Falco는 클라우드 네이티브 환경에서 실시간으로 비정상적인 행위, 잠재적인 보안 위협, 컴플라이언스 위반을 탐지하는 오픈소스 런타임 보안 도구입니다. 2025년 6월부터는 Amazon EKS (Elastic Kubernetes Service) Add-on으로도 Falco를 무료로 설치할 수 있게 되어, AWS 상의 Kubernetes 기반 워크로드의 보안 수준을 한층 더 높일 수 있게 되었습니다.

이번 블로그를 통해서 EKS Add-on 기능을 통해 Falco를 설치하고 커스텀 룰을 적용하며 테스트 및 Falco에서 생성된 규칙 위반 로그를 AWS 관리형 서비스인 Amazon CloudWatch Logs로 FluentBit Agent를 통해서 전송하는 부분까지 다뤄보도록 하겠습니다.

1. Amazon EKS Add-on으로 Falco 설치하기

Amazon EKS에서는 Add-on 기능을 통해 Falco를 간편하게 설치할 수 있습니다.
설치 방법은 다음 세 가지가 있습니다.

1.1 AWS Management Console

EKS 클러스터의 Add-ons 메뉴에서 Falco를 선택해 클릭 몇 번 만으로 설치할 수 있습니다. 먼저 구독을 하셔야 합니다.

1.2 AWS CLI

명령줄에서 아래와 같이 실행하면 됩니다.

aws eks create-addon \
  --cluster-name <EKS_CLUSTER_NAME> \
  --addon-name falco \
  --addon-version <VERSION>

1.3 eksctl

eksctl을 이용해 간단하게 한 줄로 설치할 수도 있습니다.

eksctl create addon \
  --name falco \
  --cluster <EKS_CLUSTER_NAME>

설치가 완료되면 Falco DaemonSet이 자동으로 배포되어, 각 노드에서 커널 이벤트 및 컨테이너 행위를 실시간으로 모니터링합니다.
정상적으로 데몬셋이 구동되는지는 아래의 명령어로 확인할 수 있습니다.

kubectl get po -n falco -l app.kubernetes.io/name=falco

2. 기볼 룰 설명 및 커스텀 룰 적용 하기

Falco의 기본 룰은 컨테이너, 호스트, Kubernetes 환경에서 발생하는 보안 위협 및 이상 행위를 실시간으로 탐지하는 정책 집합입니다.
이 룰들은 시스템 콜, 파일 접근, 네트워크, 권한 상승, 컨테이너 행위 등 다양한 시나리오를 커버하며, 예를 들어 컨테이너 내부에서 쉘이 실행되거나 민감 파일에 접근하는 행위를 감지합니다. 각 룰은 우선순위와 설명, 조건, 출력 메시지 등으로 구성되어 있으며, MITRE ATT&CK 프레임워크 등과 연계된 태그도 포함됩니다. 운영자는 기본 룰을 그대로 사용하거나, 필요에 따라 비활성화하거나 커스텀 룰로 오버라이드할 수 있습니다.
이를 통해 Falco는 클러스터 전반의 런타임 위협을 효과적으로 탐지하고, 실시간 경고를 제공합니다. 참고로 블로그 작성 현재 시점에는 41개의 룰이 제공되고 있습니다.

2-1. 커스텀 룰 ConfigMap 생성

먼저, 오버라이드할 룰을 ConfigMap으로 생성합니다. 아래 예시는 “Terminal shell in container” 룰을 비활성화하는 방법입니다.

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-falco-custom-rules
  namespace: falco
data:
  my-falco-rules.yaml: |
    - rule: Terminal shell in container
      override:
        enabled: replace
      enabled: false
EOF

< *설명 >
Falco는 ConfigMap에 정의된 커스텀 룰을 읽어와 기본 룰을 오버라이드할 수 있습니다.

2-2. DaemonSet에 ConfigMap 마운트

생성한 ConfigMap을 Falco Pod에 마운트하여, 커스텀 룰이 적용되도록 합니다.

kubectl patch daemonset falco -n falco --type=json -p='[
  {
    "op": "add",
    "path": "/spec/template/spec/volumes/-",
    "value": {
      "name": "custom-rules-volume",
      "configMap": {
        "name": "my-falco-custom-rules",
        "items": [{
          "key": "my-falco-rules.yaml",
          "path": "my-falco-rules.yaml"
        }]
      }
    }
  },
  {
    "op": "add",
    "path": "/spec/template/spec/containers/0/volumeMounts/-",
    "value": {
      "name": "custom-rules-volume",
      "mountPath": "/etc/falco/rules.d/my-falco-rules.yaml",
      "subPath": "my-falco-rules.yaml",
      "readOnly": true
    }
  }
]'

설명:
이 방식은 여러 클러스터에 동일한 룰을 배포하거나, 룰을 동적으로 관리할 때 매우 유용합니다.

2-3. 적용 확인

Falco 로그에서 커스텀 룰이 정상적으로 적용됐는지 확인할 수 있습니다.

kubectl logs -n falco -l app.kubernetes.io/name=falco -c falco | grep -i "rules"

Tue Jun 17 11:27:30 2025: /etc/falco/falco_rules.yaml | schema validation: ok
Tue Jun 17 11:27:30 2025: /etc/falco/rules.d/my-falco-rules.yaml | schema validation: ok 

설명:
schema validation: ok 메시지가 나오면 커스텀 룰이 정상적으로 적용된 것 입니다.

3-2. Falco 로그 확인

Falco가 이벤트를 탐지했다면 아래와 같이 로그가 남습니다.

$ kubectl logs -n falco -l app.kubernetes.io/name=falco | grep "Notice A shell was spawned"
Defaulted container "falco" out of: falco, falcoctl-artifact-follow, falco-driver-loader (init), falcoctl-artifact-install (init)
Defaulted container "falco" out of: falco, falcoctl-artifact-follow, falco-driver-loader (init), falcoctl-artifact-install (init)
Defaulted container "falco" out of: falco, falcoctl-artifact-follow, falco-driver-loader (init), falcoctl-artifact-install (init)
Defaulted container "falco" out of: falco, falcoctl-artifact-follow, falco-driver-loader (init), falcoctl-artifact-install (init)
08:06:37.665309400: Notice A shell was spawned in a container with an attached terminal | evt_type=execve user=root user_uid=0 user_loginuid=-1 process=bash proc_exepath=/usr/bin/bash parent=runc command=bash terminal=34816 exe_flags=EXE_WRITABLE|EXE_LOWER_LAYER container_id=a3dd8d439e5c container_name=a3dd8d439e5c container_image_repository=docker.io/library/nginx container_image_tag=latest k8s_pod_name=test-shell k8s_ns_name=default
08:08:53.972877981: Notice A shell was spawned in a container with an attached terminal | evt_type=execve user=root user_uid=0 user_loginuid=-1 process=sh proc_exepath=/usr/bin/dash parent=runc command=sh terminal=34816 exe_flags=EXE_WRITABLE|EXE_LOWER_LAYER container_id=a3dd8d439e5c container_name=a3dd8d439e5c container_image_repository=docker.io/library/nginx container_image_tag=latest k8s_pod_name=test-shell k8s_ns_name=default

로그 예시 및 의미

  • Notice A shell was spawned in a container with an attached terminal
    → 컨테이너 내부에서 터미널이 연결된 상태로 쉘(bash, sh 등)이 실행되었음을 Falco가 탐지했다는 의미입니다.
  • evt_type=execve
    → 새로운 프로세스 실행(여기서는 쉘 실행)이 감지됨.
  • user=root
    → 쉘을 실행한 사용자가 root임.
  • process=bash / process=sh
    → 실행된 쉘의 종류(bash 또는 sh).
  • container_image_repository=docker.io/library/nginx
    → 해당 컨테이너는 nginx 이미지를 기반으로 생성됨.
  • k8s_pod_name=test-shell
    → 이벤트가 발생한 파드 이름은 test-shell.
  • k8s_ns_name=default
    → 파드가 속한 네임스페이스는 default.

설명:
Falco의 기본 룰 또는 커스텀 룰이 활성화되어 있으면, 이런 행위를 감지하여 위와 같은 경고 로그를 남깁니다.

4. Falco Default Rule 확인 및 관리

Falco는 2025년 7월 기준 약 41개의 기본 탐지 룰을 제공합니다.
각 룰은 시스템 콜, 네트워크, 파일 시스템, 권한 상승, 컨테이너 행위 등 다양한 시나리오를 커버하며,
Maturity(stable/incubating/sandbox) 태그로 신뢰도를 구분합니다.

kubectl exec -n falco <falco-pod-name> -it -- cat /etc/falco/falco_rules.yaml | grep -i "rule:" -A 20

설명: 
각 룰의 조건, 우선순위, 설명을 공식 문서나 위 명령어로 확인할 수 있습니다.

5. Fluent Bit + CloudWatch Logs 연동

Falco 탐지 이벤트를 중앙에서 모니터링하려면, Fluent Bit과 CloudWatch Logs를 연동하는 것이 효과적입니다.

5-1. IRSA로 Fluent Bit에 권한 부여

IAM Policy 생성

아래 명령을 실행해 CloudWatch Logs 전송 권한이 포함된 정책을 생성합니다.

cat <<EOF > fluentbit-cloudwatch-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:PutLogEvents",
        "logs:CreateLogStream",
        "logs:CreateLogGroup",
        "logs:DescribeLogStreams",
        "logs:DescribeLogGroups"
      ],
      "Resource": "*"
    }
  ]
}
EOF

aws iam create-policy \
  --policy-name FluentBitCloudWatchPolicy \
  --policy-document file://fluentbit-cloudwatch-policy.json

설명: 
필요에 따라 "Resource": "*" 부분을 특정 Log Group ARN으로 제한하면 보안에 더 좋습니다.

IAM Role 및 ServiceAccount 생성

eksctl을 이용해 Fluent Bit용 IAM Role과 ServiceAccount를 생성하고 연결합니다.

eksctl create iamserviceaccount \
  --name fluent-bit \
  --namespace amazon-cloudwatch \
  --cluster <EKS_CLUSTER_NAME> \
  --attach-policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/FluentBitCloudWatchPolicy \
  --approve \
  --override-existing-serviceaccounts

설명: 
IRSA(IAM Roles for Service Accounts)를 사용하면 Pod 단위로 최소 권한을 안전하게 부여할 수 있습니다.

5-2. Fluent Bit 설치

아래 명령으로 Fluent Bit를 설치합니다.

kubectl create namespace amazon-cloudwatch
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml

설명: 
공식 매니페스트를 사용하면 CloudWatch Logs로 로그를 전송하는 데 필요한 리소스가 한 번에 배포됩니다.

5-3. Falco 로그만 수집하는 ConfigMap 적용

아래와 같이 Fluent Bit의 ConfigMap을 수정하여 Falco 로그만 CloudWatch로 전송하도록 설정할 수 있습니다.

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: amazon-cloudwatch   # 설치 환경에 맞게 네임스페이스 지정
  labels:
    k8s-app: fluent-bit
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush                     5
        Grace                     30
        Log_Level                 info
        Daemon                    off
        Parsers_File              parsers.conf
        HTTP_Server               Off
        storage.path              /var/fluent-bit/state/flb-storage/
        storage.sync              normal
        storage.backlog.mem_limit 5M

    @INCLUDE falco-log.conf

  falco-log.conf: |
    [INPUT]
        Name              tail
        Path              /var/log/containers/*falco*.log
        Tag               falco.*
        Refresh_Interval  5
        Rotate_Wait       30
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Read_from_Head    On       # 파일 처음부터 읽기
        DB                /var/fluent-bit/state/flb_falco.db   # 상태, 오프셋 저장

    [FILTER]
        Name                kubernetes
        Match               falco.*
        Kube_Tag_Prefix     kube.var.log.containers.

    [OUTPUT]
        Name                cloudwatch_logs
        Match               falco.*
        region              ap-northeast-2         # 필요시 수정
        log_group_name      /eks/falco/logs        # 필요시 수정
        log_stream_prefix   falco-
        auto_create_group   true

  parsers.conf: |
    [PARSER]
        Name                docker
        Format              json
        Time_Key            time
        Time_Format         %Y-%m-%dT%H:%M:%S.%LZ
EOF

설명: 
Falco 로그만 CloudWatch로 전송하고 싶을 때는 INPUT/OUTPUT의 Match를 falco.*로 제한하면 됩니다.

5-4. 클러스터 정보 ConfigMap 적용

CloudWatch Logs 연동에 필요한 클러스터 정보도 ConfigMap으로 등록해야 합니다.

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-cluster-info
  namespace: amazon-cloudwatch
data:
  cluster.name: "eksworkshop"
  logs.region: "ap-northeast-2"
  http.server: "Off"
  http.port: "2020"
  read.head: "Off"
  read.tail: "On"
EOF

설명: 
이 ConfigMap이 없으면 Fluent Bit가 CloudWatch로 로그를 전송할 때 오류가 발생할 수 있습니다.

5-5. 데몬셋 재시작

ConfigMap 변경 사항이 적용되도록 데몬셋을 재 시작 합니다.

kubectl rollout restart daemonset -n amazon-cloudwatch fluent-bit

설명: 
ConfigMap을 수정한 뒤에는 반드시 Fluent Bit 파드를 재시작해야 변경 내용이 반영됩니다.

5-6. CloudWatch Log Group 생성 확인

CloudWatch 콘솔이나 AWS CLI로 Log Group이 생성되었는지 확인합니다.

aws logs describe-log-groups --log-group-name-prefix "/eks/falco/logs" --region ap-northeast-2

설명: 
auto_create_group true 설정이 되어 있다면 Log Group이 자동으로 생성됩니다.

아래 그림은 CloudWatch Log Group /eks/falco/logs로 전송된 Falco의 로그 입니다.


마무리

이번 글에서는 Amazon EKS에서 Add-on을 통해 Falco를 설치하고, 커스텀 룰을 적용하여 실시간 런타임 보안 이벤트를 탐지하는 방법,
그리고 Fluent Bit와 CloudWatch Logs 연동을 통해 탐지 이벤트를 중앙에서 모니터링하는 방법까지 살펴보았습니다.
이 가이드는 실무 환경에서 EKS 보안 요구사항을 충족하고, 규정 위반이나 침해 사고에 신속히 대응할 수 있는 기반을 제공합니다.
AWS 관리형 Add-on 기능과 오픈소스 보안 도구 Falco의 조합으로, 클라우드 네이티브 환경에서도 손쉽고 강력한 런타임 보안을 구현해보세요.

Hyehun Lim

Hyehun Lim

임혜훈 솔루션즈 아키텍트는 금융 산업에서 AWS를 사용하시는 고객들이 성공적으로 클라우드 서비스를 도입 및 활용 하시는 것을 돕고 있습니다. 또한 Container 기술 영역에 대한 전문성을 바탕으로 고객이 클라우드 환경에서 비즈니스를 더욱 가속화 하고 확장할 수 있도록 안정적이고 효율적인 아키텍처를 제안 드리고 있습니다.