验证 Google 与 GKE 控制平面的连接


本页介绍了如何通过将 GKE 日志与 Access Transparency 日志相关联,验证 Google 人员与您的 Google Kubernetes Engine (GKE) 集群控制平面之间的连接。

Access Transparency 日志会记录 Google 员工在访问您的内容时所采取的操作。本指南适用于希望通过与 GKE 中的其他日志来源相关联,对 Access Transparency 日志的内容和相关的 Access Approval 审批进行进一步验证的安全管理员。此验证完全是可选的,对控制平面的安全性而言并非必需。

确保熟悉以下概念:

本页介绍了 GKE 中一组可选控制平面功能的一部分,可让您执行各种任务,例如验证控制平面安全状况,或使用您管理的密钥在控制平面中配置加密和凭据签名。 如需了解详情,请参阅 GKE 控制平面授权简介

默认情况下,Google Cloud 会对托管式控制平面应用各种安全措施。 本页介绍了一些可选功能,可让您更好地了解 GKE 控制平面或对其进行控制。

关于 Google 对集群控制平面实例的访问权限

在问题排查会话期间或出于其他合理的业务原因,网站可靠性工程师和 Cloud 客户服务人员等 Google 人员可能需要对托管控制平面的 Compute Engine 实例拥有管理员访问权限。根据您的客户服务支持包和配置,Access Transparency 会为此类管理员权限提供详细的审核日志记录。借助 Access Approval,您可以要求任何 Google 人员先获得明确批准,然后才能访问您的资源。如需详细了解管理员权限以及您可以用来授予访问权限和记录更改的工具,请参阅 Google 员工的管理员权限

控制平面访问日志

启用 GKE 控制平面授权后,GKE 会生成控制平面访问日志,您可以选择使用这些日志来交叉参考由 Access Transparency 和 Access Approval 生成的审核日志。GKE 会将控制平面访问日志添加到 Logging 中的 _Default 存储桶,以记录控制平面实例中的传入网络连接和特定 SSH 事件。您必须在项目中启用 GKE 控制平面授权,才能为集群生成控制平面访问日志。

GKE 会为控制平面生成以下访问日志:

控制平面连接日志的大小取决于集群中的节点数量、控制平面实例数量(区域性集群的控制平面实例数量比可用区集群多),以及工作负载调用 Kubernetes API 服务器的频率等因素。SSH 日志的数量很少,并且取决于节点重启的次数。

如需验证与控制平面的连接,您可以找到集群的控制平面访问日志,并将这些日志与 Access Transparency 和 Access Approval 中的审核日志进行匹配。这样,您就可以确认对控制平面实例的所有 SSH 连接都是由 Google 人员通过授权的管理员权限权限建立的。为集群启用 GKE 控制平面授权后,Google 人员对控制平面的所有 SSH 访问都是非交互式,这意味着每个 SSH 连接都会运行您授权的单个命令。

价格

请注意以下价格注意事项:

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。
  • 启用 Cloud Logging API。

    Enable the API

  • 为贵组织启用 Access Transparency。如需了解相关说明,请参阅启用 Access Transparency

  • (可选)为您的项目启用 Access Approval,然后选择 GKE 服务。如需了解相关说明,请参阅使用 Google 管理的签名密钥查看和批准访问权限请求

  • 确保您的环境符合使用 GKE 控制平面授权功能的条件。如需选择启用这些功能,请与您的 Google Cloud 销售团队联系。

使用要求

控制平面访问日志需要 GKE 1.31.1-gke.1846000 或更高版本。

所需的角色和权限

如需获得启用日志生成以及访问和处理日志所需的权限,请让管理员向您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

启用 GKE 集群控制平面访问日志

您可以通过启用相应的日志记录组件,为 Autopilot 模式和标准模式集群启用控制平面访问日志生成功能。如需详细了解控制平面日志类型,请参阅查看 GKE 日志

控制平面访问日志支持的日志记录组件名称如下:

  • 控制平面 SSH 日志:KCP_SSHD
  • 控制平面连接日志:KCP_CONNECTION

在新集群上启用控制平面访问日志

以下示例创建了一个启用了两种控制平面访问日志类型的 Autopilot 模式集群。如需仅启用一种类型的控制平面访问日志,请从命令中省略相应的组件名称。

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --logging=SYSTEM,KCP_SSHD,KCP_CONNECTION

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • LOCATION:要创建集群的位置。

如需在使用 GKE API 创建集群时指定日志记录组件,请在 projects.locations.clusters.create 方法中,在 Cluster 资源的 LoggingConfig 对象中设置相应的值。

在现有集群上启用控制平面访问日志

如需更新现有集群的日志记录配置以启用控制平面访问日志,您必须执行以下操作:

  1. 查找集群使用的现有日志记录组件。
  2. 确定要在 gcloud CLI 的 --logging 标志中指定的相应值,以便让这些日志记录组件保持启用状态。
  3. 更新集群日志记录配置,以便现有日志记录配置中启用控制平面访问日志。

您在 gcloud container clusters update 命令中为 --logging 标志指定的值与您在描述集群时看到的值不同。

  1. 检查集群的现有日志记录配置:

    gcloud container clusters describe CLUSTER_NAME \
        --location=LOCATION \
        --flatten=loggingConfig \
        --format='csv[delimiter=",",no-heading](componentConfig.enableComponents)'
    

    输出类似于以下内容:

    SYSTEM_COMPONENTS,WORKLOADS,APISERVER,SCHEDULER,CONTROLLER_MANAGER
    
  2. 从上一步的输出中,找出与日志记录组件配置对应的 --logging 标志的 gcloud CLI 值。如需查看与特定日志记录组件对应的 gcloud CLI 值的列表,请参阅可用日志表。

  3. 使用控制平面访问日志更新日志记录配置:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --logging=SYSTEM,EXISTING_LOGS,KCP_ACCESS_LOGS
    

    替换以下内容:

    • EXISTING_LOGS:您的集群已使用的日志记录组件的英文逗号分隔列表。请务必指定与这些日志记录组件对应的 gcloud CLI 值(取自可用日志表)。
    • KCP_ACCESS_LOGS:要为集群启用的控制平面访问日志类型的逗号分隔列表,如下所示:

      • 对于控制平面 SSH 日志,请指定 KCP_SSHD
      • 对于控制平面连接日志,请指定 KCP_CONNECTION

如需在使用 GKE API 更新集群时指定日志记录组件,请在 projects.locations.clusters.update 方法中,在 ClusterUpdate 资源LoggingConfig 对象中设置现有新日志记录组件值。

用于启用控制平面访问日志的集群更新示例

假设某个集群的 gcloud container clusters describe 命令具有以下日志记录配置:

SYSTEM_COMPONENTS,WORKLOADS,APISERVER,SCHEDULER,CONTROLLER_MANAGER

以下集群更新命令会启用这两种类型的控制平面访问日志,同时保留此示例集群的现有日志配置:

gcloud container clusters update example-cluster \
    --location=us-central1 \
    --logging=SYSTEM,WORKLOAD,API_SERVER,SCHEDULER,CONTROLLER_MANAGER,KCP_SSHD,KCP_CONNECTION

将控制平面访问日志与 Access Transparency 日志进行交叉引用

如需验证集群的控制平面访问权限,请获取该集群的控制平面连接日志、控制平面 SSH 日志和 Access Transparency 日志:

  1. 在 Google Cloud Console 中,打开日志浏览器页面。

    转到 Logs Explorer

  2. 如需获取特定集群的所有日志(包括控制平面访问日志和 Access Transparency 日志),请运行以下查询:

    (logName="projects/PROJECT_ID/logs/container.googleapis.com%2Fkcp-connection"
    resource.labels.cluster_name="CLUSTER_NAME"
    jsonPayload.connection.dest_port="22")
    OR
    (logName="projects/PROJECT_ID/logs/container.googleapis.com%2Fkcp-sshd"
    resource.labels.cluster_name="CLUSTER_NAME")
    OR
    (logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Faccess_transparency"
    json_payload.accesses.methodName="GoogleInternal.SSH.Master"
    json_payload.accesses.resourceName="//container.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/clusters/CLUSTER_NAME")
    

输出应显示集群的以下所有日志类型:

  • Access Transparency 日志
  • 控制平面连接日志
  • 每个 SSH 会话的 SSH 日志

执行验证检查

主要的验证检查是,您在运行上一部分中的日志记录查询时,是否会看到任何 SSH 连接的所有日志类型。每个 Access Transparency 日志都应有一个对应的控制平面连接日志和一个或多个 SSH 日志。这些日志用于记录用户在控制平面实例中执行的操作,因此日志量应较小。

您可以选择对日志内容执行以下额外检查:

  1. 对于每个控制平面 SSH 日志,请检查 SSH 日志时间戳前 15 分钟内是否存在 Access Transparency 日志。这个时间范围可解释为,在 Access Transparency 记录初始连接后几分钟,最终 SSH 会话关闭。
  2. 对于每个控制平面连接日志,请检查控制平面连接日志时间戳之前 5 分钟的时间范围内是否存在 Access Transparency 日志。
  3. 如果您为集群使用 Access Approval,请检查每个 Access Transparency 日志是否包含相应的 accessApprovals 字段。将此字段与集群的访问权限审批请求进行交叉引用。

    如需获取项目的 Access Approval 请求,请参阅查看历史 Access Approval 请求。Access Approval 可能存在例外情况

  4. (可选)验证与 Access Transparency 日志关联的已签名访问权限批准的签名。

控制平面访问日志详情

本部分介绍了 GKE 在 Google 人员连接到您的控制平面实例时生成的控制平面访问日志的详细信息和示例。

控制平面连接日志

对于到达控制平面实例的每条新网络连接,GKE 都会添加一个控制平面连接日志。这些日志包含以下具体详细信息:

  • 来源和目的地 IP 地址和端口
  • 连接方向和协议

以下是控制平面连接日志的示例:

{
  insertId: "z1eq8wonio335a5h",
  jsonPayload: {
    instance: {
      vm_name: "gke-dee49f0d6fa34ce3a2ac-f513-d195-vm",
      zone: "us-central1-c"
    },
    cluster: {
      cluster_id: "CLUSTER_ID",
      cluster_urn: "//container.googleapis.com/projects/PROJECT_NUMBER/locations/us-central1-c/clusters/CLUSTER_NAME"
    },
    connection: {
      state: "NEW",
      src_ip: "192.0.2.100",
      src_port: 32774,
      dest_ip: "203.0.113.12",
      dest_port: 22,
      direction: "INGRESS"
      protocol: "TCP"
    },
  }
  logName: "projects/PROJECT_ID/logs/container.googleapis.com%2Fkcp-connection",
  receiveTimestamp: "2024-04-11T04:08:01.883070399Z",
  resource: {
    labels: {
      cluster_name: "CLUSTER_NAME",
      location: "us-central1-c",
      project_id: "PROJECT_ID"
    }
    type: "gke_cluster",
  }
  severity: "NOTICE",
  timestamp: "2024-04-11T04:07:59.019330Z"
}

日志条目中的以下字段与验证 Google 的操作相关:

  • cluster.cluster_urn:集群的完全限定资源标识符。此标识符的格式为 //container.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/clusters/CLUSTER_NAME,其中包含以下变量:

    • PROJECT_NUMBER:集群项目的数字项目编号。
    • LOCATION:集群的 Google Cloud 位置。
    • CLUSTER_NAME:您的集群的名称。
  • connection:有关连接尝试的详细信息。此字段包含以下信息:

    • state:连接状态。对于新连接,该值为 NEW
    • src_ip:连接来源的 IP 地址。
    • src_port:连接来源的端口号。
    • dest_ip:控制平面虚拟机的内部 IP 地址。
    • dest_port:目的地端口号。
    • direction:连接方向。值始终为 INGRESS
    • protocol:IP 协议,例如 TCP

控制平面 SSH 日志

GKE 会为与控制平面实例的 SSH 连接相关的事件添加控制平面 SSH 日志。GKE 会记录以下事件:

  • 为用户接受的 SSH 密钥
  • 会话状态从 0 更改为 1,表示用户已成功登录
  • SSH 会话已打开
  • SSH 会话已关闭
  • 会话状态从 1 更改为 0,表示用户已退出
  • SSH 会话失败

例如,以下控制平面 SSH 日志适用于正在打开的 SSH 会话:

{
  insertId: "8llczemdulwbbwpa",
  jsonPayload: {
    instance: {
      vm_name: "gke-06cb920c609941c0a5ce-6840-40e9-vm",
      zone: "us-central1-c"
    },
    cluster: {
      cluster_id: "891e6d12889747748c1ac16ffcc6cb7c0a96450b36864eb680917c119fd801d0",
      cluster_urn: "//container.googleapis.com/projects/PROJECT_NUMBER/locations/us-central1/clusters/CLUSTER_NAME",
    },
    message: "pam_unix(sshd:session): session opened for user REDACTED by (uid=0)",
  },
  logName: "projects/PROJECT_ID/logs/container.googleapis.com%2Fkcp-ssh",
  receiveTimestamp: "2024-04-09T13:21:55.231436462Z"
  resource: {
    type: "gke_cluster",
    labels: {
      cluster_name: "CLUSTER_NAME",
      location: "us-central1",
      project_id: "PROJECT_ID"
    }
  },
  severity: "NOTICE",
  timestamp: "2024-04-09T13:21:50.742246Z"
}

日志条目中的以下字段与验证 Google 的操作相关:

  • cluster.cluster_urn:集群的完全限定资源标识符。此标识符的格式为 //container.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/clusters/CLUSTER_NAME,其中包含以下变量:

    • PROJECT_NUMBER:集群项目的数字项目编号。
    • LOCATION:集群的 Google Cloud 位置。
    • CLUSTER_NAME:您的集群的名称。
  • message:SSH 连接的详细信息。

停用控制平面访问日志

  1. 如需查看集群使用的具体日志类型,请运行以下命令:

    gcloud container clusters describe CLUSTER_NAME \
        --location=LOCATION \
        --flatten=loggingConfig \
        --format='csv[delimiter=",",no-heading](componentConfig.enableComponents)'
    

    输出类似于以下内容:

    SYSTEM_COMPONENTS,WORKLOADS,API_SERVER,SCHEDULER,CONTROLLER_MANAGER,KCP_SSHD,KCP_CONNECTION
    
  2. 如需为集群停用控制平面访问日志,请运行以下命令:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --logging=SYSTEM,WORKLOAD,API_SERVER,SCHEDULER,CONTROLLER_MANAGER
    

--logging 标志中,指定上一个命令的输出中的日志记录组件。此示例命令会停用控制平面访问日志,但会让其他控制平面组件日志保持启用状态。

如需使用 GKE API 停用日志记录组件,请在 projects.locations.clusters.update 方法中,在 ClusterUpdate 资源的 LoggingConfig 对象中设置相应的值。

后续步骤