返回文章列表

Falco與EFK整合Kubernetes稽核

本文介紹如何使用 Falco 和 EFK 堆積疊實作 Kubernetes 叢集的稽核與安全監控。Falco 負責偵測容器內的異常行為,並將事件輸出至 Fluentd。Fluentd 再將這些事件轉發到 Elasticsearch 進行儲存和索引,最後透過 Kibana

Kubernetes 資安

Falco 作為 Kubernetes 叢集的異常檢測工具,能有效監控容器內部的可疑活動,例如修改系統檔案、啟動 Shell、存取 Kubernetes API 伺服器等。透過自定義規則,Falco 可涵蓋更廣泛的安全場景。為了便於分析和管理這些安全事件,我們可以將 Falco 與 EFK(Elasticsearch、Fluentd、Kibana)堆積疊整合。Falco 產生的事件會被 Fluentd 收集,然後轉發至 Elasticsearch 進行儲存和索引。最後,Kibana 提供視覺化介面,讓管理員可以輕鬆查詢、分析和監控叢集的安全狀態,並根據需求設定警示和通知,及時應對潛在的安全威脅。此架構能有效提升 Kubernetes 叢集的安全性,並提供更全面的稽核追蹤能力。

使用Falco與EFK進行稽核

介紹Falco

Falco是一個由Sysdig開發的開源系統,為Kubernetes叢集中的Pod新增異常檢測功能。預設情況下,Falco包含一組由社群建立的強大規則,可以監控多種潛在的惡意事件,包括以下內容:

  • 當使用者嘗試修改/etc下的檔案時
  • 當使用者在Pod中啟動Shell時
  • 當使用者在Secret中儲存敏感資訊時
  • 當Pod嘗試呼叫Kubernetes API伺服器時
  • 任何嘗試修改系統ClusterRole的行為
  • 或任何其他您建立的自定義規則以滿足您的需求

當Falco在Kubernetes叢集上執行時,它會監視事件,並根據一組規則,將事件記錄在Falco Pod上,可以被Fluentd等系統收集,然後將事件轉發到外部日誌系統。

在本章中,我們將解釋如何使用Falco來滿足FooWidgets公司場景的技術需求。透過本章的學習,您將瞭解如何使用自定義組態選項在Kubernetes叢集上設定Falco。您還將瞭解Falco使用的規則,以及如何在需要稽核未包含在基本規則中的事件時建立規則。最後,您將使用Fluentd將事件轉發到Elasticsearch,並使用Kibana視覺化Falco產生的事件。

探索Falco的組態檔案

在安裝Falco之前,您需要了解可用的組態選項。首先是初始組態檔案,用於組態Falco如何建立事件。

Falco專案包含一組基本的組態檔案,您可以用於初始稽核。很可能您需要更改基本組態以滿足您的特定企業需求。在本文中,我們將介紹Falco的佈署,並提供對組態檔案的基本理解。

Falco是一個功能強大的系統,可以根據您的安全需求進行自定義。由於它具有很高的擴充套件性,因此無法在單章中涵蓋組態的每個細節。但是,像許多流行的專案一樣,它有一個活躍的GitHub社群,您可以在https://github.com/falcosecurity/falco上發布問題或加入其Slack頻道。

Falco的組態檔案

Falco的組態檔案包括一個基本組態檔案和包含將被稽核的事件的規則檔案。基本組態檔案是一個簡單的YAML檔案,包含每個組態選項的鍵值對,以及其他使用鍵值對的YAML檔案,但它們包含稽核事件的詳細資訊和組態。

有四個基本的組態檔案可用於組態您的佈署,如下所示:

  • falco.yaml
  • falco_rules.yaml
  • falco_rules.local.yaml
  • k8s_audit_rules.yaml

包含的組態檔案可以開箱即用,但您可能需要更改一些值以滿足您的日誌記錄需求。在本文中,我們將詳細解釋最重要的組態選項。前三個組態檔案是基本Falco佈署的一部分,將在本章中詳細解釋。最後一個組態檔案不是基本Falco安裝所需的。它是一個可選的附加元件,可以啟用以向API伺服器新增額外的稽核功能。

falco.yaml組態檔案

您需要編輯的第一個檔案是基本組態檔案,以組態Falco如何建立稽核事件。它允許您自定義Falco的基本設定,包括事件輸出格式、時間戳記組態和端點目標(如Slack頻道)。讓我們對該檔案進行詳細的逐步分析,嘗試逐一理解它。

組態檔案中的第一個部分是rules_files部分。本部分採用rules_file鍵的形式,其值為規則檔案(帶有破折號)。(這也可以表示為rules_file: [file1, file2, file3, ...]。)

我們將在本章中解釋每個規則檔案的功能。在此示例組態中,我們告訴Falco使用三個檔案作為規則,並且每個檔案都是在安裝過程中從ConfigMap掛載的:

rules_file:
  - /etc/falco/falco_rules.yaml
  - /etc/falco/falco_rules.local.yaml
  - /etc/falco/k8s_audit_rules.yaml

內容解密:

此段落定義了Falco使用的規則檔案。其中包括:

  • falco_rules.yaml:預設規則檔案,包含預設的稽核規則。
  • falco_rules.local.yaml:本地規則檔案,用於自定義稽核規則。
  • k8s_audit_rules.yaml:Kubernetes稽核規則檔案,用於監控Kubernetes API伺服器的活動。

下一組值將組態Falco如何輸出事件,包括時間格式,以及以文字或JSON格式輸出事件的選項。

預設情況下,time_format_iso_8601值設定為false,這告訴Falco使用本地/etc/localtime格式。將該值設定為true會告訴Falco使用YYYY-MM-DD日期格式、24小時制時間格式和UTC時區來標記每個事件。

選擇適當的格式是您組織的決定。如果您有一個全球性的組織,那麼將所有日誌記錄設定為使用ISO 8601格式可能是有益的。但是,如果您有一個區域性的組織,那麼使用本地日期和時間格式可能更為方便,因為您可能不需要將事件與其他時區的日誌系統進行關聯:

time_format_iso_8601: false

內容解密:

此設定控制Falco輸出的時間格式。如果設定為true,則使用ISO 8601格式(YYYY-MM-DD);否則,使用本地時間格式。

接下來的兩行允許您組態事件輸出的格式,可以是文字或JSON格式。預設值設定為false,這告訴Falco以文字格式輸出事件。如果第一個鍵設定為false,則第二個值將不會被評估,因為JSON未啟用:

json_output: false
json_include_output_property: true

內容解密:

此設定控制Falco輸出的格式。如果json_output設定為true,則事件將以JSON格式輸出;否則,以文字格式輸出。json_include_output_property設定控制是否包含額外的輸出屬性。

以下是一些相同型別的事件在文字格式和JSON格式下的示例:

  • Falco文字日誌輸出如下所示:
19:17:23.139089915: Notice A shell was spawned in a container with an attached terminal (user=root k8s.ns=default k8s.pod=falco-daemonset-9mrn4 container=0756e87d121d shell=bash parent=runc cmdline=bash terminal=34816 container_id=0756e87d121d image=<NA>) k8s.ns=default k8s.pod=falco-daemonset-9mrn4 container=0756e87d121d k8s.ns=default k8s.pod=falco-daemonset-9mrn4 container=0756e87d121d

圖表翻譯: 此圖表呈現了Falco的主要組態檔案及其功能。其中包括:

  • falco.yaml:基本組態檔案,用於設定事件輸出格式和時間格式。
  • falco_rules.yaml:預設規則檔案,包含預設的稽核規則。
  • falco_rules.local.yaml:本地規則檔案,用於自定義稽核規則。
  • k8s_audit_rules.yaml:Kubernetes稽核規則檔案,用於監控Kubernetes API伺服器的活動。

探索Falco的設定檔

Falco的設定檔是用於定義其行為和規則的重要檔案。預設的falco.yaml檔案包含了各種設定選項,這些選項控制著Falco如何收集事件、如何記錄日誌以及如何觸發警示。

JSON日誌輸出格式

Falco的JSON日誌輸出格式如下所示:

{
  "output": "20:47:39.535071657: Notice A shell was spawned in a container with an attached terminal (user=root k8s.ns=default k8s.pod=falco-daemonset-mjv2d container=daeaaf1c0551 shell=bash parent=runc cmdline=bash terminal=34816 container_id=daeaaf1c0551 image=<NA>) k8s.ns=default k8s.pod=falco-daemonset-mjv2d container=daeaaf1c0551 k8s.ns=default k8s.pod=falco-daemonset-mjv2d container=daeaaf1c0551",
  "priority": "Notice",
  "rule": "Terminal shell in container",
  "time": "2020-02-13T20:47:39.535071657Z",
  "output_fields": {
    "container.id": "daeaaf1c0551",
    "container.image.repository": null,
    "evt.time": 1581626859535071657,
    "k8s.ns.name": "default",
    "k8s.pod.name": "falco-daemonset-mjv2d",
    "proc.cmdline": "bash",
    "proc.name": "bash",
    "proc.pname": "runc",
    "proc.tty": 34816,
    "user.name": "root"
  }
}

內容解密:

  • output欄位包含了事件的詳細資訊,包括事件發生的時間、事件型別、涉及的容器和程式等。
  • priority欄位表示事件的優先順序別,用於區分事件的重要程度。
  • rule欄位指示了觸發該事件的規則名稱。
  • time欄位記錄了事件發生的時間戳記。
  • output_fields欄位提供了事件的詳細欄位資訊,包括容器ID、Kubernetes名稱空間、程式命令列等。

日誌和優先順序設定

接下來的設定選項控制著Falco如何記錄其自身的系統事件:

log_stderr: true
log_syslog: true
log_level: info

內容解密:

  • log_stderrlog_syslog設定選項決定了Falco是否將事件記錄到標準錯誤輸出和syslog中。
  • log_level設定選項定義了Falco記錄日誌的級別,可以設為emergency、alert、critical、error、warning、notice、info或debug。

事件優先順序和緩衝輸出

priority: debug
buffered_outputs: false

內容解密:

  • priority設定選項指定了Falco評估規則的優先順序別,只有優先順序等於或高於該值的規則才會被評估。
  • buffered_outputs設定選項控制著輸出是否緩衝,預設為false。

系統呼叫事件丟棄處理

syscall_event_drops:
  actions:
    - log
    - alert
  rate: 0.03333
  max_burst: 10

內容解密:

  • 當系統呼叫緩衝區溢位時,Falco可以組態為忽略、記錄日誌、發出警示或離開。
  • ratemax_burst設定選項控制著Falco執行組態動作的頻率。

輸出速率限制

outputs:
  rate: 1
  max_burst: 1000

內容解密:

  • ratemax_burst設定選項用於限制輸出的速率,避免過多的警示輸出。

Syslog輸出和檔案輸出

syslog_output:
  enabled: true

file_output:
  enabled: false
  keep_alive: false
  filename: ./events.txt

內容解密:

  • syslog_output設定選項控制著是否將事件輸出到syslog。
  • file_output設定選項允許將事件輸出到檔案中,可以設定是否保持檔案開啟狀態。

Web伺服器組態

webserver:
  enabled: true
  listen_port: 8765
  k8s_audit_endpoint: /k8s_audit
  ssl_enabled: false
  ssl_certificate: /etc/falco/falco.pem

內容解密:

  • Web伺服器組態用於整合Kubernetes稽核事件與Falco,可以設定是否啟用SSL加密。

程式輸出和HTTP輸出

program_output:
  enabled: false
  keep_alive: false
  program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX"

http_output:
  enabled: true
  url: http://falcosidekick:2801

內容解密:

  • program_output允許執行外部程式來處理警示。
  • http_output允許將警示傳送到HTTP端點。

Falco規則組態檔案

Falco的規則組態檔案定義了用於產生警示的規則。這些規則檔案透過rules_files鍵在主組態檔案中指定。接下來的部分將解釋如何組態用於建立Falco警示的檔案。

探索Falco的設定檔

Falco的規則檔案中包含三種元素:

  • 規則:設定Falco的警示
  • 巨集:建立一個函式,可縮短規則中的定義
  • 清單:可在規則中使用的專案集合

瞭解規則

Falco包含了一組示例Kubernetes規則,您可以直接使用或根據您的特殊需求修改現有的規則。 預設的Falco安裝包含三個規則集。

規則檔案概述

每個規則檔案都具有相同的語法,因此在詳細解釋每個檔案之前,讓我們先解釋規則、巨集和清單如何協同工作以建立規則。

示例:偵測容器存取K8S API伺服器

我們的範例將在非Kubernetes本身的Pod嘗試聯絡API伺服器時產生警示。這種活動可能表明攻擊者正在試圖利用Kubernetes API伺服器。

Falco規則範例

- rule: Contact K8S API Server From Container
  desc: Detect attempts to contact the K8s API Server from a container
  condition: evt.type=connect and evt.dir=< and (fd.typechar=4 or fd.typechar=6) and container and not k8s_containers and k8s_api_server
  output: Unexpected connection to K8s API Server from container (command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag connection=%fd.name)
  priority: NOTICE
  tags: [network, k8s, container, mitre_discovery]

規則解析

部分說明
rule規則名稱
desc規則描述
condition觸發規則的條件
output警示輸出
priority警示優先順序
tags標籤

瞭解條件(欄位和值)

條件包含多個類別欄位,可以使用標準的and、not、or等條件進行評估。

事件類別欄位範例
evt.type=connect and evt.dir=< 

此條件使用事件(evt)和檔案描述符(fd)類別欄位。

使用巨集

巨集允許您建立一個集合,以使規則建立更快、更容易。 在前面的範例中,條件使用了兩個巨集:k8s_containersk8s_api_server

k8s_containers巨集定義
- macro: k8s_containers
  condition: >
    (container.image.repository in (gcr.io/google_containers/hyperkube-amd64,
    gcr.io/google_containers/kube2sky, sysdig/agent, sysdig/falco,
    sysdig/sysdig, falcosecurity/falco) or (k8s.ns.name = "kube-system"))

內容解密:

此巨集定義了Kubernetes容器的條件,用於判斷是否允許容器存取K8S API伺服器。條件檢查容器的映像儲存函式庫是否在指定的清單中,或名稱空間是否為kube-system

圖表說明

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Falco與EFK整合Kubernetes稽核

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖表呈現了Falco規則的結構,包括條件、事件類別和檔案描述符類別。事件類別包含evt.type=connectevt.dir=<兩個條件,而檔案描述符類別包含fd.typechar=4 or fd.typechar=6的條件。