设置 OS Login 及双重身份验证

本主题介绍了设置 OS Login 及双重身份验证的基本步骤。

如果您使用 OS Login 管理对实例的访问,则可以借助双重身份验证(也称为 2FA)机制来增加一道额外的安全保障。如需详细了解使用 OS Login 的其他优势,请参阅 OS Login

如需在实例上将 OS Login 与 2FA 身份验证结合使用,请完成以下步骤:

  1. 安装或更新客机环境
  2. (可选)如果您是组织管理员,请查看管理组织中的 OS Login
  3. 为您的 Google 帐号或网域启用 2FA
  4. 在您的项目或实例上启用 2FA
  5. 向您自己、项目成员或组织成员授予必要的 IAM 角色
  6. (可选)针对您自己、项目成员或组织成员向用户帐号添加自定义 SSH 密钥。另外,当您连接到实例时,Compute Engine 会自动为您生成这些密钥。
  7. 连接实例
  8. 查看预期的登录行为

如需进一步限制虚拟机访问权限,您还可以设置受硬件支持的 SSH 密钥对。 如需了解详情,请参阅使用安全密钥进行 SSH 连接

设置 OS Login 及 2FA 后,您可以使用审核日志来监控身份验证会话。

准备工作

限制

  • Google Kubernetes Engine (GKE) 目前不支持 OS Login。启用 OS Login 后,GKE 集群节点将继续使用元数据 SSH 密钥。

  • 目前,Fedora CoreOS 映像不支持 OS Login。如需管理对使用这些映像创建的虚拟机的实例访问权限,请使用 Fedora CoreOS Ignition 系统

  • Windows Server 和 SQL Server 映像不支持 OS Login。

支持的方法或验证类型

OS Login 支持以下 2FA 方法或验证类型:

第 1 步:安装或更新客机环境

您的实例必须安装有最新版本的客机环境。 大多数公共映像均已安装最新版本。

如果您的实例运行已导入的自定义映像,请在这些虚拟机上安装客机环境

如果您没有最新的客机环境,请更新您的客机环境

第 2 步:(可选)查看如何管理组织中的 OS Login

如果您是组织管理员,则可以设置一些配置,例如在组织级层启用 OS Login。 请参阅管理组织中的 OS Login

第 3 步:为您的 Google 帐号或网域启用 2FA

您必须先对 Google 帐号或网域启用双重身份验证,然后才能为您的项目或实例启用这种验证方法。确保对包含项目或实例的网域启用 2FA,或者为拥有相应项目或实例的用户启用 2FA。

为保证安全性,您需要对所属组织中的用户帐号进行双重身份验证。启用 OS Login 双重身份验证不会阻止未配置双重身份验证的用户登录。

G Suite 管理员可以为网域启用双重身份验证,而个别 Google 用户可以在用户帐号级别启用双重身份验证。

网域

只有 G Suite 管理员才能为网域启用双重身份验证。

如需为网域启用 2FA,请参阅 G Suite 管理指南中的通过两步验证来保护您的企业

用户帐号

如果您的用户帐号并非由 G Suite 管理员管理,则可以为单个 Google 帐号配置 2FA。

如需为个别 Google 帐号配置 2FA,请参阅 Google 两步验证

第 4 步:在您的项目或实例上启用 2FA

在网域或用户帐号级层启用双重身份验证后,您可以为个别实例或项目启用 OS Login 2FA 功能。

实例或项目必须首先启用 OS Login 才能使用 OS Login 2FA。

您可以在实例创建或项目设置期间同时配置 OS Login 和 OS Login 2FA, 也可以在已启用 OS Login 的现有实例或项目上配置 OS Login 2FA。

如需将您的项目或实例配置为使用 OS Login 双重身份验证,请在项目或实例元数据中设置 enable-oslogin-2fa=TRUEenable-oslogin=TRUE

控制台

您可以使用下列其中一种方法将元数据值应用于项目或虚拟机:

  • 方法 1:创建实例时,在实例元数据中设置 enable-oslogin-2fa=TRUEenable-oslogin=TRUE

    1. 在 Google Cloud Console 中,转到“虚拟机实例”页面。

      转到“虚拟机实例”页面

    2. 点击创建实例
    3. 创建新实例页面上,为实例填写所需的属性。
    4. 元数据部分中,添加以下元数据条目:

      • enable-oslogin,值为 TRUE
      • enable-oslogin-2fa,值为 TRUE
    5. 点击创建以创建实例。

  • 方法 2:在项目级元数据中设置 enable-oslogin-2faenable-oslogin=TRUE,以将此设置应用于项目中的所有实例。

    1. 转到“元数据”页面。

      转到“元数据”页面

    2. 点击修改
    3. 元数据部分中,添加以下元数据条目:

      • enable-oslogin,值为 TRUE
      • enable-oslogin-2fa,值为 TRUE
    4. 点击保存以应用更改。

    对于未运行 CoreOS 的虚拟机,此更改将立即生效;您无需重启实例。对于 CoreOS 发行版,请重新启动(重启)实例,以使更改生效。如需重启,请先对实例执行停止操作,然后再执行启动操作。

  • 方法 3:在现有实例的元数据中设置 enable-oslogin-2faenable-oslogin=TRUE

    1. 转到“虚拟机实例”页面。

      转到“虚拟机实例”页面

    2. 点击要为其设置元数据值的实例的名称。
    3. 在实例详情页面的顶部,点击修改以修改实例设置。
    4. 自定义元数据下,添加以下元数据条目:

      • enable-oslogin,值为 TRUE
      • enable-oslogin-2fa,值为 TRUE
    5. 在实例详情页面的底部,点击保存以将更改应用于实例。

    对于除 CoreOS 之外的所有操作系统,此更改将立即生效;您无需重启实例。对于 CoreOS 发行版,请重新启动(重启)实例,以使更改生效。如需重启,请先在实例上执行停止操作,然后再执行启动操作。

gcloud

您可以使用下列其中一种方法将元数据值应用于项目或虚拟机:

  • 方法 1:创建实例时,在实例元数据中设置 enable-oslogin-2fa=TRUEenable-oslogin=TRUE

    instance-name 替换为您的实例名称。

    gcloud compute instances create instance-name \
        --metadata enable-oslogin=True,enable-oslogin-2fa=True
    
  • 方法 2:在项目级元数据中设置 enable-oslogin-2fa=TRUEenable-oslogin=TRUE,以将此项设置应用于项目中的所有实例。

    gcloud compute project-info add-metadata \
        --metadata enable-oslogin=True,enable-oslogin-2fa=True
    
  • 方法 3:在现有实例的元数据中设置 enable-oslogin-2fa=TRUEenable-oslogin=TRUE

    instance-name 替换为您的实例名称。

    gcloud compute instances add-metadata \
        --metadata enable-oslogin=True,enable-oslogin-2fa=True instance-name
    

第 5 步:为用户帐号配置 OS Login 角色

授予 OS Login IAM 角色

当您在项目中的一个或多个实例上启用 OS Login 后,这些虚拟机将只接受在项目或组织中拥有必要 IAM 角色的用户帐号发出的连接。

如需授予对这些虚拟机的 OS Login 访问权限,您需要向相关用户授予必要的角色。如需授予 OS Login 访问权限,请完成以下步骤:

  1. 授予以下实例访问角色之一。

    您可以使用 gcloud compute instances add-iam-policy-binding 命令在实例级层授予这些实例访问角色。

  2. 如果您的虚拟机实例使用一个服务帐号,则必须将每个用户配置为对该服务帐号拥有 roles/iam.serviceAccountUser 角色。如需了解如何将用户的访问权限添加到服务帐号,请参阅管理服务帐号模拟

  3. 如需允许组织外部的用户访问您的虚拟机,除了授予实例访问角色之外,还应授予 roles/compute.osLoginExternalUser 角色。 该角色必须由组织管理员在组织级层授予。如需了解详情,请参阅向组织外部的用户授予实例访问权限

向服务帐号授予 SSH 访问权限

您可以使用 OS Login 角色来允许服务帐号建立与实例的 SSH 连接。这对于以下任务非常有用:

您可以通过以下过程向您的服务帐号授予 SSH 访问权限:

  1. 创建服务帐号
  2. 向您的服务帐号授予必要的 OS Login 角色。服务帐号需要使用与用户帐号相同的角色。如需了解如何为服务帐号配置角色和权限,请参阅向服务帐号授予角色
  3. 向您的服务帐号提供应用默认凭据,以便它可以为向必要 API 发出的请求授权。可使用以下选项之一提供应用默认凭据:

向您的服务帐号授予 SSH 访问权限之后,可以对应用进行配置以创建 SSH 密钥,并建立与 VPC 网络上其他实例的 SSH 连接。如需了解服务帐号 SSH 的示例应用,请参阅使用 SSH 将应用连接到实例教程。

撤消 OS Login IAM 角色

要撤消用户对可以使用操作系统登录的实例的访问权限,请从该用户帐号中移除用户角色。如需了解如何移除用户的 IAM 角色,请参阅授予、更改和撤消对资源的访问权限

撤消某用户的访问权限后,该用户仍然拥有与其帐号关联的公共 SSH 密钥,但这些密钥不再会对虚拟机实例起作用。

第 6 步:(可选)将 SSH 密钥添加到用户帐号

如果您想使用第三方工具连接到虚拟机,则需要将 SSH 密钥添加到您的用户帐号。如果您使用其他方式(例如 gcloud 命令行工具或通过浏览器进行 SSH 连接)连接到您的实例,则可以跳过此步骤,因为 Compute Engine 会自动为您生成这些密钥。

您可以将 SSH 公钥与以下用户帐号类型相关联:

您可以使用 gcloud 命令行工具OS Login API 将 SSH 密钥添加到自己的帐号中。或者,如果您是组织的网域管理员,则可以使用 Directory API 将 SSH 密钥添加到组织中的用户帐号。

gcloud

gcloud compute os-login 命令仅适用于 Cloud SDK 版本 184 及更高版本。

使用 gcloud 命令行工具将 SSH 公钥与帐号相关联。

gcloud compute os-login ssh-keys add \
    --key-file key-file-path \
    --ttl expire-time

替换以下内容:

  • key-file-path:指向本地工作站上 SSH 公钥的路径。确保 SSH 公钥格式正确。如果您在 Linux 系统上使用 PuTTYgen 来生成公钥,则必须使用 public-openssh 格式。
  • expire-time:一个可选标志,用于设置 SSH 公钥的到期时间。例如,您可以指定 30m,则 SSH 密钥将在 30 分钟后过期。此标志使用下列单位:
    • s 表示秒数
    • m 表示分钟数
    • h 表示小时数
    • d 表示天数。将值设为 0 以指示没有到期时间。

OS Login API

使用 OS Login API 以将 SSH 公钥与帐号相关联:

POST https://oslogin.googleapis.com/v1/users/account-email:importSshPublicKey

{
 "key": "ssh-key",
 "expirationTimeUsec": "expiration-timestamp"
}

替换以下内容:

  • account-email:表示您的托管用户帐号的电子邮件地址。
  • ssh-key:您想要应用于帐号的公钥。确保 SSH 公钥格式正确。如果您在 Linux 系统上使用 PuTTYgen 来生成公钥,则必须使用 public-openssh 格式。
  • expiration-timestamp:密钥的到期时间(以微秒为单位,从新纪元开始算)。

Directory API

如果您是组织的网域管理员,则可以使用 Directory API 参考将 SSH 密钥添加到组织中其他用户的帐号。例如,使用一个或多个 SSH sshPublicKeys 条目创建对 directory.users.update 方法发出的 PUT 请求:

PUT https://www.googleapis.com/admin/directory/v1/users/user-id-key

{
 "sshPublicKeys": [
  {
   "key": "ssh-key",
   "expirationTimeUsec": "expiration-timestamp"
  },
  {
   "key": "ssh-key",
   "expirationTimeUsec": "expiration-timestamp"
  }
 ]
}

替换以下内容:

  • user-id-key:用户的不可变 ID。
  • ssh-key:您要应用于帐号的公钥。确保 SSH 公钥格式正确。如果您在 Linux 系统上使用 PuTTYgen 来生成公钥,则必须使用 public-openssh 格式。
  • expiration-timestamp:密钥的到期时间(以微秒为单位,从 Epoch 起算)。

如需从帐号中移除所有密钥,请指定 "sshPublicKeys": null 作为正文,并将 user-id-key 替换为用户的不可变 ID:

PUT https://www.googleapis.com/admin/directory/v1/users/user-id-key

{
  "sshPublicKeys": null
}

将密钥添加到帐号后,您可以使用第三方工具以及与帐号关联的用户名连接到实例。 请注意,您的组织管理员可以更改此用户名

您可以通过运行 gcloud compute os-login describe-profile 命令找到帐号的当前用户名:

例如,输出结果可能类似于以下内容:

name: '314159265358979323846'
posixAccounts:
- gid: '27182818'
  homeDirectory: /home/user_example_com
  ⋮
  uid: '27182818'
  username: user_example_com
⋮

第 7 步:连接到实例

您可以通过以下 3 种主要方式连接到虚拟机:

如果您连接到虚拟机的方式是使用 gcloud 命令行工具或通过浏览器进行 SSH 连接,Compute Engine 会自动生成 SSH 密钥并将其与您的用户帐号关联。

如果您使用第三方工具连接到实例,则需要将公钥添加到您的用户帐号。 该虚拟机从您的用户帐号获取您的公钥,允许您在提供了正确的用户名和匹配的 SSH 私钥后连接到该实例。

当您连接到该实例时,系统会根据您选择的 2FA 方法或验证类型向您发送一条消息。

  • 如果选择的是 Google 身份验证器,您将看到以下消息:

    "Enter your one-time password:"

  • 如果选择的是短信或电话验证,您将看到以下消息:

    "A security code has been sent to your phone. Enter code to continue:"

  • 如果选择的是电话提示,您将看到以下消息:

    A login prompt has been sent to your enrolled device:"

    使用电话提示方法时,请接受手机或平板电脑上的提示以继续操作。使用其他方法时,请输入您的安全代码或动态密码。

第 8 步:预期的登录行为

  • 在某些使用 OS Login 的实例上,您可能会在建立连接后收到以下错误消息:

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

    忽略此错误消息。此错误不会影响您的实例。

  • 如果 G Suite 管理员未设置用户名,则 OS Login 会通过组合用户的 Google 个人资料所关联电子邮件中的用户名和域来生成默认的 Linux 用户名。此命名惯例可确保唯一性。例如,如果与 Google 个人资料关联的用户电子邮件地址是 user@example.com,则其生成的用户名为 user_example_com

    G Suite 组织可以选择更改默认设置,为新生成的用户名移除域名后缀。例如,如果与 Google 个人资料关联的用户电子邮件地址是 user@example.com,则其生成的用户名为 user。如需了解详情,请参阅管理 OS Login API

    如果用户来自另一个 G Suite 组织,则生成的用户名会带有“ext_”前缀。例如,如果 user@example.com 正在访问其他组织中的虚拟机,则其生成的用户名为 ext_user_example_com

  • 使用 gcloud compute ssh 命令登录实例时,对于属于 example.com 域的用户 user,登录消息的格式如下:

    Using OS Login user user_example_com instead of default user user

    此消息确认用户是使用 OS Login 个人资料登录的。

查看 OS Login 2FA 审核日志

Compute Engine 提供审核日志以跟踪双重身份验证请求。 双重身份验证有两种请求类型:

  • StartSession。启动新的身份验证会话。在 StartSession 调用中,客户端向服务器声明其功能并获取有关第一个验证的信息。StartSession 调用会返回以下内容:

    • 会话 ID。此会话 ID 会传递给所有后续 ContinueSession 调用。
    • 有关此新身份验证会话中所用验证方法或 2FA 方法的信息。
  • ContinueSession。继续现有身份验证会话。使用所提供的会话 ID,ContinueSession API 可以执行以下两项操作之一:

    • 接收对于验证或相应身份方法的响应,随后执行身份验证、拒绝验证请求或要求用户提供额外的验证信息。
    • 切换到与服务器最初在上一轮 API 调用中提出的验证类型不同的验证。如果客户端选择使用不同的验证类型(例如,选择 Google 身份验证器而非电话提示),则客户端可以使用所需类型的 request.challengeId,在对服务器的调用中请求不同的验证类型。

如需查看日志,您必须具有日志查看器的权限,或者具有项目的 Viewer 或 Editor 身份。

  1. 在 Cloud Console 中,转到“日志”页面。

    转到“日志”页面

  2. 展开下拉菜单并选择 Audited Resource
  3. 在搜索栏中,输入 oslogin.googleapis.com,然后按 Enter 键。
  4. 系统将显示描述双重身份验证请求的审核日志列表。 展开以下任一条目可以了解详情:

    用于双重身份验证的审核日志。

对于任何审核日志,您可以执行以下操作:

  1. 展开 protoPayload 属性。

    用于双重身份验证的审核日志指标。

  2. 查找 methodName 以查看此日志适用的活动(StartSessionContinueSession 请求)。例如,如果此日志跟踪的是 StartSession 请求,则方法名称将显示为 "google.cloud.oslogin.OsLoginService.v1.StartSession"。同样,ContinueSession 日志会显示为 "google.cloud.oslogin.OsLoginService.v1.ContinueSession"。每项启动会话和继续会话请求都会记录一个审核日志条目。

不同的日志类型有不同的审核日志属性。例如,与 StartSession 相关的审核日志具有特定于启动会话的属性,而 ContinueSession 的审核日志具有其自己的属性集。某些审核日志属性同时适用于这两种日志类型。

所有双重身份验证审核日志

属性
serviceName oslogin.googleapis.com
resourceName 包含项目编号的字符串。此项目编号指示审核日志所属的登录请求。例如 projects/myproject12345
severity 日志消息的严重级别。例如 INFOWARNING
request.email API 调用正在执行身份验证的用户的电子邮件地址。
request.numericProjectId Google Cloud 项目的编号。
response.@type type.googleapis.com/google.cloud.oslogin.OsLoginService.v1.StartOrContinueSessionResponse
response.sessionId 唯一标识会话的 ID 字符串。此会话 ID 将传递给序列中的下一项 API 调用。
response.authenticationStatus 会话状态。例如 AuthenticatedChallenge requiredChallenge pending
response.challenges 可供您为通过此轮身份验证而尝试的一组验证。其中最多有一项验证已开始,并且状态为 READY。其他验证则作为可选项提供,用户可以指定这些可选项来取代系统推荐的主要验证方案。

StartSession 审核日志

属性
methodName google.cloud.oslogin.OsLoginService.v1.StartSession
request.@type type.googleapis.com/google.cloud.oslogin.OsLoginService.v1.StartSessionRequest
request.supportedChallengeTypes 可供您从中选择的验证类型或 2FA 方法列表。

ContinueSession 审核日志

属性
methodName google.cloud.oslogin.OsLoginService.v1.ContinueSession
request.sessionId 唯一地识别上一次会话的 ID 字符串。此会话 ID 是由序列中的上一项 API 调用传递而来的。
request.@type type.googleapis.com/google.cloud.oslogin.OsLoginService.v1.ContinueSessionRequest
request.challengeId 标识要启动或执行哪项验证的 ID 字符串。此 ID 必须属于 response.challenges 调用在上一次 API 响应中返回的验证类型。
request.action 要执行的操作。

后续步骤