授權政策總覽
單體式應用程式可能在單一位置執行,但全球分散式微服務應用程式會在網路邊界之間發出呼叫。這表示應用程式的進入點更多,惡意攻擊的機會也更多。此外,由於 Kubernetes Pod 具有暫時 IP,傳統以 IP 為基礎的防火牆規則不足以保護工作負載之間的存取。在微服務架構中,必須採用新的安全性做法。Cloud Service Mesh 以 Kubernetes 服務帳戶和 Istio 安全性政策等安全防護功能為基礎,提供更多功能,協助您保護應用程式。
本頁面提供應用程式運作人員 AuthorizationPolicy 自訂資源 (CR) 的總覽。授權政策可讓您在應用程式 (L7) 和傳輸 (L3/4) 層啟用工作負載的存取控管。您可以設定授權政策來指定權限,也就是這項服務或使用者可以執行的操作。
授權政策
根據預設,網格中服務之間 (以及使用者與服務之間) 的要求皆可通過。您可以使用 AuthorizationPolicy CR 為工作負載定義精細政策。套用授權政策後,Cloud Service Mesh 會將政策發布至 Sidecar Proxy。當要求進入工作負載時,Sidecar Proxy 會檢查授權政策,判斷是否應允許或拒絕要求。
如要進一步瞭解平台支援 AuthorizationPolicy CR 的哪些欄位,請參閱「支援的功能」。
政策範圍
您可以將政策套用至整個服務網格、命名空間或個別工作負載。
如要套用網格層級政策,請在
metadata:namespace欄位中指定根命名空間istio-system:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...如要將政策套用至命名空間,請在
metadata:namespace欄位中指定命名空間:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...如要將政策限制在特定工作負載,請加入
selector欄位。apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
基本結構
授權政策包含政策範圍、action 和 rules 清單:
如上一節所述,政策範圍可以是整個網格、命名空間或特定工作負載。如果加入這個欄位,
selector欄位會指定政策的目標。action欄位指定要ALLOW還是DENY要求。如未指定動作,系統預設會將動作設為ALLOW。為求明確,建議您一律指定動作。(授權政策也支援AUDIT和CUSTOM動作。只有部分平台支援AUDIT動作。詳情請參閱「支援的功能」。)rules指定觸發動作的時間。
在下列範例中:
這項政策會套用至
demo命名空間中傳送至frontend服務的要求。如果要求標頭中包含「hello:world」,系統就會允許要求,否則會拒絕要求。
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
要求作業的存取控管
您可以在 rules 下方新增 to 區段,控管特定要求作業 (例如 HTTP 方法或 TCP 通訊埠) 的存取權。在以下範例中,只有 GET 和 POST HTTP 方法可以存取 demo 命名空間中的 currencyservice。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
對已驗證身分進行存取控管
在上述範例中,政策允許來自未經驗證工作負載的要求。如果您已啟用STRICT雙向 TLS (mTLS),則可在source部分,根據要求來源的工作負載或命名空間身分限制存取權。
使用
principals或notPrincipal欄位,在工作負載層級控管存取權。使用
namespaces或notNamespaces欄位,在命名空間層級控管存取權。
上述所有欄位都必須啟用 STRICT mTLS。如果無法設定 STRICT mTLS,請參閱「拒絕明文要求」一節,瞭解替代解決方案。
找到的工作負載
在以下範例中,只有 frontend 服務可以向 currencyservice 傳送要求。來自其他工作負載的 currencyservice 要求會遭到拒絕。
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
如要指定服務帳戶,principals 必須採用下列格式:
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
如果您使用叢集內 Cloud Service Mesh 搭配 Citadel CA,則 cluster.local 是信任網域。在所有其他情況下,PROJECT_ID.svc.id.goog是網格的信任網域。
信任網域對應至系統的信任根,是 Workload Identity 的一部分。Cloud Service Mesh 會使用信任網域,在網格中建立所有身分。舉例來說,在 SPIFFE ID
spiffe://mytrustdomain.com/ns/default/sa/myname 中,子字串 mytrustdomain.com 指定工作負載來自名為 mytrustdomain.com 的信任網域。
使用 Cloud Service Mesh 憑證授權單位時,Cloud Service Mesh 會自動產生信任網域。這項設定是根據叢集的工作負載集區而定。
只要叢集共用相同的信任根,多叢集網格中就能有一或多個信任網域。
已識別的命名空間
以下範例顯示的政策會拒絕來源不是 foo 命名空間的要求:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
值比對
授權政策中的多數欄位都支援下列所有比對結構定義:
- 完全比對:完全比對字串。
- 使用
"*"萬用字元進行萬用字元比對:- 前置字元比對:以
"*"結尾的字串。舉例來說,"test.example.*"與"test.example.com"或"test.example.com.cn"相符。 - 後置字串比對:以
"*"開頭的字串。舉例來說,"*.example.com"與"eng.example.com"或"test.eng.example.com"相符。
- 前置字元比對:以
- 存在比對:如要指定欄位必須存在且不得為空白,請使用
fieldname: ["*"]格式。這與不指定欄位不同,不指定欄位代表比對任何內容,包括空白。
但有幾種情況例外。舉例來說,下列欄位僅支援完全比對:
- 「
when」部分下方的「key」欄位 - 「
source」部分下方的「ipBlocks」 - 「
to」部分下方的「ports」欄位
以下範例政策允許存取前置字串為 /test/* 或後置字串為 */info 的路徑:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
排除條件比對
如要比對 when 欄位中的 notValues、source 欄位中的 notIpBlocks、to 欄位中的 notPorts 等負面條件,Cloud Service Mesh 支援排除比對。如果要求路徑不是 /healthz,下列範例需要有效的要求 principals,該要求衍生自 JWT 驗證。因此,這項政策會將傳送至 /healthz 路徑的要求排除在 JWT 驗證之外:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
拒絕明文要求
Cloud Service Mesh 預設會啟用自動 mTLS。啟用自動 mTLS 後,用戶端 Sidecar Proxy 會自動偵測伺服器是否有 Sidecar。用戶端 Sidecar 會將 mTLS 傳送至具有 Sidecar 的工作負載,並將純文字傳送至沒有 Sidecar 的工作負載。為確保最佳安全性,建議您啟用 STRICT mTLS。
如果無法為工作負載或命名空間啟用 STRICT 模式的 mTLS,可以採取下列做法:
- 建立授權政策,明確允許
namespaces或principals非空白的流量,或 - 拒絕
namespaces或principals為空的流量。
由於 namespaces 和 principals 只能透過 mTLS 要求擷取,因此這些政策會有效拒絕任何純文字流量。
如果要求中的主體為空白 (明文要求即是如此),下列政策會拒絕要求。如果主體不為空白,政策就會允許要求。["*"] 表示非空白比對,與 notPrincipals 搭配使用則表示比對空白主體。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
授權政策優先順序
您可以分別設定 ALLOW 和 DENY 授權政策,但必須瞭解政策優先順序和預設行為,確保政策能發揮預期效果。下圖說明政策優先順序。
以下各節的範例政策說明瞭一些預設行為,以及可能適用的情況。
全部禁止
以下範例顯示不符合任何項目的 ALLOW 政策。根據預設,如果沒有其他 ALLOW 政策,要求一律會遭拒。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
建議您先採用「不允許任何項目」政策,然後逐步新增更多 ALLOW 政策,開放更多工作負載存取權,這是良好的安全性做法。
拒絕所有存取權
以下範例顯示比對所有項目的 DENY 政策。由於系統會在評估 ALLOW 政策前先評估 DENY 政策,因此即使有與要求相符的 ALLOW 政策,所有要求仍會遭拒。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
如要暫時停用工作負載的所有存取權,可以使用「全部拒絕」政策。
允許超級 VIP
以下範例顯示比對所有項目的 ALLOW 政策,並允許完整存取工作負載。「全部允許」政策一律會允許要求,因此其他 ALLOW 政策會失效。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
如要暫時公開工作負載的完整存取權,可以使用「全部允許」政策。如果存在任何 DENY 政策,系統會先評估 DENY 政策,再評估 ALLOW 政策,因此要求仍可能遭到拒絕。
最佳做法
為每項服務建立 Kubernetes 服務帳戶,並在 Deployment 中指定服務帳戶。例如:
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...首先,請採用不允許任何存取權的政策,然後逐步新增更多
ALLOW政策,開放更多工作負載存取權。如果服務使用 JWT:
建立
DENY政策來封鎖未經驗證的要求,例如:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]套用「不允許任何項目」政策。
為每個工作負載定義
ALLOW政策。如需範例,請參閱「JWT 權杖」。
後續步驟
進一步瞭解 Cloud Service Mesh 安全防護功能:
- 設定 Cloud Service Mesh 使用者驗證
- 設定服務的稽核政策
- 設定傳輸安全性
- 將 Identity-Aware Proxy 與 Cloud Service Mesh 整合
- 在 GKE 叢集使用 Cloud Service Mesh egress 閘道的最佳做法
如要進一步瞭解授權政策,請參閱 Istio 說明文件: