全部產品
Search
文件中心

Alibaba Cloud Service Mesh:零信任安全概述

更新時間:Jun 30, 2024

零信任是指無論在網路邊界內部還是外部,都沒有任何隱含的信任。阿里雲Service MeshASM是重要的雲原生零信任體系落地載體之一,將身份認證和授權從應用程式代碼整合到ASM,開箱即用、動態可配、更新策略更加容易且立即生效。本文介紹為什麼要使用ASM實現零信任以及如何使用ASM中的零信任體系。

背景資訊

微服務提供了諸多價值,包括延展性、敏捷性、獨立擴充、商務邏輯隔離、獨立生命週期管理和更容易的分布式開發。然而,這些分布眾多的微服務也會增加安全的挑戰,每個微服務都是一個被攻擊的目標。Kubernetes為託管和編排您的微服務提供了一個出色的平台。但是,預設情況下,微服務之間的所有互動都不安全。它們通過純文字HTTP進行通訊,但這不足以滿足安全要求。只依賴網路邊界來保證安全是不夠的,因為一旦內部的某個服務被攻陷,攻擊者能夠以該機器為跳板來攻擊內網。所以,內部的調用也必須安全,這就是零信任安全的價值。零信任是指任何地方都需要顯式認證,並使用最小許可權原則來限制對資源的訪問。

Service Mesh技術的一個重要的價值主張就是它如何有效地保護應用的生產環境,同時又不降低開發人員的生產力。通過Service Mesh技術,為微服務架構採用零信任網路安全方法提供必要的基礎,以此實現所有訪問都經過強身份認證、基於上下文授權、記錄監控等安全目標。使用這些網格功能,您可以為屬於網格的所有應用程式提供安全控制能力,例如所有流量都已加密、到應用程式的所有流量都通過策略執行點(PEP)的驗證等。

在使用Kubernetes Network Policy實現三層網路安全控制之上,ASM提供了包括對等身份和請求身份認證能力、Istio授權策略以及更為精細化管理的基於OPA(Open Policy Agent)的策略控制能力。阿里雲ASM提供的這些零信任安全能力,協助使用者實現上述這些安全目標。

構建ASM能力的理論體系包括了以下幾個方面:

  • 工作負載身份:零信任的基礎,為雲原生工作負載提供了統一的身份。ASM為Service Mesh下的每一個工作負載提供了簡單易用的身份定義,並根據特定情境提供定製機制用於擴充身份構建體系,同時相容社區SPIFFE標準。

  • 安全性憑證:零信任的載體,ASM提供了認證簽發以及認證生命週期管理、輪轉等機制。通過X509 TLS認證建立身份,每個代理都使用該認證,並提供認證和私密金鑰輪換。

  • 策略執行:零信任的引擎,基於策略的信任引擎是構建零信任的核心,ASM除了支援Istio RBAC授權策略之外,還提供了基於OPA提供更加細粒度的授權策略。

  • 可視化與分析:零信任的洞察,ASM提供了可觀測機制用於監視策略執行的日誌和指標,來判斷每一個策略的執行情況。

為什麼要使用ASM實現零信任

與直接在應用程式代碼中構建安全機制的傳統方法相比,ASM體繫結構具有以下多種安全性好處:

  • Sidecar代理的生命週期與應用程式保持獨立,因此可以更輕鬆地管理這些Sidecar代理。

  • 允許動態配置,更新策略變得更加容易,更新立即生效,而無需重新部署應用程式。

  • ASM的集中控制架構使企業的安全團隊可以構建、管理和部署適用於整個企業的安全性原則,從而預設情況下就能確保應用開發人員構建的業務應用的安全。他們無需額外的工作即可立即使用這些安全性原則。

  • ASM提供了對附加到請求的終端使用者憑證進行身份認證的能力,如JWT。

  • 使用ASM體繫結構,可以將身份認證和授權系統作為服務部署在網格中。如同網格中的其他服務一樣,這些安全系統從網格中也可以得到安全保證,包括傳輸中的加密、身份識別、策略執行點、終端使用者憑證的身份認證和授權等。

藉助ASM,可以使用單個控制平面來實施強大的身份和訪問管理、透明的TLS和加密、身份認證和授權以及稽核線索記錄。ASM開箱即用地提供了這些功能,簡單地安裝和管理使開發人員、系統管理員和安全團隊可以保護其微服務應用程式。

如何使用ASM中的零信任體系

ASM能夠減小雲原生環境中的被攻擊面積,並提供零信任應用網路所需的基礎架構。通過ASM管理服務到服務的安全性,可以確保ASM的端到端加密、服務等級身份認證和細粒度授權策略。

在ASM體系下,可以支援:

  • 在服務之間實施雙向TLS認證或者面向Server側的TLS認證,支援認證的自動輪轉等生命週期管理。網格內的通訊都經過身份認證和加密處理。

  • 啟用基於身份的細粒度授權,以及基於其他維度參數的授權。基於角色存取控制 (RBAC) 的基礎,支援“最低許可權”的立場,也就是只有經過授權的服務才能根據ALLOW或DENY規則相互連信。

1

當前ASM提供了工作負載身份、對等身份認證、請求身份認證、授權策略、OPA策略的零信任安全基本能力。

工作負載身份

當應用程式在ASM環境中運行時,ASM會為每個服務提供一個唯一標識。串連到ASM中啟動並執行其他微服務時,將會使用該標識。服務識別可用於服務的雙向驗證,以此進行驗證是否允許服務間的訪問,同時該服務識別也可用於授權策略中。

當使用ASM管理運行在Kubernetes上的工作負載時,ASM會為每個工作負載提供服務身份。該身份基於工作負載的服務賬戶令牌實現。

ASM中的服務身份符合SPIFFE標準,並具有以下格式:spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>

您可以登入ASM控制台,查看基於Kubernetes叢集接入的服務。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 工作負載身份

  3. 工作負載身份頁面頂部,設定資料面為叢集ID,然後選擇命名空間,查看Kubernetes叢集接入服務網格的工作負載身份。

對等身份認證

ASM提供了兩種身份認證:對等身份認證和請求身份認證。對等身份認證是指當兩個微服務相互互動時,可以啟用雙向TLS進行對等身份認證。

  • 如果請求的用戶端和服務端都注入了Sidecar,預設情況下會啟用ASM的mTLS通訊。

  • 如果只有用戶端注入了Sidecar,用戶端會自行根據服務端的配置,決定是否啟用mTLS通訊。

  • 如果只有服務端注入了Sidecar,預設的mTLS模式是PERMISSIVE,即可以同時接受明文和加密流量。如果您此時給服務端配置了PeerAuthentication,且設定了mTLS模式為STRICT,請求就會失敗。

請求身份認證

ASM提供了兩種身份認證:對等身份認證和請求身份認證。請求身份認證允許終端使用者和系統使用請求身份認證,與微服務進行互動。通常使用JSON Web令牌(JWT)執行該操作。

當請求微服務時,您可以建立請求身分識別驗證策略,對服務的請求執行JWT身分識別驗證。請求身分識別驗證會對帶有JWT Token的請求進行JWT身分識別驗證,只有正確的JWT Token才能訪問服務成功。請求身分識別驗證對不帶有JWT Token的請求不會進行JWT身分識別驗證,不帶有JWT Token的請求不受限制可以正常訪問服務。

說明

您可以使用授權策略和請求身份認證,實現只有正確的JWT Token才能訪問服務,無效的JWT Token或者不帶有JWT Token的請求都將訪問失敗。

  1. 部署被請求的bookinfo應用。具體操作,請參見在ASM執行個體關聯的叢集中部署應用

  2. 部署發起請求的sleep應用。

    1. 在ACK叢集對應的KubeConfig環境下,建立sleep.yaml。

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 執行以下命令,部署sleep應用。

      kubectl apply -f sleep.yaml -n default 
  3. 建立請求身份認證策略,對details服務的入站請求強制執行JWT身份認證。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 請求身份認證,然後單擊建立

    3. 在建立頁面,配置如下資訊,為工作負載details定義JWT規則,然後單擊建立

      3

      部分配置項說明如下:

      • issuer:JWT的頒發者,本樣本設定為testing@secure.istio.io

      • audiences:JWT受眾列表。設定哪些服務可以使用JWT Token訪問目標服務。本樣本設定為空白,表示對訪問的服務不受限制。

      • jwks:設定JWT請求資訊,本樣本設定的JWT請求資訊如下。更多資訊,請參見jwks.json

        { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}
  4. 使用JWT工具將JWT請求資訊編碼成JWT Token。

    { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}

    預期編碼成以下令牌:

    eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
  5. 驗證請求身份認證是否生效。

    1. 執行以下命令,使用上文編碼的JWT Token訪問details服務。

      export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
      kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://details:9080/details/1 -o /dev/null --header "Authorization: Bearer $TOKEN" -s -w '%{http_code}\n'        

      返回200,說明訪問成功。

    2. 執行以下命令,使用無效的JWT Token訪問details服務。

      kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://details:9080/details/1 -o /dev/null --header "Authorization: Bearer badtoken" -s -w '%{http_code}\n'                              

      返回403,說明訪問失敗。

    3. 執行以下命令,不帶JWT Token訪問details服務。

      kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://details:9080/details/1 -o /dev/null  -s -w '%{http_code}\n'

      返回200,說明訪問成功。

      根據以上結果,可以看到使用正確的JWT Token訪問服務成功,使用無效的JWT Token訪問服務失敗,不帶有JWT Token的請求訪問成功。說明請求身份認證生效。

授權策略

當請求微服務時,您可以使用授權策略對請求的連接埠、IP、來源等進行限制,只有符合要求的請求才能訪問服務。以下授權策略對請求來源進行限制,限制請求中必須帶有固定簽發者版發的JWT Token才能訪問服務。

  1. 部署被請求的bookinfo應用。具體操作,請參見在ASM執行個體關聯的叢集中部署應用

  2. 部署發起請求的sleep應用。

    1. 使用以下內容,建立sleep.yaml。

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 在ACK叢集對應的KubeConfig環境下,執行以下命令,部署sleep應用。

      kubectl apply -f sleep.yaml -n default 
  3. 建立授權策略。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊使用YAML建立

  4. 建立頁面,選擇default命名空間,配置如下YAML,然後單擊建立

    關於欄位的說明,請參見Authorization Policy

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: require-jwt
      namespace: default
    spec:
      action: ALLOW
      rules:
        - from:
            - source:
                requestPrincipals:
                  - testing@secure.istio.io/testing@secure.istio.io
      selector:
        matchLabels:
          app: details
  5. 執行以下命令,使用不帶有JWT Token的請求訪問服務。

     kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://details:9080/details/1 -o /dev/null  -s -w '%{http_code}\n'

    預期輸出:

    403

    不使用JWT Token訪問details服務訪問失敗,說明授權策略生效。授權策略限制了所有請求必須帶有testing@secure.istio.io頒發的JWT Token才能訪問服務成功。

OPA策略

OPA是一個策略引擎,可為您的應用程式實現細粒度的存取控制。OPA作為通用策略引擎,可以與微服務一起部署為獨立服務。為了保護應用程式,必須先授權對微服務的每個請求,然後才能對其進行處理。為了檢查授權,微服務對OPA進行API調用,以確定請求是否被授權。更多資訊,請參見OPA

ASM整合了開放策略代理(OPA)外掛程式,通過OPA定義存取控制策略,可以使您的應用實現細粒度的存取控制,並支援動態更新OPA策略。具體操作,請參見在ASM中實現動態更新OPA策略

總結及參考案例

綜上所述,ASM提供了以下增強安全性的組件:

  • 提供具有完整認證生命週期管理的託管認證基礎設施,解決了憑證發行和CA輪換的複雜性。

  • 託管的控制面API,用於向Envoy代理分發身份認證策略、授權策略和安全命名資訊。

  • Sidecar代理通過提供策略執行點PEP來協助確保網格的安全。

  • Envoy代理擴充允許遙測資料收集和審計。

每一個工作負載通過X509 TLS認證建立身份,每個Sidecar代理都使用該認證。ASM會提供並定期輪換認證和私密金鑰。如果某個特定的私密金鑰被盜用,ASM很快就會用新的私密金鑰替換它,從而大大減少了攻擊面。

參考案例

  • 使用授權策略在入口網關上實施基於IP的存取控制或者基於自訂外部授權的存取控制等。

  • 某互聯金融客戶在解決跨叢集多語言應用的存取權限控制方面,使用ASM提供的授權策略隔離外聯地區和應用地區。同時結合出口網關審計網格的流量,配合授權策略,控制應用對第三方服務的存取權限。