從0到1使用Kubernetes系列(八):安全

Kubernetes 的安全是一個相當廣泛的主題,涉及很多高度相關的內容。和探討大部分安全性相關的問題一樣,首先需要考慮威脅模型——誰可能攻擊你的系統,以及他們如何做到這一點。這可以幫你確定安全工作的優先級。對於大多數 Kubernetes 應用有三類主要的攻擊者:

  1. 外部攻擊者:當你在內部或雲上部署應用時,你可能面臨來自集羣外的攻擊。這類攻擊者沒有系統權限,所以會專注於公開的服務,會嘗試獲取訪問權限並提升權限。
  2. 泄露的容器:Kubernetes 集羣通常運行着各種工作負載。攻擊者也可能利用集羣中運行的容器的漏洞進行攻擊,在這種時候,要最大程度降低漏洞攻擊影響到整個集羣的風險。攻擊者可以訪問單個容器的資源,因此限制容器權限至關重要。
  3. 惡意用戶:Kubernetes 是一個多用戶系統。攻擊者可能擁有某用戶的賬戶,並企圖獲得更多權限,這種情況比較複雜,要具體分析,需要限制不同用戶的訪問權限。

圍繞雲原生基礎概念構建的模型可以幫你建立對 Kubernetes 安全的總體認識。下圖將安全劃分爲四個層級,被稱爲雲原生安全的4C模型。管理員將在不同的層次上應對三類攻擊者。

4C 指的是雲(Cloud)、集羣(Cluster),容器(Containers)和代碼(Code)

正如你在圖中所看見的,4C 模型中每部分的安全性都是相互包含的。只依靠增強代碼層次安全來預防雲、集羣和容器中安全漏洞是幾乎不可能的。適當提高其他層的安全能力,就已經爲你的代碼提供強大的基礎安全保障。下面將詳細介紹這四部分內容。

Cloud

大多數情況下,云爲 Kubernetes 集羣提供可信的計算資源。如果雲的基礎設置是不可靠的(或以易受到攻擊的方式配置),那就沒有辦法保證在這個基礎上構建的 Kubernetes 集羣的安全性。每一個雲服務提供商都向他們的客戶提供大量如何在其環境安全運行負載的建議。下面提供常用雲服務廠商的安全文檔鏈接,並且提供了構建安全 Kubernetes 集羣的建議。

雲服務提供商安全文檔列表

雲服務廠商 鏈接
阿里雲 https://www.alibabacloud.com/trust-center
AWS https://aws.amazon.com/security/
Google Cloud Platform https://cloud.google.com/security/
Microsoft Azure https://docs.microsoft.com/en-us/azure/security/azure-security

如果你運行在自己的硬件上或者其他雲服務提供商,請查閱文檔獲取最佳安全實踐。

通用的安全建議

  • 理想情況下,不開放 Kubernetes Master 節點公網訪問,並且限制能夠訪問集羣 Master 節點的 IP 地址。

  • 通過網絡安全組等配置工作節點只接受 Master 節點上指定端口的連接,並且接受 Kubernetes 中服務類型爲 NodePort 和 LoadBalancer 的連接。如果可能,這些節點也不應該暴露在公網中。

  • Kubernetes 訪問雲服務提供商的 API,每一個雲服務提供商都賦予 Kubernetes 的 Master 和 Node 不同的權限。該訪問權限遵循其管理資源所需資源的最小權限原則。

  • 訪問 etcd, 只有在 master 節點中通過 TLS 可以訪問 etcd。

  • 在所有可能情況下,對停用狀態的的驅動設備加密。ectd 擁有整個集羣的狀態(包括密鑰信息),因此對其磁盤要在其停用的時候加密。

Cluster

Kubernetes 是一個複雜的系統,下圖展示了一個集羣不同的組成部分,爲了保證集羣整體的安全,需要仔細保護每一個組件。

將需要注意保護的集羣組件劃分成兩個部分:

  1. 保護組成集羣的可配置組件
  2. 保護運行在集羣中的應用

集羣的組件

  1. 控制對 Kubernetes API 的訪問

    使用 TLS 進行安全通訊。Kubernetes 期望默認情況下使用 TLS 對集羣中所有 API 通信進行加密,大多數安裝方式都會創建必要的證書並分發給集羣組件。

    API 認證。在安裝集羣時,爲API服務器選擇與通用訪問模式匹配的身份驗證機制。例如,小型單用戶集羣可能希望使用簡單的證書或靜態Bearer令牌方法。較大的羣集可能希望集成現有的OIDC或LDAP服務器,以將用戶細分爲多個組。更多有信息請參考認證

    API 授權。一旦通過身份驗證,每個API調用也都有望通過授權檢查。Kubernetes 附帶了一個集成的基於角色的訪問控制(RBAC)組件,該組件將傳入的用戶或組與捆綁到角色中的一組權限進行匹配。這些權限將動詞(get,create,delete)與資源(pods,service,nodes)結合在一起,並且可以是命名空間或集羣作用域。提供了一組現成的角色,這些角色根據客戶端可能要執行的操作提供合理的默認責任分離。更多有關信息請參考授權

  2. 控制對 Kubelet 的訪問。

    Kubelet 在端口10250和10255上提供小型 REST API。端口10250是讀/寫端口,而10255是具有API端點子集的只讀端口。這些端點授予對節點和容器的強大控制權。默認情況下,Kubelets允許未經身份驗證對此API進行訪問。生產集羣應啓用 Kubelet 身份驗證和授權,可以通過設置 --read-only-port=0 來禁用只讀端口,但是10250 端口用於系統指標收集和其他重要功能,所以開發者必須仔細控制對此端口的訪問。更多有關信息請參考Kubelet身份驗證/授權

  3. 保護集羣組件不受損壞

    • 限制對 etcd 的訪問。對API的etcd後端的寫入訪問權等同於在整個集羣上獲得root權限,而讀取訪問權也可以獲取集羣信息。管理員應始終使用從API服務器到etcd服務器的強憑據,例如通過TLS客戶端證書的相互身份驗證,通常建議 etcd服務器隔離在僅API服務器可以訪問的防火牆後面。
    • 限制對Alpha或Beta功能的訪問。Alpha和Beta Kubernetes功能正在積極開發中,並且可能會存在限制或錯誤,從而導致安全漏洞。始終評估Alpha或Beta功能可能提供的價值,以防對您的安全狀況造成潛在風險。如有疑問,請禁用不使用的功能。
    • 啓用審覈日誌記錄。審覈記錄器是一項Beta版功能,可記錄API的行爲,在出現問題後提供分析依據。
    • 經常輪換基礎設施憑證。密鑰和憑證生存週期越短,就越難被攻擊者利用。
    • 在啓用第三方集成之前,請先進行審查。
    • 停用時加密 ectd。etcd數據庫將包含可通過Kubernetes API訪問的所有信息,可能使攻擊者深入瞭解羣集的狀態。
    • 接收有關安全更新和報告漏洞的警報。

集羣中的應用

根據應用程序受到的攻擊,關注安全的特定方面。例如,運行中的服務 A 對於其他應用非常重要,而服務 B 容易受到資源耗盡攻擊,如果不設置服務 B 的資源限制,就會因爲服務 B 耗盡資源導致服務 A 不可用。所以需要注意下面幾個常見安全措施:

  • 定義資源限制

    默認情況下,Kubernetes 集羣中對所有資源沒有對 CPU 、內存和磁盤的使用限制。可以通過創建資源配額策略,並附加到 namespace 中來限制資源的使用。

    下面的例子將限制命名空間中Pod 的數量爲4個,CPU使用在1和2之間,內存使用在1GB 和 2GB 之間。

    # compute-resources.yaml
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: compute-resources
    spec:
      hard:
        pods: "4"
        requests.cpu: "1"
        requests.memory: 1Gi
        limits.cpu: "2"
        limits.memory: 2Gi
        requests.nvidia.com/gpu: 4
    

    分配資源配額到命名空間:

    kubectl create -f ./compute-resources.yaml --namespace=myspace
    

    查看 namespace 資源使用情況:

    [root@localhost ~]# kubectl describe quota compute-resources --namespace=myspace
    Name:                    compute-resources
    Namespace:               myspace
    Resource                 Used  Hard
    --------                 ----  ----
    limits.cpu               0     2
    limits.memory            0     2Gi
    pods                     0     4
    requests.cpu             0     1
    requests.memory          0     1Gi
    requests.nvidia.com/gpu  0     4
    

    也可以爲 Pod 添加資源限制,設置內存請求爲 256MiB,內存限制爲512MiB

    apiVersion: v1
    kind: Pod
    metadata:
      name: default-mem-demo
    spec:
      containers:
      - name: default-mem-demo-ctr
        image: nginx
        resources:
          limits:
            memory: 512Mi
          requests:
            memory: 256Mi
    
  • Pod 安全策略

    作爲 Pod 的組成部分,容器通常配置有非常實用的安全默認值,這些默認值適用於大多數情況。但是,有時 Pod 可能需要其他權限才能執行其預期任務,在這種情況下,我們需要增強 Pod 的默認權限。安全上下文定義了 Pod 或容器的特權和訪問控制,安全上下文設置有:

    1. 委託訪問:基於用戶ID 和用戶組ID 權限去訪問資源對象(如文件)。
    2. SELinux:爲對象分配安全標籤
    3. 以特權或非特權用戶運行
    4. Linux 功能:爲進程提供一些特權,而不去賦予它root用戶的所有特權
    5. AppArmor:使用程序配置文件來限制單個程序的功能。
    6. Seccomp:過濾進程的系統調用
    7. 允許提升權限(AllowPrivilegeEscalation):子進程能否獲得父進程更多的權限。這個布爾值直接控制是否在容器進程上設置了 no_new_privs 標誌。在以下情況下 AllowPrivilegeEscalation 始終爲 true——一是,以特權OR運行;二是,具有 CAP_SYS_ADMIN

    securityContext 字段下配置安全策略,在 Pod 中指定的安全策略將被應用於所有容器,容器中指定的安全策略應用於單個容器,當它們重複時,容器級會覆蓋 Pod 級的的安全策略。

    apiVersion: v1
    kind: Pod
    metadata:
      name: security-context-demo
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 3000
        fsGroup: 2000
      volumes:
      - name: sec-ctx-vol
        emptyDir: {}
      containers:
      - name: sec-ctx-demo
        image: busybox
        command: [ "sh", "-c", "sleep 1h" ]
        volumeMounts:
        - name: sec-ctx-vol
          mountPath: /data/demo
        securityContext:
          runAsUser: 2000
          allowPrivilegeEscalation: false
    

    更多有關信息請參考Pod 安全策略

  • 網絡規則

    Kubernetes允許來自集羣中任何容器的所有網絡流量發送到集羣中的任何其他容器並由其接收。當嘗試隔離工作負載時,這種開放式方法沒有幫助,因此需要應用網絡策略來幫助開發者實現所需的隔離。Kubernetes NetworkPolicy API使開發者能夠將入口和出口規則應用於選定的Pod,用於第3層和第4層流量,並依賴於實現容器網絡接口(CNI)的兼容網絡插件的部署。

    網絡策略是 namespace 作用域,並根據匹配標籤(例如,tier:backend)的選擇應用於Pod。當NetworkPolicy對象的Pod選擇器與Pod匹配時,根據策略中定義的入口和出口規則來管理進出Pod的流量。 所有來自或發往該Pod的流量都會被拒絕,除非有允許它的規則。

    要在Kubernetes集羣中正確隔離網絡和傳輸層的應用程序,網絡策略應以“拒絕所有”的默認前提開始。然後,應將每個應用程序組件及其所需源和目標的規則逐個列入白名單,並進行測試以確保流量模式按預期工作。

  • 密鑰管理

    Kubernetes 使用 Secrets 保護應用程序需要訪問敏感信息——密碼、X.509證書、SSH密鑰或OAuth令牌等。它通過卷裝入,對它的訪問嚴格限於那些需要使用它的實體(用戶和Pod),且當存儲在磁盤上時(靜止狀態)它是不可訪問或只讀的。

需要考慮的全部安全問題如下:

需要關注的安全領域 建議
RBAC 授權 https://kubernetes.io/docs/reference/access-authn-authz/rbac/
認證方式 https://kubernetes.io/docs/reference/access-authn-authz/controlling-access/
密鑰管理 https://kubernetes.io/docs/concepts/configuration/secret/ https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Pod 安全規則 https://kubernetes.io/docs/concepts/policy/pod-security-policy/
服務質量 https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/
網絡規則 https://kubernetes.io/docs/concepts/services-networking/network-policies/
ingress 的 TLS https://kubernetes.io/docs/concepts/services-networking/ingress/#tls

Contanier

爲了在 Kunernetes 中運行軟件,必須將它打包成容器。需要考慮下面的注意事項,來保證容器符合 Kubernetes 安全配置。

  • 最小化鏡像

    理想情況下,使用應用程序二進制文件和二進制文件所依賴的的任何相關項來創建鏡像。事實上,沒有什麼阻止開發者將 scratch 作爲基礎鏡像,並將靜態鏈接的二進制文件複製到鏡像中。它沒有其他依賴,鏡像中包含單個文件,以及一些描述容器如何運行的元數據。最小化鏡像加快鏡像的分發速度,並且顯著減少容器內部的受攻擊面。

  • 基礎鏡像

    但是這並不總是可行的,因此需要慎重選擇基礎鏡像。最佳的方法是使用操作系統供應商支持的鏡像,或者是 docker hub 上官方支持的鏡像。不要盲目使用之前未經過審查的不受信任來源的鏡像,尤其是在生產環境中。

  • 鏡像掃描

    鏡像掃描對於保障容器應用的安全至關重要,確保您的鏡像定期通過信譽良好的工具進行掃描,可以使用 CoreOS 的 Clair 之類的工具掃描容器中的已知漏洞,它是容器鏡像的靜態漏洞分析器。

  • 鏡像的簽名和執行

    使用 CNCF 項目的的 TUF 和 Notary 對容器進行簽名,在執行前驗證簽名,確保鏡像的正確沒有被篡改。

  • 禁止特權用戶

    在構建鏡像時,創建最低操作系統權限的用戶完成容器的運行。

Code

最後是代碼級別,這是程序員能掌控的被攻擊面,但不在 Kubernetes 的安全保護範圍,提供如下建議:

  • 僅通過 TLS 訪問

    如果您的代碼需要通過TCP進行通信,則理想情況下,它將提前與客戶端執行TLS握手。除少數情況外,默認行爲應是對傳輸中的所有內容進行加密。

  • 限制通信範圍

    無論什麼情況下,程序只應該公開必要的端口。

  • 第三方依賴安全性

    確保第三方依賴是安全的。

  • 靜態代碼分析

    大多數語言都提供了靜態代碼分析,可以分析代碼中是否存在潛在的不安全編碼實踐。

  • 動態探測攻擊

    自動化工具可以針對您的服務嘗試會破壞服務的攻擊。這些包括SQL注入,CSRF和XSS。最受歡迎的動態分析工具之一是OWASP Zed Attack代理。

更多關於Kubernetes系列的文章歡迎閱讀:

關於Choerodon豬齒魚

Choerodon豬齒魚是一個開源企業服務平臺,基於Kubernetes的容器編排和管理能力,整合DevOps工具鏈、微服務和移動應用框架,來幫助企業實現敏捷化的應用交付和自動化的運營管理的開源平臺,同時提供IoT、支付、數據、智能洞察、企業應用市場等業務組件,致力幫助企業聚焦於業務,加速數字化轉型。

大家也可以通過以下社區途徑瞭解豬齒魚的最新動態、產品特性,以及參與社區貢獻:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章