傳統IDS面臨的一個主要挑戰是效能開銷。為每個網路封包或系統呼叫執行IDS會產生顯著的系統負擔,從而降低系統效能。這就是eBPF技術帶來革新的地方。

eBPF的技術優勢與安全考量

擴充套件式Berkeley封包過濾器(eBPF)是一種安全高效地擴充套件Linux核心功能的機制。它具有以下優勢:

  • 極高效能:最初設計用於快速封包處理
  • 核心級整合:現在核心開發者使用它觀察核心中所有元件的執行時行為
  • 受信任執行:作為核心內的可信程式碼執行,比其他IDS和追蹤技術受到的限制更少

然而,在核心中執行也帶來了潛在風險。eBPF子系統和JIT編譯器曾出現多次安全漏洞,如CVE-2021-31440,這是一個Linux核心eBPF驗證器中的不正確邊界計算,允許攻擊者繞過驗證機制。但總體而言,這些風險被認為比緩慢、不完整的核心開發者追蹤解決方案或更容易出錯的IDS要小。

隨著eBPF功能的擴充套件和與核心的深度整合,許多容器網路介面(CNI)和安全產品現在使用eBPF進行檢測和網路管理,包括Cilium、Pixie和後面將詳細介紹的Falco。

安全研究與eBPF的雙面性

安全研究者對eBPF進行了深入研究,既探討其防禦能力,也分析其潛在的攻擊向量:

  • Jeff Dileo的「Evil eBPF In-Depth Practical Abuses of an In-Kernel Bytecode Runtime」探討了BPF及其攻擊手法
  • Valentina Palmiotti的「Kernel Pwning with eBPF: A Love Story」則詳細介紹了eBPF的各個元件

這些研究表明,強大的技術工具往往具有雙面性,既可用於強化安全,也可能被攻擊者利用。

Kubernetes與容器入侵偵測的新正規化

雲原生環境帶來了全新的安全挑戰,也為入侵偵測系統提供了新的機會。Kubernetes和容器環境中的IDS系統支援名稱空間工作負載、主機和網路層面的入侵偵測。

容器化環境中IDS的獨特優勢

透過將程式分割到不同名稱空間,IDS可以利用更明確的中繼資料來輔助決策。這種更細粒度的資料能夠提供對攻擊更深入的洞察,這在決定是否終止執行容器時尤為重要,因為這可能影響生產工作負載。

容器IDS的主要優勢在於其監控範圍更為聚焦——它只需監控單個容器,而非整台機器。單一用途容器中允許行為的定義範圍要小得多,這使得IDS能夠制定更精確的策略來阻止不必要的行為。

容器特定IDS的設計理念

容器特定IDS的設計理念主要圍繞以下幾點:

  1. 名稱空間感知:能夠區分不同容器名稱空間中的活動
  2. 微服務友好:適應微服務架構中服務高度分散的特性
  3. 動態適應:能夠處理容器快速建立和銷毀的場景
  4. 資源效率:在不顯著影響容器效能的前提下提供保護

這些設計理念使容器IDS能夠提供比傳統IDS更精確、更有效的保護。

Falco:雲原生入侵偵測的實踐

Falco是一個開放原始碼的雲原生入侵偵測系統,可以在容器中或主機上執行。它代表了現代容器安全監控的最佳實踐之一。

Falco的技術演進與架構

Falco的技術架構經歷了重要的演進:

  • 早期版本:傳統上,Falco需要一個專用的核心模組來執行,將其程式碼載入核心以便與系統呼叫互動
  • 現代架構:自2019年起,Falco也支援eBPF,這允許從使用者空間將通用程式碼載入核心記憶體

這種演進帶來了多項優勢:

  • 減少了自定義程式碼的需求
  • 降低了對核心模組的依賴
  • 能夠透過一個廣為人知的介面使用核心監控和執行技術

Falco的佈署與許可權需求

在容器中執行Falco時,它需要特定的許可權:

  • 對主機的特權存取,或
  • 具有CAP_BPF能力並能存取主機PID名稱空間

在eBPF模式下,當程式使用系統呼叫(如open())與檔案互動時,eBPF程式會被觸發,並可以在核心VM中執行任意程式碼來做出決策。根據輸入,操作將被接受或阻止。

以下是一個Falco佈署的範例命令:

docker run --rm -i -t \
-e HOST_ROOT=/ \
--cap-add BPF \
--cap-add SYS_PTRACE \
--pid=host \
$(ls /dev/falco* | xargs -I {} echo --device {}) \
-v /var/run/docker.sock:/var/run/docker.sock \
falcosecurity/falco-no-driver:latest

這個命令做了以下幾件事:

  1. 以互動模式執行Falco容器
  2. 設定HOST_ROOT環境變數指向主機根目錄
  3. 增加BPF和SYS_PTRACE能力,使Falco能夠使用eBPF和系統跟蹤功能
  4. 使容器分享主機PID名稱空間,使其能夠檢視所有主機程式
  5. 動態找出並掛載所有Falco裝置
  6. 掛載Docker通訊端,使Falco能夠與Docker守護程式通訊
  7. 使用無驅動模式的Falco映像(依賴eBPF而非核心模組)

執行後,Falco會開始監控系統活動,並在檢測到可疑行為時發出警示。例如,以下是Falco檢測到容器中啟動shell的警示:

DEMO 13:07:48.722501295: Notice A shell was spawned in a container with an attached terminal
(user=root user_loginuid=-1 <NA> (id=52af6056d922) shell=sh parent=<NA> cmdline=sh -c unset $(env | grep -Eo '.*VERSION[^\=]*') && exec bash terminal=34816 container_id=52af6056d922 image=<NA>)

這個警示顯示在容器中啟動了一個shell,這在某些安全策略下可能被視為可疑行為。警示包含了豐富的上下文訊息,包括使用者、容器ID、命令列等,方便安全團隊進行調查。

Sysdig與Falco的關係

值得一提的是,Falco根據Sysdig,一個系統內省工具。Sysdig生態系統包括:

  • Sysdig Cloud:提供工作負載和Kubernetes效能監控
  • Sysdig Secure:根據Falco構建的商業產品,提供額外的企業級功能

這種開放原始碼與商業產品的結合模式,使Falco能夠在保持社群活力的同時,也能滿足企業級使用者的需求。

雲原生入侵偵測最佳實踐

在實施雲原生入侵偵測系統時,有幾個關鍵最佳實踐值得考慮:

多層次防禦策略

單一防禦機制永遠不夠。實施多層次防禦策略,結合:

  1. 網路層防護:使用服務網格和網路策略限制容器間通訊
  2. 主機層監控:佈署Falco等工具監控主機層面的異常活動
  3. 容器行為分析:監控容器執行時行為,識別偏離正常模式的活動

最小許可權原則

確保容器和Pod僅擁有執行其功能所需的最小許可權:

  • 使用Kubernetes的安全上下文限制容器能力
  • 實施網路策略限制Pod間通訊
  • 避免使用特權容器,除非絕對必要

持續監控與警示

建立全面的監控和警示系統:

  • 集中收集所有IDS產生的日誌和警示
  • 實施自動化分析,識別潛在的安全事件
  • 建立明確的事件回應流程,確保安全團隊能夠及時處理警示

定期更新與測試

保持IDS系統的最新狀態:

  • 定期更新簽章資料函式庫
  • 測試IDS對新型威脅的檢測能力
  • 進行紅隊演習,評估防禦機制的有效性

雲原生安全

隨著雲原生技術的不斷發展,入侵偵測系統也在不斷演進。幾個值得關注的趨勢包括:

人工智慧與機器學習的融合

AI和ML技術正在被整合到入侵偵測系統中,提供更強大的異常檢測能力:

  • 使用無監督學習識別複雜的異常模式
  • 透過深度學習分析容器行為,建立更精確的基準模型
  • 減少誤報,提高真實威脅的檢測率

跨雲環境的統一監控

隨著多雲和混合雲架構的普及,能夠跨不同雲環境提供統一監控的IDS解決方案變得越來越重要:

  • 對多雲Kubernetes叢集的統一可見性
  • 跨環境的一致安全策略執行
  • 集中化的安全事件管理

與DevSecOps的深度整合

入侵偵測正在成為DevSecOps流程的重要組成部分:

  • 在CI/CD流程中整合安全測試和掃描
  • 自動化回應機制,實作安全自我修復
  • 將安全洞察反饋到開發流程,實作持續改進

雲原生入侵偵測系統的未來將更加人工智慧、自動化和整合化,為日益複雜的雲環境提供更有效的保護。

在現代資安架構中,入侵偵測系統已從傳統的網路和主機監控工具演進為深度整合於雲原生環境的人工智慧解決方案。透過利用eBPF等先進技術,現代IDS能夠以最小的效能開銷提供更精確的威脅檢測。Falco等工具代表了這一演進的最前沿,為Kubernetes和容器環境提供專門設計的安全監控能力。隨著雲原生技術的持續發展,入侵偵測系統將繼續適應和創新,應對不斷變化的威脅環境。

Falco:容器環境的行為監控衛士

在容器安全領域,Falco作為一個強大的開放原始碼行為監控工具,提供了一系列由社群貢獻和維護的規則,特別是針對Kubernetes叢集的專用安全規則。在實際佈署中,我發現Falco的威力在於它能夠識別異常行為並即時發出警示,這對於保護容器環境至關重要。

網路連線監控規則

Falco的網路監控規則主要關注意外的TCP連線,這些規則能夠偵測到來自非預期連線埠的入站流量。在設計安全架構時,我通常會從這些基本規則開始,針對特定環境進行調整:

允許的入站連線埠白名單

針對Kubernetes核心元件,Falco預設允許以下入站連線埠:

  • 6443:kube-apiserver容器
  • 10252:kube-controller容器
  • 8443:kube-dashboard容器
  • 10053、10055、8081:kube-dns容器
  • 10251:kube-scheduler容器

當監控到這些白名單之外的連線嘗試時,Falco會立即觸發警示。這種白名單機制在我看來是最安全的做法,因為它遵循「預設拒絕」的原則。

程式監控規則

除了網路監控,Falco還提供了對意外啟動程式的監控,這對於發現容器中的惡意活動至關重要:

允許的程式白名單

Falco針對Kubernetes元件允許以下程式:

  • kube-apiserver (對應kube-apiserver容器)
  • kube-controller-manager (對應kube-controller容器)
  • /dashboard (對應kube-dashboard容器)
  • /kube-dns (對應kube-dns容器)
  • kube-scheduler (對應kube-scheduler容器)

在實際佈署中,我發現這些規則需要根據具體環境進行微調。例如,如果你使用了自定義的容器映像或修改了預設設定,可能需要擴充套件這些白名單。

檔案存取監控

Falco還監控檔案系統活動,偵測非預期的檔案讀取嘗試:

允許的唯讀檔案字首

預設情況下,Falco允許存取以下目錄下的檔案:

  • /public

對於其他目錄的唯讀存取嘗試,Falco會發出警示。在我的實踐中,這個規則通常需要根據應用程式的實際需求進行擴充套件,因為大多數應用需要存取的路徑遠不止這些。

社群規則的擴充套件與自定義

這些社群貢獻的規則形成了一個有用的基礎集,但在生產環境中,我強烈建議根據叢集的具體安全需求進行擴充套件和自定義。每個環境都有其獨特性,通用規則無法覆寫所有場景。

規則繞過風險警示

雖然使用社群貢獻的規則通常是更好的選擇,但任何軟體都不可能完全沒有缺陷。例如,安全研究組織Darkbit發現了一個Falco規則繞過漏洞,攻擊者可以利用寬鬆的正規表示式規則佈署自定義的特權代理容器。

以下是一個有漏洞的規則範例:

- macro: falco_privileged_containers
  condition: (openshift_image or
              user_trusted_containers or
              container.image.repository in (trusted_images) or
              container.image.repository in (falco_privileged_images) or
              container.image.repository startswith istio/proxy_ or
              container.image.repository startswith quay.io/sysdig)

這個規則定義了一個名為falco_privileged_containers的巨集,用於識別被允許以特權模式執行的容器。漏洞存在於最後一行,container.image.repository startswith quay.io/sysdig這個條件過於寬鬆,允許任何以quay.io/sysdig開頭的映像以特權模式執行。攻擊者可以建立一個名為docker.io/my-org-name-that-ends-with-sysdig/agent的容器映像,繞過這個規則的限制。

這種漏洞提醒我們,在編寫自定義規則時要特別注意條件的精確性,避免過於寬鬆的比對條件。在我的實踐中,我通常會使用完全比對而非字首比對,並定期審查規則以確保安全性。

機器學習型入侵偵測系統

隨著容器環境的複雜性增加,傳統的根據規則的入侵偵測系統可能不足以應對所有威脅。機器學習(ML)型入侵偵測系統透過分析相同的訊號,但使用模型來預測容器是否被入侵,提供了更加靈活和適應性強的解決方案。

主流ML型入侵偵測解決方案

市場上已有多種根據機器學習的容器安全解決方案:

  1. Aqua Security - 使用根據ML的行為分析,監控容器、網路和主機中的行為並做出反應。我發現它的優勢在於能夠建立應用程式的行為基線,並識別偏離這些基線的異常活動。

  2. Prisma Cloud - 提供第3層容器間防火牆,透過ML學習應用程式元件之間的有效流量模式。這種方法特別適合微服務架構,因為它能夠理解服務之間的正常通訊模式。

  3. Lacework - 採用無監督機器學習,提供跨雲可觀察性和執行時威脅回應。在我的評估中,它的優勢是能夠自動發現環境中的異常,無需預定義規則。

  4. Accuknox - 結合無監督機器學習來檢測不穩定性和潛在攻擊,以及"身份即邊界"的概念,實作零信任網路、應用程式和資料保護。

這些解決方案的共同點是它們都能夠學習應用程式的正常行為模式,而不僅依賴於預定義的規則。這使它們能夠檢測到更複雜和未知的攻擊模式,這些攻擊可能會繞過傳統的根據簽名的入侵偵測系統。

機器學習IDS的優勢與挑戰

在實施機器學習型IDS時,我發現它們有以下優勢:

  1. 能夠檢測未知威脅和零日攻擊
  2. 適應性強,隨著環境變化自動調整
  3. 減少誤報,提高安全團隊的工作效率

但同時也面臨一些挑戰:

  1. 需要時間來學習正常行為模式
  2. 可能需要大量資源進行計算和分析
  3. 對於極為罕見的攻擊模式,檢測效果可能不佳

在選擇機器學習型IDS時,我建議考慮系統的可解釋性、誤報率以及與現有安全工具的整合能力。

容器取證技術

在安全事件發生後,取證分析是重建攻擊路徑和評估影響範圍的關鍵步驟。容器取證是從不完整或歷史來源重建資料的藝術,在Linux環境中,這涉及捕捉程式、記憶體和檔案系統內容,以進行離線分析,找出入侵的來源或影響,並檢查攻擊者的技術。

容器取證的基本概念

更高階的系統會收集更多訊息,例如它們已經記錄的網路連線訊息。在發生嚴重入侵時,整個叢集或帳戶可能被切斷網路,使攻擊者無法繼續攻擊,並且整個系統可以被映像和探索。

像kube-forensics這樣的工具可以"建立執行中的Pod狀態的檢查點快照,用於後續的離線分析",這樣惡意工作負載可以被轉儲和終止,系統可以還原使用。它執行一個forensics-controller-manager,使用PodCheckpoint自定義資源定義(CRD)來有效地執行docker inspect、docker diff,最後執行docker export。

值得注意的是,這種方法無法捕捉程式的記憶體,而記憶體中可能包含未儲存到磁碟的植入物或攻擊者工具,或者是程式啟動後被刪除的工具。

程式記憶體轉儲技術

要捕捉程式的記憶體,可以使用標準工具如GDB。從容器內部使用這些工具可能很困難,因為可能需要符號。從容器外部,轉儲記憶體並搜尋有趣資料是很簡單的。

以下是一個結合Trufflehog和GDB程式轉儲的簡單Bash指令碼範例:

#!/bin/bash
# truffleproc — hunt secrets in process memory // 2021 @controlplaneio
set -Eeuo pipefail
PID="${1:-1}"
TMP_DIR="$(mktemp -d)"
STRINGS_FILE="${TMP_DIR}/strings.txt"
RESULTS_FILE="${TMP_DIR}/results.txt"
CONTAINER_IMAGE="controlplane/build-step-git-secrets"
CONTAINER_SHA="51cfc58382387b164240501a482e30391f46fa0bed317199b08610a456078fe7"
CONTAINER="${CONTAINER_IMAGE}@sha256:${CONTAINER_SHA}"

main() {
  ensure_sudo
  echo "# coredumping pid ${PID}"
  coredump_pid
  echo "# extracting strings to ${TMP_DIR}"
  extract_strings_from_coredump
  echo "# finding secrets"
  find_secrets_in_strings || true
  echo "# results in ${RESULTS_FILE}"
  less -N -R "${RESULTS_FILE}"
}

ensure_sudo() {
  sudo touch /dev/null
}

coredump_pid() {
  cd "${TMP_DIR}"
  sudo grep -Fv ".so" "/proc/${PID}/maps" | awk '/ 0 /{print $1}' | (
    IFS="-"
    while read -r START END; do
      START_ADDR=$(printf "%llu" "0x${START}")
      END_ADDR=$(printf "%llu" "0x${END}")
      sudo gdb \
        --quiet \
        --readnow \
        --pid "${PID}" \
        -ex "dump memory ${PID}_mem_${START}.bin ${START_ADDR} ${END_ADDR}" \
        -ex "set confirm off" \
        -ex "set exec-file-mismatch off" \
        -ex quit od |& grep -E "^Reading symbols from"
    done | awk-unique
  )
}

extract_strings_from_coredump() {
  strings "${TMP_DIR}"/*.bin >"${STRINGS_FILE}"
}

find_secrets_in_strings() {
  local DATE MESSAGE
  DATE="($(date --utc +%FT%T.%3NZ))"
  MESSAGE="for pid ${PID}"
  cd "${TMP_DIR}"
  git init --quiet
  git add "${STRINGS_FILE}"
  git -c commit.gpgsign=false commit \
    -m "Coredump of strings ${MESSAGE}" \
    -m "https://github.com/controlplaneio/truffleproc" \
    --quiet
  echo "# ${0} results ${MESSAGE} ${DATE} | @controlplaneio" >>"${RESULTS_FILE}"
  docker run -i -e IS_IN_AUTOMATION= \
    -v "$(git rev-parse --show-toplevel):/workdir:ro" \
    -w /workdir \
    "${CONTAINER}" \
    bash |& command grep -P '\e\[' | awk-unique >> "${RESULTS_FILE}"
}

awk-unique() {
  awk '!x[$0]++'
}

main "${@:-}"

這個指令碼名為truffleproc,用於在程式記憶體中搜尋敏感訊息。它的主要功能包括:

  1. main() - 指令碼的主函式,協調整個流程
  2. ensure_sudo() - 確保指令碼以root許可權執行
  3. coredump_pid() - 使用GDB轉儲指定程式ID的記憶體
  4. extract_strings_from_coredump() - 從記憶體轉儲中提取字元串
  5. find_secrets_in_strings() - 使用Trufflehog工具在提取的字元串中搜尋可能的機密
  6. awk-unique() - 去除重複行的輔助函式

指令碼首先取得目標程式的記憶體對映,然後使用GDB提取每個記憶體區域,接著提取所有可讀字元串,最後使用Trufflehog工具分析這些字元串以發現高熵值的部分,這些通常是金鑰、令牌等敏感訊息。

將這個指令碼儲存為procdump.sh並針對本地shell執行:

$ procdump.sh $(pgrep -f bash)

你將看到載入到shell中的任何高熵字元串或可疑機密:

1 # procdump.sh results for pid 5598 (2021-02-23 08:58:54.972Z) | @controlplaneio
2 Reason: High Entropy
3 Date: 2021-02-23 08:58:54
4 Hash: 699776ae32d13685afca891b0e9ae2f1156d2473
5 Filepath: strings.txt
6 Branch: origin/master
7 Commit: WIP
8 
9 +SECRET_KEY=c0dd1e1eaf1e757e55e118fea7caba55e7105e51eaf1e55c0caa1d05efa57e57
10 +GH_API_TOKEN=1abb1ebab1e5e1ec7ed5c07f1abe118b0071e551005edf1a710c8c10aca5ca1d

記憶體轉儲攻擊的風險與防護

需要特別注意的是,在程式名稱空間中擁有root許可權的攻擊者可以轉儲該名稱空間中任何其他程式的記憶體。而主機程式名稱空間中的root使用者可以轉儲節點上任何程式的記憶體(包括子名稱空間)。

在我設計雲原生應用程式時,通常採用以下策略來避免這類別攻擊:

  1. 使用時取回機密 - 從檔案系統或金鑰管理系統中在使用時才檢索機密
  2. 不使用時丟棄機密 - 當不需要使用機密時,將其從記憶體中丟棄,這樣系統對這種攻擊更有彈性
  3. 記憶體中加密機密 - 雖然解金鑰同樣面臨被轉儲的風險,因此也應在不使用時丟棄

這些策略可以顯著提高容器環境中機密管理的安全性,減少記憶體轉儲攻擊的風險。

蜜罐技術:最後的防線

雖然入侵偵測系統可以檢測和防止幾乎所有對系統的濫用,但我必須強調,安全領域沒有萬能的解決方案。應該假設像Captain Hashjack這樣的惡意攻擊者仍然能夠繞過任何精心的安全設定。複雜系統為攻擊者提供了不對稱的優勢:防禦者只需犯一個錯誤就可能被入侵。

蜜罐的作用與價值

攻擊者可能仍然能夠從容器中逃逸或穿越到主機。或者,如果他們在受IDS管控的容器中操作,他們可能會操縱應用程式的預期行為(例如,使用不同的標誌呼叫相同的應用程式),從而讀取敏感資料而不觸發IDS警示。

因此,最後的防線是簡單而有效的蜜罐 - 一個合法應用程式永遠不會使用的簡單伺服器或檔案。它無害地藏在一個誘人或安全的位置,當攻擊者存取它時觸發警示。蜜罐可能由網路掃描或系統通常不會發出的HTTP請求觸發。

蜜罐佈署策略

在容器環境中佈署蜜罐時,我通常採用以下策略:

  1. 分散佈署 - 在不同的名稱空間和節點上佈署多個蜜罐,增加攻擊者觸發的可能性
  2. 真實偽裝 - 使蜜罐看起來像真實的服務,包括合理的連線埠、服務名稱和設定
  3. 低互動性 - 使用低互動性蜜罐減少資源消耗,同時捕捉基本攻擊訊息
  4. 隔離環境 - 將蜜罐佈署在隔離的環境中,防止攻擊者利用蜜罐攻擊真實系統
  5. 即時警示 - 設定即時警示機制,確保安全團隊能夠快速回應潛在入侵

蜜罐不僅可以檢測入侵,還可以延緩攻擊者的行動,為安全團隊提供寶貴的回應時間。此外,透過分析攻擊者與蜜罐的互動,可以取得有關攻擊技術和意圖的重要情報。

在現代容器環境中,蜜罐技術與傳統入侵偵測系統相結合,形成了深度防禦策略的重要組成部分。雖然它們不能防止所有攻擊,但能夠提供額外的安全層,使攻擊者更難以在不被發現的情況下移動和操作。

容器安全是一個多層次的挑戰,需要結合多種技術和方法。從Falco等根據規則的監控工具,到機器學習型入侵偵測系統,再到容器取證和蜜罐技術,每種方法都有其獨特的優勢和適用場景。透過深入理解這些技術並將它們整合到全面的安全策略中,我們可以顯著提高容器環境的安全性,即使面對最複雜的攻擊也能保持彈性。

在實施這些安全措施時,重要的是記住安全是一個持續的過程,而非一次性的佈署。定期審查和更新安全設定,保持對新威脅和漏洞的警覺,以及培訓團隊成員瞭解最佳安全實踐,都是維護容器環境安全的關鍵因素。