OS Login 问题排查


本文档介绍如何使用元数据服务器排查 OS Login 问题。如需了解如何设置 OS Login 或查看分步说明,请参阅设置 OS Login

您可以从虚拟机实例中查询元数据服务器。 如需了解详情,请参阅存储和检索实例元数据

准备工作

  • 设置身份验证(如果尚未设置)。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以按如下方式向 Compute Engine 进行身份验证。

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. REST

      如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证

常见的错误消息

以下是使用 OS Login 时可能遇到的常见错误示例。

找不到群组名称

在某些使用操作系统登录的虚拟机上,您可能会在建立连接后收到以下错误消息:

/usr/bin/id: cannot find name for group ID 123456789

忽略此错误消息。此错误不会影响您的虚拟机。

获取群组失败

创建虚拟机时,您可能会看到如下所示的日志:

Dec 10 22:31:05 instance-1 google_oslogin_nss_cache[381]: oslogin_cache_refresh[381]: Refreshing group entry cache
Dec 10 22:31:05 instance-1 google_oslogin_nss_cache[381]: oslogin_cache_refresh[381]: Failure getting groups, quitting

这些日志表明您的组织未配置 OS Login Linux 群组。请忽略这些消息。

Failed precondition

使用 SSH 连接到虚拟机时,您可能会看到如下所示的错误:

ERROR: (gcloud.compute.ssh) FAILED_PRECONDITION: The specified username or UID is not unique within given system ID.

如果 OS Login 尝试生成一个在组织中已存在的用户名,就会发生此错误。当用户账号被删除,并且不久后又创建了使用相同电子邮件地址的新用户时,这种情况很常见。删除用户账号后,系统最多需要 48 小时才能移除用户的 POSIX 信息。

如需解决此问题,请执行以下某项操作:

参数无效

使用 SSH 连接到虚拟机或使用 SCP 传输文件时,您可能会看到如下所示的错误:

ERROR: (gcloud.compute.ssh) INVALID_ARGUMENT: Login profile size exceeds 32 KiB. Delete profile values to make additional space.
ERROR: (gcloud.compute.scp) INVALID_ARGUMENT: Login profile size exceeds 32 KiB. Delete profile values to make additional space.

如需解决这些错误,请执行以下操作:

  1. 运行 gcloud compute os-login describe-profile 命令查看您的 OS Login 配置文件:

    gcloud compute os-login describe-profile
    

    输出类似于以下内容:

    name: '00000000000000'
    posixAccounts:
    ...
    sshPublicKeys:
     ...:
       fingerprint: ...
       key: |
         ssh-rsa AAAAB3NzaC1yc2...
       name: ...
     ...
    
  2. 查看输出内容,找出所有未使用的 SSH 密钥。

  3. 使用 gcloud compute os-login ssh-keys remove 命令从输出中移除所有未使用的密钥:

    gcloud compute os-login ssh-keys remove --key=KEY
    

    KEY 替换为密钥的指纹或密钥字符串。

为防止将来出现此问题,请为 SSH 密钥添加过期时间。过期的密钥将在过期后 48 小时或在向配置文件添加新密钥时,自动从您的登录配置文件中移除。

HTTP 响应代码:503

尝试使用 SSH 连接到虚拟机时,您可能会看到以下错误:

Failed to validate organization user USERNAME has login permission, got HTTP response code: 503

此问题是由每个虚拟机实例每秒 100 次查询的元数据服务器速率限制引起的。此限制无法调整。如需解决此问题,请等待几秒钟,然后重试连接。

为了防止日后出现此问题,请尝试执行以下操作:

  • 在应用代码中实现重试机制。如需了解详情,请参阅:
  • 重复使用现有的 SSH 连接。
  • 批量发送命令,以减少 SSH 连接和 OS Login 元数据查询。

默认 OS Login 元数据条目

Compute Engine 定义了一组提供 OS Login 信息的默认元数据条目。默认元数据始终由服务器定义和设置。默认元数据键区分大小写。

下表介绍了您可以查询的条目。

相对于 http://metadata.google.internal/computeMetadata/v1/
元数据条目 说明
project/attributes/enable-oslogin 检查当前 Google Cloud 项目是否已启用 OS Login。
instance/attributes/enable-oslogin 检查当前虚拟机是否已启用 OS Login。
oslogin/users/ 检索 OS Login 用户的个人资料信息。 您可以传递 usernameuidpagesizepagetoken 等查询参数。
oslogin/authorize/

检索 OS Login 用户的登录或管理级别权限设置。

要检查权限,您必须指定 policy 查询参数。 政策参数的值必须设置为 login(用于检查登录权限)或 adminLogin(用于检查 sudo 访问权限)。

检查是否已配置 OS Login

使用 Google Cloud 控制台或 Google Cloud CLI 查询元数据以确定是否已启用 OS Login。在项目或实例元数据中将 enable-oslogin 元数据键设置为 TRUE 时,系统会启用 OS Login。如果同时设置了实例元数据和项目元数据,则实例元数据中设置的值优先。

查看 OS Login 用户

要查看多个用户的个人资料信息,您需要指定 pagesizepagetoken 参数。将 pagesizepagetoken 替换为所需的数值。

curl "http://metadata.google.internal/computeMetadata/v1/oslogin/users?pagesize=PAGE_SIZE&
pagetoken=PAGE_TOKEN" -H "Metadata-Flavor: Google"

例如,要将 pagesize 设置为 1,将 pagetoken 设置为 0,请运行以下命令:

curl "http://metadata.google.internal/computeMetadata/v1/oslogin/users?pagesize=1&pagetoken=0" -H "Metadata-Flavor: Google"

在大多数发行版上,您还可以运行 Unix 命令 getent passwd 来检索组织用户的密码条目。

查看特定的 OS Login 用户

要查看虚拟机上特定用户的个人资料信息,请运行以下命令:

curl "http://metadata.google.internal/computeMetadata/v1/oslogin/users?username=USERNAME" -H "Metadata-Flavor: Google"

USERNAME 替换为您要查询的用户的用户名。

例如,您可以执行请求来查找用户 user_example_com。以下命令和输出增加了格式,以提高可读性。

curl "http://metadata.google.internal/computeMetadata/v1/oslogin/users?username=user_example_com" -H "Metadata-Flavor: Google"

输出类似于以下内容:

{
    "loginProfiles": [{
        "name": "12345678912345",
        "posixAccounts": [{
            "primary": true,
            "username": "user_example_com",
            "uid": "123451",
            "gid": "123451",
            "homeDirectory": "/home/user_example_com",
            "operatingSystemType": "LINUX"
        }],
        "sshPublicKeys": {
            "204c4b4fb...": {
                "key": "ssh-rsa AAAAB3Nz...",
                "fingerprint": "204c4b4fb..."
            }
        }
    }]
}

在大多数发行版上,您还可以运行 getent passwd usernamegetent passwd uid 等 Unix 命令来检索个人资料信息。

要检索用户的 SSH 密钥,您还可以运行 /usr/bin/google_authorized_keys USERNAME。 如果未返回密钥,则说明用户可能没有登录虚拟机所需的权限。

检查登录权限

要查看登录权限和管理级别权限,您必须提供 policy=login&email=LOGIN_NAME 查询参数。

  1. 查询用户个人资料以获取 name 字段的值:

    curl "http://metadata.google.internal/computeMetadata/v1/oslogin/users?username=user_example_com" -H "Metadata-Flavor: Google"
  2. 在输出中,记下 name

  3. 使用 name 的值运行以下 login 命令:

    curl "http://metadata.google.internal/computeMetadata/v1/oslogin/authorize?policy=login&email=LOGIN_NAME" -H "Metadata-Flavor: Google"
    

例如,您可以查询在上一部分查看的用户 user_example_com 的登录权限:

curl "http://metadata.google.internal/computeMetadata/v1/oslogin/authorize?policy=login&email=12345678912345" -H "Metadata-Flavor: Google"

命令输出表明用户有权登录虚拟机:

{"success":true}

检查您的虚拟机是否有服务账号

您可以查询元数据服务器以查找与您的虚拟机关联的服务账号。在虚拟机上,运行以下命令:

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" -H "Metadata-Flavor: Google"

输出类似于以下内容:

12345-sa@developer.gserviceaccount.com/
default/

如果未找到服务账号,则输出为空。

使用 gcpdiag 调试 OS Login 问题

gcpdiag 是一种开源工具,不是由官方提供支持的 Google Cloud 产品。您可以使用 gcpdiag 工具来帮助识别和修复 Google Cloud 项目问题。如需了解详情,请参阅 GitHub 上的 gcpdiag 项目

此 gcpdiag runbook 用于调查 Google Cloud 中 Windows 和 Linux 虚拟机上出现 SSH 访问权限问题的潜在原因。它侧重于:
  • 虚拟机健康状况:检查虚拟机是否正在运行以及是否有足够的资源(CPU、内存、磁盘)。
  • 权限:确保您拥有正确的 IAM 权限来配置 SSH 密钥。
  • 虚拟机设置:验证 SSH 密钥和其他元数据是否已正确配置。
  • 网络规则:查看防火墙规则,确认允许 SSH 流量。
  • 客户操作系统:查找可能阻止 SSH 的内部操作系统问题。

Google Cloud 控制台

  1. 完成然后复制以下命令。
  2. gcpdiag runbook gce/ssh --project=PROJECT_ID \
        --parameter name=VM_NAME \
        --parameter zone=ZONE \
        --parameter principal=PRINCIPAL \
        --parameter tunnel_through_iap=IAP_ENABLED
  3. 打开 Google Cloud 控制台并激活 Cloud Shell。
  4. 打开 Cloud 控制台
  5. 粘贴复制的命令。
  6. 运行 gcpdiag 命令以下载 gcpdiag Docker 映像,然后执行诊断检查。如果适用,请按照输出说明修复失败的检查。

Docker

您可以使用封装容器运行 gcpdiag,以在 Docker 容器中启动 gcpdiag。必须安装 Docker 或 Podman

  1. 在本地工作站上复制并运行以下命令。
    curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
  2. 执行 gcpdiag 命令:
    ./gcpdiag runbook gce/ssh --project=PROJECT_ID \
        --parameter name=VM_NAME \
        --parameter zone=ZONE \
        --parameter principal=PRINCIPAL \
        --parameter tunnel_through_iap=IAP_ENABLED

查看此 Runbook 的可用参数

替换以下内容:

  • PROJECT_ID:资源所在项目的 ID
  • VM_NAME:项目中的目标虚拟机的名称。
  • ZONE:目标虚拟机所在的可用区。
  • PRINCIPAL:发起 SSH 连接的用户或服务账号主账号。对于基于密钥的身份验证,请使用通过 Cloud Shell 命令行工具进行身份验证的用户或登录 Google Cloud 控制台的用户。对于服务账号模拟,它应该是服务账号的电子邮件地址。
  • IAP_ENABLED:一个布尔值(true 或 false),指示是否使用 Identity-Aware Proxy 建立 SSH 连接。默认值:true

实用标志:

  • --projectPROJECT_ID
  • --universe-domain:如果适用,则为托管资源的可信合作伙伴主权云网域
  • --parameter-p:Runbook 参数

如需查看所有 gcpdiag 工具标志的列表和说明,请参阅 gcpdiag 使用说明

后续步骤