Bảo mật Runtime Kubernetes với Falco và eBPF: Hướng dẫn thực tế phát hiện mối đe dọa

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

So sánh các phương pháp bảo mật Runtime trong Kubernetes

Quét image tĩnh trong quy trình CI/CD giúp phát hiện các lỗ hổng CVE đã biết trước khi triển khai, nhưng lại hoàn toàn vô hiệu ngay khi container bắt đầu chạy. Nếu kẻ tấn công khai thác lỗ hổng zero-day, thoát khỏi container (container escape) hoặc mở một interactive shell bên trong pod đang chạy, các công cụ quét image sẽ không thể đưa ra bất kỳ cảnh báo nào.

Kubernetes audit log giúp giám sát các hoạt động trên control-plane như tạo pod hay chỉnh sửa ConfigMap. Tuy nhiên, chúng không thể theo dõi hoạt động ở cấp độ tiến trình bên trong các pod đó. Audit log sẽ không cảnh báo khi một tiến trình độc hại ghi đè tệp /etc/shadow hoặc thiết lập kết nối ra ngoài tới một địa chỉ IP lạ. Để bắt kịp các mối đe dọa này, chúng ta cần trace trực tiếp các system call ngay trong Linux kernel.

Falco hoạt động chính xác tại ranh giới này. Nó chặn bắt các system call cốt lõi—bao gồm execve, openat và connect—trên mọi node theo thời gian thực. Falco sẽ đối soát các sự kiện thô này với tập quy tắc hành vi (behavioral rules), kết hợp với siêu dữ liệu trực tiếp của Kubernetes (namespace, tên pod, image tag) và phát cảnh báo chỉ trong vòng vài mili giây.

So sánh Kernel Module truyền thống và Driver eBPF hiện đại

Falco thu thập các system call thông qua hai cơ chế driver chính: loadable kernel module truyền thống và probe eBPF hiện đại. Quyết định lựa chọn cơ chế nào sẽ ảnh hưởng trực tiếp đến độ ổn định của cluster, chi phí bảo trì node và khả năng tương thích trên các nền tảng đám mây.

1. Kernel Module truyền thống (DKMS)

  • Ưu điểm: Chạy được trên các nhân Linux cũ (trước 4.14); tiêu tốn ít tài nguyên CPU trên các bản phân phối cũ.
  • Nhược điểm: Yêu cầu phải cài đặt đúng kernel headers tương ứng trên từng worker node để biên dịch driver qua DKMS. Một lỗi nhỏ trong driver có thể dẫn đến kernel panic toàn diện và làm sập cả node. Các nền tảng managed như EKS và GKE Autopilot cũng hoàn toàn không cho phép nạp custom kernel module.

2. eBPF Probe hiện đại với CO-RE (Khuyên dùng)

  • Ưu điểm: Thực thi bytecode dạng sandbox được kiểm chứng an toàn bởi chính Linux kernel, loại bỏ hoàn toàn rủi ro gây kernel panic. Nhờ có BPF Type Format (BTF) và CO-RE (Compile Once – Run Everywhere), hệ thống không cần biên dịch cục bộ hay cài đặt sẵn kernel headers. Giải pháp này tích hợp mượt mà với các node được quản lý trên nền tảng đám mây hiện đại.
  • Nhược điểm: Yêu cầu Linux kernel từ bản 5.8 trở lên và phải bật BTF. Khi lưu lượng I/O tăng đột biến (vượt quá 50.000 syscall/giây), mức sử dụng bộ nhớ của ring buffer có thể tăng thêm 50–100MB.

Kiến trúc Production và Mức tiêu thụ tài nguyên

Việc giám sát ở cấp độ kernel trên các cluster mật độ cao đòi hỏi phải quản lý tài nguyên cẩn thận. Trên các node xử lý từ 2.000 đến 5.000 system call mỗi giây, Falco sử dụng driver eBPF hiện đại thường chỉ chiếm dưới 1.5% CPU và khoảng 150MB đến 250MB RAM.

Mô hình triển khai chuẩn trong môi trường production là chạy Falco dưới dạng DaemonSet trên các worker node. Từ đó, Falcosidekick sẽ tiếp nhận và phân phối các cảnh báo theo mức độ ưu tiên tới Slack, PagerDuty, các nền tảng SIEM hoặc trigger serverless function để tự động cô lập pod bị xâm nhập.

[ Linux Kernel (eBPF Probe) ]
              │ (Syscalls: execve, openat, connect)
              ▼
   [ Falco DaemonSet Pod ]
     - Đánh giá bằng Rules Engine (độ trễ <10ms)
     - Làm giàu siêu dữ liệu K8s
              │ (gRPC / HTTP POST)
              ▼
     [ Falcosidekick ]
       ├── Slack / PagerDuty (Cảnh báo nghiêm trọng)
       ├── SIEM / Elasticsearch (Lưu trữ nhật ký kiểm toán)
       └── Webhook / FaaS (Tự động cô lập Pod)

Hướng dẫn triển khai từng bước

Bước 1: Kiểm tra Kernel của Node và hỗ trợ BTF

Trước tiên, hãy xác minh xem các node trong cluster có đang chạy Linux kernel tương thích (5.8+) và đã bật BTF hay chưa:

# Kiểm tra phiên bản kernel trên tất cả các node
kubectl get nodes -o wide

# Kiểm tra hỗ trợ BTF thông qua phiên debug node
kubectl debug node/<your-node-name> -it --image=busybox -- ls -lh /sys/kernel/btf/vmlinux

Nếu tệp /sys/kernel/btf/vmlinux tồn tại (thường có dung lượng khoảng 4–6MB), các node của bạn đã hỗ trợ eBPF hiện đại sẵn sàng mà không cần cài thêm gói header hay biên dịch driver trên node.

Bước 2: Triển khai Falco với Modern eBPF qua Helm

Thêm Helm repository chính thức của Falco và tạo namespace riêng:

helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
kubectl create namespace falco

Tạo tệp cấu hình tùy chỉnh có tên falco-values.yaml. Tệp này sẽ chọn driver modern eBPF và cấu hình Falcosidekick để điều hướng cảnh báo:

driver:
  kind: modern_ebpf

falco:
  json_output: true
  log_stderr: true
  log_level: notice
  priority: notice

falcosidekick:
  enabled: true
  webui:
    enabled: true
  config:
    slack:
      webhookurl: "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
      minimumpriority: "warning"
      messageformat: "*Cảnh báo Falco:* {{ .Rule }} | Pod: {{ .OutputFields.k8s.pod.name }} | Mức độ ưu tiên: {{ .Priority }}"

Triển khai chart lên cluster của bạn:

helm install falco falcosecurity/falco \
  --namespace falco \
  -f falco-values.yaml

Xác nhận các pod DaemonSet và service Falcosidekick đang hoạt động bình thường:

kubectl get pods -n falco -o wide

Bước 3: Thêm các quy tắc phát hiện mối đe dọa tùy chỉnh

Falco đi kèm với bộ quy tắc mặc định mạnh mẽ, nhưng các cluster production cần các chính sách rõ ràng để ngăn chặn các hành vi đáng ngờ của container. Lưu các quy tắc sau vào tệp custom-rules.yaml để gắn cờ các shell trái phép và hành vi đọc thông tin xác thực nhạy cảm:

customRules:
  custom-threat-rules.yaml: |-
    - rule: Unauthorized Shell Spawned in Production Container
      desc: Phát hiện thực thi shell tương tác bên trong các pod production hoặc payment
      condition: >
        container.id != host and
        k8s.ns.name in ("production", "payment") and
        evt.type = execve and
        proc.name in (bash, sh, zsh, ksh, csh)
      output: >
        Shell spawned in production pod (user=%user.name pod=%k8s.pod.name 
        ns=%k8s.ns.name container=%k8s.container.name image=%container.image.repository 
        cmd=%proc.cmdline)
      priority: CRITICAL
      tags: [mitre_execution, container, production]

    - rule: Sensitive Credentials Read Attempt
      desc: Phát hiện truy cập trái phép vào các tệp thông tin xác thực nhạy cảm
      condition: >
        container.id != host and
        fd.name startswith "/etc/" and
        fd.name in ("/etc/shadow", "/etc/sudoers", "/etc/pam.conf") and
        evt.type in (open, openat, openat2)
      output: >
        Sensitive credential file accessed (user=%user.name file=%fd.name 
        pod=%k8s.pod.name ns=%k8s.ns.name cmd=%proc.cmdline)
      priority: WARNING
      tags: [mitre_credential_access, security]

Áp dụng các quy tắc mới bằng cách cập nhật bản triển khai Helm:

helm upgrade falco falcosecurity/falco \
  --namespace falco \
  -f falco-values.yaml \
  -f custom-rules.yaml

Bước 4: Kích hoạt phát hiện và xác minh cảnh báo

Kiểm tra cấu hình bằng cách khởi tạo một pod thử nghiệm nhẹ trong namespace production:

# Khởi chạy một pod thử nghiệm tạm thời
kubectl run test-app --namespace production --image=alpine:3.19 -- sleep 3600

# Kích hoạt Rule 1: Khởi chạy một shell tương tác
kubectl exec -it test-app -n production -- /bin/sh

# Kích hoạt Rule 2: Thử đọc /etc/shadow bên trong shell
cat /etc/shadow

# Thoát phiên làm việc
exit

Kiểm tra luồng log của Falco để xác nhận các cảnh báo đã được kích hoạt:

kubectl logs -n falco -l app.kubernetes.io/name=falco -c falco --tail=50 | grep "Shell spawned"

Falco sẽ xuất ra sự kiện JSON có cấu trúc hiển thị chính xác câu lệnh, container image, tên pod và user thực hiện chỉ trong vài giây, cung cấp ngữ cảnh đầy đủ để đội ngũ phản ứng sự cố xử lý ngay lập tức.

Share: