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


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

Access Transparency 日志会记录 Google 员工在访问您的内容时所采取的操作。本指南适用于希望通过与 GKE 中的其他日志记录来源相关联来额外验证 Access Transparency 日志内容和相关 Access Approval 批准内容的安全管理员。此验证完全是可选的,没有此验证也可保护控制平面。

确保熟悉以下概念:

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

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

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

在问题排查期间或出于其他合理的业务原因,Google 人员(例如站点可靠性工程师和 Cloud Customer Care 员工)可能需要对托管控制平面的 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

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

  • 确保您的环境符合使用 GKE control plane authority 功能的条件。如需选择启用这些功能,请与您的 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 地址和目的地 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 对象中设置相应值。

后续步骤