解決 Cloud Service Mesh 中的安全性問題

本節說明 Cloud Service Mesh 與 Istio API 的常見問題,以及解決問題的方法。如需其他協助,請參閱取得支援

在 Cloud Service Mesh 中,Cloud Service Mesh 憑證授權單位或 Istiod 會為網格中所有叢集的工作負載核發憑證。驗證 (例如 mTLS) 和授權政策 (例如允許/拒絕) 會推送至各個叢集。這些政策會決定哪些工作負載可以進行通訊,以及通訊方式。

TLS 問題

下列各節說明如何解決 Cloud Service Mesh 中的 TLS 相關問題。

本節的範例會使用變數 ${CTX},這是您用來存取叢集的預設 Kubernetes 設定檔中的內容名稱。設定 ${CTX} 變數,如以下範例所示:

export CTX=gke_PROJECT_ID_CLUSTER_LOCATION_CLUSTER_NAME

驗證 TLS 強制執行

確認服務要求傳輸層安全標準 (TLS) 連線時,是否禁止使用純文字要求:

kubectl exec SOURCE_POD -n SOURCE_NAMESPACE -c \
    SOURCE_CONTAINER -- curl -v DESTINATION_URL

假設服務需要 TLS 連線,上述的純文字要求應會失敗,導致輸出類似以下的內容:

curl: (56) Recv failure: Connection reset by peer command terminated with exit code 56

檢查 mTLS 憑證

啟用 mTLS 後,請查看 X-Forwarded-Client-Cert 標頭,檢查工作負載的 mTLS 憑證。如要這樣做,請按照下列步驟操作:

  1. 部署 httpbin 範例服務,該服務可顯示收到的標頭。

  2. 使用 curl 查看 X-Forwarded-Client-Cert 標頭:

    kubectl exec --context=${CTX} SOURCE_POD -n SOURCE_NAMESPACE -c \
    SOURCE_CONTAINER -- curl http://httpbin.sample:8000/headers -s | \
    grep X-Forwarded-Client-Cert

    X-Forwarded-Client-Cert 標頭會顯示 mTLS 憑證資訊,如以下範例所示:

    X-Forwarded-Client-Cert": "By=spiffe://lt-multicluster-t2-5-15-2020.svc.id.goog/ns/sample/sa/httpbin;Hash=0781d68adfdab85b08b6758ed502f352464e81166f065cc6acde9433337b4494;Subject=\"OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US\";URI=spiffe://lt-multicluster-t2-5-15-2020.svc.id.goog/ns/sample/sa/sleep
  3. 或者,您也可以在 sidecar 上使用 openssl 查看整個憑證鏈結:

    kubectl debug --image istio/base --target istio-proxy -it --context=${CTX} SOURCE_POD \
    -n SOURCE_NAMESPACE -- openssl s_client -alpn istio -showcerts -connect httpbin.sample:8000

    輸出內容會顯示憑證鏈結。如果您使用的是 Mesh CA,請確認根憑證 CN 包含 istio_v1_cloud_workload_root-signer-...。如果您使用 Istiod 做為憑證授權單位,請確認根憑證是否已使用 O = <var>YOUR_TRUST_DOMAIN</var> 設定。

Istiod 記錄中的 TLS bad certificate 錯誤

如果您在記錄中看到 TLS 握手 bad certificate 錯誤,可能表示 Istiod 無法與服務建立 TLS 連線。

您可以使用規則運算式字串 TLS handshake error.*bad certificate 在記錄中找出這些錯誤。

這些錯誤通常是資訊性質,且會暫時性發生。不過,如果這些問題持續發生,可能表示系統有問題。

  1. 確認 istio-sidecar-injector MutatingWebhookConfiguration 有 CA 組合。

    補充資訊注入器 webhook (用於自動補充資訊注入) 需要 CA 套件,才能與 API 伺服器和 Istiod 建立安全連線。這個 CA 組合會由 istiod 修補至設定中,但有時可能會遭到覆寫 (例如,如果您重新套用 webhook 設定)。

  2. 驗證 CA 組合是否存在:

    kubectl get mutatingwebhookconfiguration -l app=sidecar-injector -o=jsonpath='{.items[0].webhooks[0].clientConfig.caBundle}'
    

    如果輸出內容不為空白,表示已設定 CA 組合。如果 CA 組合包遺失,請重新啟動 istiod,讓它重新掃描 webhook,然後重新安裝 CA 組合包。

授權政策拒絕記錄

如要瞭解授權政策拒絕記錄,請參閱拒絕記錄

未強制執行授權政策

如果您發現授權政策未確實執行的症狀,請使用下列指令進行驗證:

kubectl exec --context=${CTX} -it SOURCE_POD -n SOURCE_NAMESPACE \
    -c SOURCE_CONTAINER -- curl DESTINATION_URL

在輸出內容中,access denied 訊息表示授權政策已正確強制執行,如下所示:

RBAC: access denied

如果您確認未強制執行授權政策,請拒絕存取命名空間。以下範例會拒絕存取名為 authz-ns 的命名空間:

kubectl apply --context=${CTX} -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-authz-ns
  namespace: authz-ns
spec:
  {}
EOF

Istiod 記錄中出現「customresourcedefinitions.apiextensions.k8s.io is forbidden」錯誤

您可能會看到類似以下的錯誤訊息:

error failed to list CRDs: customresourcedefinitions.apiextensions.k8s.io is forbidden: User "system:serviceaccount:istio-system:istiod-service-account" cannot list resource "customresourcedefinitions" in API group "apiextensions.k8s.io" at the cluster scope

您可以使用規則運算式字串 /error.*cannot list resource/,在記錄中找出這些錯誤。

如果 Istiod 部署作業缺少正確的 IAM 繫結,或是 RBAC 權限不足以讀取自訂資源,就可能發生這項錯誤。

  1. 請檢查帳戶是否缺少 IAM 繫結。首先,請確認您已正確設定憑證和權限。接著,使用下列指令檢查 IAM 繫結是否存在。在本例中,PROJECT_ID 是 gcloud config get-value project 的輸出內容,而 PROJECT_NUMBER 是 gcloud projects list --filter="project_id=${PROJECT_ID}" --format="value(project_number)" 的輸出內容:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-meshdataplane.iam.gserviceaccount.com" --role "roles/meshdataplane.serviceAgent"
  2. 檢查 RBAC 規則是否正確安裝。

  3. 如果找不到 RBAC 規則,請重新執行 asmcli install 重新建立規則。

  4. 如果 RBAC 規則存在且錯誤仍持續發生,請確認 ClusterRoleBindingsRoleBindings 是否將 RBAC 規則附加至正確的 Kubernetes 服務帳戶。此外,請確認 istiod 部署作業是否使用指定的服務帳戶。

serverca 在 Istiod 記錄檔中顯示的程序錯誤

您可能會看到類似以下的錯誤訊息:

Authentication failed: Authenticator ClientCertAuthenticator at index 0 got error

您可以使用規則運算式字串 /serverca.*Authentication failed:.*JWT/,在記錄中找出這些錯誤。

如果 JWT 發出者設定錯誤、用戶端使用已過期的權杖,或是其他安全性問題導致連線無法正確驗證至 istiod,就可能發生這個錯誤。

Ingress Gateway TLS 的憑證和私密金鑰更新速度緩慢

如果叢集使用 TRAFFIC_DIRECTOR 控制層實作,且入口網頁閘道使用未掛載憑證的部署,憑證更新作業可能需要 60 分鐘。

如要讓新憑證立即生效,您可以重新啟動入口網關 Pod,或按照最佳化部署作業的操作說明進行。