解决 Cloud Service Mesh 中的安全问题

本部分介绍常见的 Cloud Service Mesh 和 Istio API 问题,以及 解决方法。如果您需要其他帮助,请参阅获取支持

在 Cloud Service Mesh 中,Cloud Service Mesh 证书授权机构或 Istiod 向网格中所有集群的工作负载颁发证书。身份验证(例如 mTLS)和授权政策(例如允许/拒绝)将被推送到每个集群。这些政策决定了哪些工作负载可以通信以及如何通信。

TLS 问题

以下部分介绍了如何在 Google Cloud 控制台中解决 Cloud Service Mesh。

本部分中的示例使用变量 ${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 软件包。

    Sidecar 注入器 Webhook(用于自动执行 Sidecar 注入)需要使用 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 部署使用的是否是指定的服务账号。

Istiod 日志中的 serverca 进程错误

您可能会看到类似于以下内容的错误:

Authentication failed: Authenticator ClientCertAuthenticator at index 0 got error

您可以使用正则表达式字符串 /serverca.*Authentication failed:.*JWT/ 在日志中查找这些错误。

如果 JWT 颁发者配置有误、客户端使用的是过期的令牌,或者存在其他某个安全问题导致连接无法向 Istiod 正确进行身份验证,则可能会出现此错误。