控制 SSH 登录访问权限的最佳实践


本文档介绍了控制对 Linux 虚拟机 (VM) 实例的 SSH 登录访问权限的最佳实践。

如需有效管理对虚拟机实例的 SSH 访问权限,您必须在用户需要时向其授予访问权限,并在用户不再需要时撤消该访问权限。如果您撤消访问权限的流程不可靠或未涵盖所有资源,那么即使不法分子的访问权限应已被撤消,他们也可能仍能保留访问权限。

以下部分包含有助于您确保有效撤消访问权限并防范持久性威胁的最佳实践:

本文档重点介绍特定于 Google Cloud 的实践或在 Google Cloud 上使用 SSH 时特别重要的实践。本文档未涵盖特定 SSH 客户端或服务器实现的最佳实践。

使用 OS Login 确保根据 IAM 政策持续评估访问权限

Compute Engine 公共 Linux 映像已配置为允许 SSH 公钥验证。如需授权用户的公钥并向其授予建立 SSH 会话的权限,您可以使用以下两种机制之一:

  • 基于元数据的密钥授权:作为管理员,您可以将用户的公钥上传到虚拟机或项目元数据,也可以向用户授予修改元数据的权限以允许其自行执行上传操作。

    上传到单个虚拟机元数据的公钥仅会向用户授予对该虚拟机的 root 权限;上传到项目元数据的密钥会向用户授予对项目中所有虚拟机的访问权限。

  • OS Login 密钥授权:作为用户,您可以将一个或多个公钥上传到您的 OS Login 个人资料(属于您的 Google 用户账号)。

    作为管理员,您可以通过授予 OS Login Admin User IAM 角色或 OS Login User IAM 角色,决定是向用户授予虚拟机上的 root 权限还是普通用户权限。

    gcloud CLI、Google Cloud 控制台浏览器内 SSH 客户端和 IAP 桌面会自动检测您正在使用的机制,并可以相应地上传用户的密钥。

这两种机制之间的一个关键区别在于,系统何时根据 IAM 政策评估访问权限:

  • 对于元数据密钥,系统仅在密钥上传时评估一次访问权限。

    用户的密钥与虚拟机或项目的生命周期相关联,在您移除密钥或删除虚拟机或项目之前一直有效。暂停或删除用户账号不会影响其密钥的有效性。

  • 若使用 OS Login,每次用户尝试建立 SSH 会话时都会评估访问权限。

    用户的密钥与其用户账号的生命周期相关联。如果您在 Cloud Identity 或 Google Workspace 中暂停或删除用户,则其密钥将无法再用于授予 SSH 访问权限。

使用基于元数据的密钥可能会使您面临持久性威胁:如果用户的公钥没有及时从元数据中删除,他们可能会保留比必要更长时间的 SSH 访问权限,甚至他们离开组织后仍可能保留访问权限。虽然您可以通过定期清理元数据来降低此风险,但在较大的环境中,这样做可能很困难,而且可能还不够,因为基于元数据的密钥向用户授予 root 权限

为了帮助防范此类持久性威胁,请勿允许用户使用基于元数据的密钥。请改为将您的项目配置为强制使用 OS Login。

使用组织政策强制执行一致的 OS Login 使用方式

OS Login 由 enable-oslogin 元数据键控制:在项目或实例元数据中将 enable-oslogin 设置为 TRUE 会启用 OS Login,将其设置为 FALSE 会停用 OS Login。

如需修改项目级层元数据,您需要拥有项目的 compute.projects.setCommonInstanceMetadata 权限。此权限属于 Compute Instance Admin (roles/compute.instanceAdmin.v1) 和 Compute Admin (roles/compute.admin) 角色。同样,修改实例级层元数据需要具有相应虚拟机实例的 compute.instances.setMetadata 权限。

实例级元数据的优先级高于项目级元数据。因此,在项目元数据中将 enable-oslogin 设置为 TRUE 不足以在整个项目中强制使用 OS Login:具有 Compute Instance Admin 权限或项目中虚拟机实例等效访问权限的用户,可以通过向虚拟机实例的元数据中添加 enable-oslogin=FALSE 来替换您的设置。

如需强制执行一致的 OS Login 使用方式,请勿依赖于在项目元数据中将 enable-oslogin 设置为 TRUE。相反,请应用使用组织政策为组织启用 OS Login,以便拒绝在实例或项目元数据中将 enable-oslogin 设置为 false 的任何尝试。

临时或按虚拟机授予特权角色

如果您有运行不同工作负载且由不同团队管理的虚拟机实例,则可以通过在不同的 Google Cloud 项目中部署这些虚拟机,并让这些项目使用共享网络,进而简化访问权限管理。但是,使用单独的项目并非总是可行,并且您的某些项目可能包含虚拟机实例的组合,其中不同的虚拟机实例应该只能供不同的用户访问。

每当项目包含此类不同虚拟机实例组合时,请避免在项目级层永久向用户授予 Compute Instance Admin 等角色,而是区分“只能查看”访问权限和特权访问权限:

  • 授予用户 Compute Viewer 或项目层级的等效只读角色。借助此角色,用户可以使用 Google Cloud 控制台浏览虚拟机,但无法发布 SSH 密钥或访问虚拟机。
  • 仅为单个虚拟机或仅在即时基础上授予用户 Compute OS LoginCompute Instance Admin 或其他特权角色。

在用户离开组织时暂停其用户账号

在 Cloud Identity 或 Google Workspace 中暂停或删除用户账号会自动撤消用户的 IAM 权限。由于 OS Login 在允许用户建立 SSH 会话之前会检查其 IAM 权限,因此暂停或删除用户账号也会撤消用户对使用 OS Login 的虚拟机的访问权限。

如果您已将 Cloud Identity 或 Google Workspace 配置为使用外部 IdP 进行单点登录,则员工会同时在外部 IdP 和 Cloud Identity 或 Google Workspace 中拥有用户账号。在外部 IdP 中停用或删除员工的用户账号会撤消他们建立新浏览器会话来访问 Google 服务的权限,但不会对 OS Login 产生直接影响:只要员工的 Cloud Identity 或 Google Workspace 用户账号仍然处于活跃状态,OS Login 将继续允许用户进行身份验证并建立 SSH 连接。

如需在用户离开组织时可靠地撤消 SSH 访问权限,请务必暂停或删除其 Cloud Identity 或 Google Workspace 用户账号。如果您使用外部 IdP,请将其配置为传播用户暂停事件,以便 OS Login 可以撤消访问权限。

避免授予对具有特权服务账号的虚拟机的 SSH 访问权限

如果虚拟机实例具有关联的服务账号,则虚拟机上运行的应用可以向虚拟机的元数据服务器请求短期有效凭据并使用这些凭据来充当服务账号

拥有对虚拟机的 SSH 访问权限会授予您类似的权限:与应用一样,您可以从虚拟机的元数据服务器请求短期有效的凭据,并充当关联的服务账号。

由于具有对关联服务账号的虚拟机的 SSH 访问权限后,您可以充当该服务账号,因此 OS Login 要求您对该服务账号拥有 iam.serviceAccounts.actAs 权限,并且会在您每次连接到虚拟机实例时检查此权限。这样,OS Login 有助于维护服务账号的安全性,并防止 SSH 访问权限被滥用来提升权限。

如需进一步降低与具有特权服务账号的虚拟机关联的风险,请考虑使用以下替代方案:

  • 除非工作负载需要访问 Google Cloud 资源,否则请勿将服务账号关联到虚拟机。
  • 使用单一用途的服务账号,并仅向其授予对工作负载所需资源的访问权限。
  • 要求用户请求即时访问权限,而不是永久授予用户对虚拟机和服务账号的访问权限。

限制 root 权限的使用

使用 OS Login 并向用户授予 OS Login User (roles/compute.osLogin) 角色时,您将为用户分配对虚拟机的受限用户权限。相反,如果您向用户授予 OS Login Admin User (roles/compute.osAdminLogin) 角色、使用基于元数据的密钥授权(而非 OS Login)或允许用户修改虚拟机元数据,则会隐式向用户授予对虚拟机的 root 权限。

向用户授予对虚拟机的 root 权限可能会导致持久性风险:用户可能会滥用这些权限来创建新用户账号或安装后门,以便持续访问虚拟机。

为了帮助降低这种持久性风险,请限制 root 权限的使用,在不需要 root 权限时仅授予 OS Login User (roles/compute.osLogin) 角色。

预先创建 POSIX 个人资料,以确保用户名和 UID 保持一致

每个 Linux 虚拟机都维护用户 (/etc/passwd) 和群组 (/etc/groups) 的本地数据库。当您首次使用 SSH 连接到 Linux 虚拟机时,客机环境会自动创建 Linux 用户账号并为其分配一个 UID。

使用基于元数据的密钥时,客机环境不会将 Linux 用户与您的 Google 用户账号相关联,并且可能会在您连接到的每个虚拟机上为您分配不同的 UID。如果您在不强制跨机器使用一致 UID 的环境中使用假定一致 UID 的协议(例如 NFS),则用户可能会意外地或者不法分子可能会恶意地以其他用户的身份执行远程访问。

当您使用基于元数据的密钥时,客机环境还允许您选择要使用的用户名。如果您选择的是同事之前使用的用户名,则会使用最初为同事创建的账号登录。

您可以使用 OS Login 来防止出现此类 UID 和用户名歧义:当您首次使用 OS Login 登录 Linux 虚拟机时,客机环境会根据您的 Google 用户账号的 POSIX 个人资料创建 Linux 用户。POSIX 配置文件可用作 Linux 用户的模板,并定义了以下内容:

  • 一个 Linux 用户名,在同一 Cloud Identity 或 Google Workspace 账号的所有用户中不重复
  • 在所有 Google Cloud 项目中均不重复的 UID 和 GID
  • 主目录路径
  • 其他配置,如登录 Shell

如果您在首次登录时 Google 账号没有 POSIX 个人资料,OS Login 会自动为您创建一个。

OS Login 分配的用户名和 UID 在您的 Google Cloud 环境中不重复,但可能会与您在 Google Cloud 外部使用的用户名和 UID 重叠或不一致。如果您需要 OS Login 用户名和 UID 在其他环境中保持一致,最好不要依赖自动配置文件创建。请改用 Directory API 预创建 OS Login POSIX 个人资料,并分配自定义用户名、UID 和 GID。

后续步骤