零信任安全概述
零信任是指無論在網(wǎng)絡(luò)邊界內(nèi)部還是外部,都沒有任何隱含的信任。阿里云服務(wù)網(wǎng)格ASM是重要的云原生零信任體系落地載體之一,將身份認證和授權(quán)從應(yīng)用程序代碼集成到ASM,開箱即用、動態(tài)可配、更新策略更加容易且立即生效。本文介紹為什么要使用ASM實現(xiàn)零信任以及如何使用ASM中的零信任體系。
背景信息
微服務(wù)提供了諸多價值,包括可伸縮性、敏捷性、獨立擴展、業(yè)務(wù)邏輯隔離、獨立生命周期管理和更容易的分布式開發(fā)。然而,這些分布眾多的微服務(wù)也會增加安全的挑戰(zhàn),每個微服務(wù)都是一個被攻擊的目標。Kubernetes為托管和編排您的微服務(wù)提供了一個出色的平臺。但是,默認情況下,微服務(wù)之間的所有交互都不安全。它們通過純文本HTTP進行通信,但這不足以滿足安全要求。只依賴網(wǎng)絡(luò)邊界來保證安全是不夠的,因為一旦內(nèi)部的某個服務(wù)被攻陷,攻擊者能夠以該機器為跳板來攻擊內(nèi)網(wǎng)。所以,內(nèi)部的調(diào)用也必須安全,這就是零信任安全的價值。零信任是指任何地方都需要顯式認證,并使用最小權(quán)限原則來限制對資源的訪問。
服務(wù)網(wǎng)格技術(shù)的一個重要的價值主張就是它如何有效地保護應(yīng)用的生產(chǎn)環(huán)境,同時又不降低開發(fā)人員的生產(chǎn)力。通過服務(wù)網(wǎng)格技術(shù),為微服務(wù)架構(gòu)采用零信任網(wǎng)絡(luò)安全方法提供必要的基礎(chǔ),以此實現(xiàn)所有訪問都經(jīng)過強身份認證、基于上下文授權(quán)、記錄監(jiān)控等安全目標。使用這些網(wǎng)格功能,您可以為屬于網(wǎng)格的所有應(yīng)用程序提供安全控制能力,例如所有流量都已加密、到應(yīng)用程序的所有流量都通過策略執(zhí)行點(PEP)的驗證等。
在使用Kubernetes Network Policy實現(xiàn)三層網(wǎng)絡(luò)安全控制之上,ASM提供了包括對等身份和請求身份認證能力、Istio授權(quán)策略以及更為精細化管理的基于OPA(Open Policy Agent)的策略控制能力。阿里云ASM提供的這些零信任安全能力,幫助用戶實現(xiàn)上述這些安全目標。
構(gòu)建ASM能力的理論體系包括了以下幾個方面:
工作負載身份:零信任的基礎(chǔ),為云原生工作負載提供了統(tǒng)一的身份。ASM為服務(wù)網(wǎng)格下的每一個工作負載提供了簡單易用的身份定義,并根據(jù)特定場景提供定制機制用于擴展身份構(gòu)建體系,同時兼容社區(qū)SPIFFE標準。
安全證書:零信任的載體,ASM提供了證書簽發(fā)以及證書生命周期管理、輪轉(zhuǎn)等機制。通過X509 TLS證書建立身份,每個代理都使用該證書,并提供證書和私鑰輪換。
策略執(zhí)行:零信任的引擎,基于策略的信任引擎是構(gòu)建零信任的核心,ASM除了支持Istio RBAC授權(quán)策略之外,還提供了基于OPA提供更加細粒度的授權(quán)策略。
可視化與分析:零信任的洞察,ASM提供了可觀測機制用于監(jiān)視策略執(zhí)行的日志和指標,來判斷每一個策略的執(zhí)行情況。
為什么要使用ASM實現(xiàn)零信任
與直接在應(yīng)用程序代碼中構(gòu)建安全機制的傳統(tǒng)方法相比,ASM體系結(jié)構(gòu)具有以下多種安全性好處:
Sidecar代理的生命周期與應(yīng)用程序保持獨立,因此可以更輕松地管理這些Sidecar代理。
允許動態(tài)配置,更新策略變得更加容易,更新立即生效,而無需重新部署應(yīng)用程序。
ASM的集中控制架構(gòu)使企業(yè)的安全團隊可以構(gòu)建、管理和部署適用于整個企業(yè)的安全策略,從而默認情況下就能確保應(yīng)用開發(fā)人員構(gòu)建的業(yè)務(wù)應(yīng)用的安全。他們無需額外的工作即可立即使用這些安全策略。
ASM提供了對附加到請求的終端用戶憑據(jù)進行身份認證的能力,如JWT。
使用ASM體系結(jié)構(gòu),可以將身份認證和授權(quán)系統(tǒng)作為服務(wù)部署在網(wǎng)格中。如同網(wǎng)格中的其他服務(wù)一樣,這些安全系統(tǒng)從網(wǎng)格中也可以得到安全保證,包括傳輸中的加密、身份識別、策略執(zhí)行點、終端用戶憑據(jù)的身份認證和授權(quán)等。
借助ASM,可以使用單個控制平面來實施強大的身份和訪問管理、透明的TLS和加密、身份認證和授權(quán)以及審核日志記錄。ASM開箱即用地提供了這些功能,簡單地安裝和管理使開發(fā)人員、系統(tǒng)管理員和安全團隊可以保護其微服務(wù)應(yīng)用程序。
如何使用ASM中的零信任體系
ASM能夠減小云原生環(huán)境中的被攻擊面積,并提供零信任應(yīng)用網(wǎng)絡(luò)所需的基礎(chǔ)框架。通過ASM管理服務(wù)到服務(wù)的安全性,可以確保ASM的端到端加密、服務(wù)級別身份認證和細粒度授權(quán)策略。
在ASM體系下,可以支持:
在服務(wù)之間實施雙向TLS認證或者面向Server側(cè)的TLS認證,支持證書的自動輪轉(zhuǎn)等生命周期管理。網(wǎng)格內(nèi)的通信都經(jīng)過身份認證和加密處理。
啟用基于身份的細粒度授權(quán),以及基于其他維度參數(shù)的授權(quán)。基于角色訪問控制 (RBAC) 的基礎(chǔ),支持“最低權(quán)限”的立場,也就是只有經(jīng)過授權(quán)的服務(wù)才能根據(jù)ALLOW或DENY規(guī)則相互通信。
當前ASM提供了工作負載身份、對等身份認證、請求身份認證、授權(quán)策略、OPA策略的零信任安全基本能力。
工作負載身份
當應(yīng)用程序在ASM環(huán)境中運行時,ASM會為每個服務(wù)提供一個唯一標識。連接到ASM中運行的其他微服務(wù)時,將會使用該標識。服務(wù)標識可用于服務(wù)的雙向驗證,以此進行驗證是否允許服務(wù)間的訪問,同時該服務(wù)標識也可用于授權(quán)策略中。
當使用ASM管理運行在Kubernetes上的工作負載時,ASM會為每個工作負載提供服務(wù)身份。該身份基于工作負載的服務(wù)賬戶令牌實現(xiàn)。
ASM中的服務(wù)身份符合SPIFFE標準,并具有以下格式:spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>
。
您可以登錄ASM控制臺,查看基于Kubernetes集群接入的服務(wù)。
登錄ASM控制臺,在左側(cè)導(dǎo)航欄,選擇 。
在網(wǎng)格管理頁面,單擊目標實例名稱,然后在左側(cè)導(dǎo)航欄,選擇 。
在工作負載身份頁面頂部,設(shè)置數(shù)據(jù)面為集群ID,然后選擇命名空間,查看Kubernetes集群接入服務(wù)網(wǎng)格的工作負載身份。
對等身份認證
ASM提供了兩種身份認證:對等身份認證和請求身份認證。對等身份認證是指當兩個微服務(wù)相互交互時,可以啟用雙向TLS進行對等身份認證。
如果請求的客戶端和服務(wù)端都注入了Sidecar,默認情況下會啟用ASM的mTLS通信。
如果只有客戶端注入了Sidecar,客戶端會自行根據(jù)服務(wù)端的配置,決定是否啟用mTLS通信。
如果只有服務(wù)端注入了Sidecar,默認的mTLS模式是PERMISSIVE,即可以同時接受明文和加密流量。如果您此時給服務(wù)端配置了PeerAuthentication,且設(shè)置了mTLS模式為STRICT,請求就會失敗。
請求身份認證
ASM提供了兩種身份認證:對等身份認證和請求身份認證。請求身份認證允許最終用戶和系統(tǒng)使用請求身份認證,與微服務(wù)進行交互。通常使用JSON Web令牌(JWT)執(zhí)行該操作。
當請求微服務(wù)時,您可以創(chuàng)建請求身份驗證策略,對服務(wù)的請求執(zhí)行JWT身份驗證。請求身份驗證會對帶有JWT Token的請求進行JWT身份驗證,只有正確的JWT Token才能訪問服務(wù)成功。請求身份驗證對不帶有JWT Token的請求不會進行JWT身份驗證,不帶有JWT Token的請求不受限制可以正常訪問服務(wù)。
您可以使用授權(quán)策略和請求身份認證,實現(xiàn)只有正確的JWT Token才能訪問服務(wù),無效的JWT Token或者不帶有JWT Token的請求都將訪問失敗。
部署被請求的bookinfo應(yīng)用。具體操作,請參見在ASM實例關(guān)聯(lián)的集群中部署應(yīng)用。
部署發(fā)起請求的sleep應(yīng)用。
在ACK集群對應(yīng)的KubeConfig環(huán)境下,創(chuàng)建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 ---
執(zhí)行以下命令,部署sleep應(yīng)用。
kubectl apply -f sleep.yaml -n default
創(chuàng)建請求身份認證策略,對details服務(wù)的入站請求強制執(zhí)行JWT身份認證。
登錄ASM控制臺,在左側(cè)導(dǎo)航欄,選擇 。
在網(wǎng)格管理頁面,單擊目標實例名稱,然后在左側(cè)導(dǎo)航欄,選擇 ,然后單擊創(chuàng)建。
在創(chuàng)建頁面,配置如下信息,為工作負載details定義JWT規(guī)則,然后單擊創(chuàng)建。
部分配置項說明如下:
issuer:JWT的頒發(fā)者,本示例設(shè)置為testing@secure.istio.io。
audiences:JWT受眾列表。設(shè)置哪些服務(wù)可以使用JWT Token訪問目標服務(wù)。本示例設(shè)置為空,表示對訪問的服務(wù)不受限制。
jwks:設(shè)置JWT請求信息,本示例設(shè)置的JWT請求信息如下。更多信息,請參見jwks.json。
{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}
使用JWT工具將JWT請求信息編碼成JWT Token。
{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}
預(yù)期編碼成以下令牌:
eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
驗證請求身份認證是否生效。
執(zhí)行以下命令,使用上文編碼的JWT Token訪問details服務(wù)。
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,說明訪問成功。
執(zhí)行以下命令,使用無效的JWT Token訪問details服務(wù)。
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,說明訪問失敗。
執(zhí)行以下命令,不帶JWT Token訪問details服務(wù)。
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,說明訪問成功。
根據(jù)以上結(jié)果,可以看到使用正確的JWT Token訪問服務(wù)成功,使用無效的JWT Token訪問服務(wù)失敗,不帶有JWT Token的請求訪問成功。說明請求身份認證生效。
授權(quán)策略
當請求微服務(wù)時,您可以使用授權(quán)策略對請求的端口、IP、來源等進行限制,只有符合要求的請求才能訪問服務(wù)。以下授權(quán)策略對請求來源進行限制,限制請求中必須帶有固定簽發(fā)者版發(fā)的JWT Token才能訪問服務(wù)。
部署被請求的bookinfo應(yīng)用。具體操作,請參見在ASM實例關(guān)聯(lián)的集群中部署應(yīng)用。
部署發(fā)起請求的sleep應(yīng)用。
使用以下內(nèi)容,創(chuàng)建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 ---
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,部署sleep應(yīng)用。
kubectl apply -f sleep.yaml -n default
創(chuàng)建授權(quán)策略。
登錄ASM控制臺,在左側(cè)導(dǎo)航欄,選擇 。
在網(wǎng)格管理頁面,單擊目標實例名稱,然后在左側(cè)導(dǎo)航欄,選擇 ,然后單擊使用YAML創(chuàng)建。
在創(chuàng)建頁面,選擇default命名空間,配置如下YAML,然后單擊創(chuàng)建。
關(guān)于字段的說明,請參見授權(quán)策略(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
執(zhí)行以下命令,使用不帶有JWT Token的請求訪問服務(wù)。
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'
預(yù)期輸出:
403
不使用JWT Token訪問details服務(wù)訪問失敗,說明授權(quán)策略生效。授權(quán)策略限制了所有請求必須帶有
testing@secure.istio.io
頒發(fā)的JWT Token才能訪問服務(wù)成功。
OPA策略
OPA是一個策略引擎,可為您的應(yīng)用程序?qū)崿F(xiàn)細粒度的訪問控制。OPA作為通用策略引擎,可以與微服務(wù)一起部署為獨立服務(wù)。為了保護應(yīng)用程序,必須先授權(quán)對微服務(wù)的每個請求,然后才能對其進行處理。為了檢查授權(quán),微服務(wù)對OPA進行API調(diào)用,以確定請求是否被授權(quán)。更多信息,請參見OPA。
ASM集成了開放策略代理(OPA)插件,通過OPA定義訪問控制策略,可以使您的應(yīng)用實現(xiàn)細粒度的訪問控制,并支持動態(tài)更新OPA策略。具體操作,請參見在ASM中實現(xiàn)動態(tài)更新OPA策略。
總結(jié)及參考案例
綜上所述,ASM提供了以下增強安全性的組件:
提供具有完整證書生命周期管理的托管證書基礎(chǔ)設(shè)施,解決了證書頒發(fā)和CA輪換的復(fù)雜性。
托管的控制面API,用于向Envoy代理分發(fā)身份認證策略、授權(quán)策略和安全命名信息。
Sidecar代理通過提供策略執(zhí)行點PEP來幫助確保網(wǎng)格的安全。
Envoy代理擴展允許遙測數(shù)據(jù)收集和審計。
每一個工作負載通過X509 TLS證書建立身份,每個Sidecar代理都使用該證書。ASM會提供并定期輪換證書和私鑰。如果某個特定的私鑰被盜用,ASM很快就會用新的私鑰替換它,從而大大減少了攻擊面。
參考案例
使用授權(quán)策略在入口網(wǎng)關(guān)上實施基于IP的訪問控制或者基于自定義外部授權(quán)的訪問控制等。
某互聯(lián)金融客戶在解決跨集群多語言應(yīng)用的訪問權(quán)限控制方面,使用ASM提供的授權(quán)策略隔離外聯(lián)區(qū)域和應(yīng)用區(qū)域。同時結(jié)合出口網(wǎng)關(guān)審計網(wǎng)格的流量,配合授權(quán)策略,控制應(yīng)用對第三方服務(wù)的訪問權(quán)限。