介绍 自 2015 年以来,优步一直在运营基于 Apache Hadoop ®的数据分析平台。随着 2016 年采用率呈指数级增长,我们决定使用Kerberos身份验证来保护我们的平台。从那时起,Kerberos 已成为我们安全基础架构的重要组成部分,不仅支持 Uber 的 Hadoop 生态系统,还支持其他被认为对我们的技术堆栈至关重要的服务。 Uber 在数千台机器上部署了庞大而多样化的技术堆栈,并存储了超过 300 PB 的分析数据。使用 Kerberos 身份验证的系统包括 YARN、HDFS、Apache Hive ™、Apache Kafka®、Apache Zookeeper ™、Presto®、Apache Spark ™、Apache Flink®和 Apache Pinot ™,等等。除了开源系统,许多内部开发的平台和服务也使用 Kerberos 进行身份验证。所有这些服务都需要安全地相互通信,并为其所有用户客户端提供安全访问。 在这篇博文中,我们将分享一些关键挑战和解决方案,这些挑战和解决方案使我们能够在 Uber 扩大采用 Kerberos 进行身份验证。 Kerberos 在我们开始描述我们在 Uber 采取了哪些步骤来扩展 Kerberos 之前,让我们先从高层次的角度来了解 Kerberos。 Kerberos 是一种计算机网络身份验证协议。它以希腊神话中哈迪斯的三头看门狗刻耳柏洛斯( Cerberus)命名。该协议于 1980 年代初在麻省理工学院首次开发,目前的版本发布 (v5) 可追溯到 1993 年。尽管它是一个相当古老的协议,但其优势使 Kerberos 能够满足分布式系统的要求,而无需对原始设计进行任何重大更改。 图 1:Kerberos 协议 正如Kerberos名称所暗示的那样,该协议有 3 个核心参与者: 密钥分发中心 (KDC): Kerberos 服务器,用于存储主体(用户或服务)及其凭据,并允许他们相互证明自己的身份 客户端: 由需要访问某些资源的用户或服务运行的进程 资源服务器: 为网络客户端提供资源的服务器 该协议通过在参与者之间交换票证来工作: 每个 Kerberos 网络服务通常在启动期间使用 KDC 进行身份验证,并在运行时保持身份验证票证有效 如果客户端需要访问一些受 Kerberos 保护的网络资源,它首先使用 KDC 登录并获得一个可过期的身份验证票证 (TGT—ticket-granting-ticket)。TGT 将允许客户端在没有客户端凭据的情况下请求访问 任何 资源(SSO——稍后会详细介绍) 使用此票证,客户端需要向 KDC 请求特定资源服务器的服务票证 现在,客户端可以通过提供服务器票证向资源服务器进行身份验证 一件值得一提的重要事情是,Kerberos 允许其客户端使用两种方法之一进行身份验证:使用明确的密码或使用名为" keytab "的安全密钥文件。 Kerberos 具有一些重要的优势,使其能够被各种系统广泛采用,这就是我们在 Uber 使用它的原因: Hadoop 生态系统(在 Uber 大量使用)原生支持基于 Kerberos 的身份验证 凭据永远不会在未加密的情况下通过网络发送 票证的生命周期有限,因此在票证过期后,客户端必须使用 KDC 进行身份验证才能获得新票证 它是一种单点登录 (SSO) 协议,这意味着客户端需要向 KDC 进行一次身份验证,以便能够在票证有效时访问任何受 Kerberos 保护的资源 所有客户端和服务器/服务都相互认证 票据可以补充主机信息,允许一台受感染的主机不影响网络中其他主机的安全 我们可以通过在它们之间设置信任关系来构建独立的 Kerberos 领域(域)的层次结构 该系统经过验证、可靠,并且在确保基础设施安全方面拥有良好的记录 Hadoop 选择 Kerberos 作为其主要身份验证协议的一些具体原因可以在这篇论文中找到。有关 Kerberos 的更多详细信息,请参阅RFC 4120或维基百科。 标准化账户类型 身份验证从身份开始。随着优步经历高速增长阶段,每天使用数据平台的员工和团队数量迅速增长。如果没有适当的流程,我们就很难指导不同部门和工作职能(运营、数据科学家、分析师、工程师)的用户以正确的方式利用适当的账户来完成他们的任务。 身份验证过程涉及两方:客户端和服务器。用户始终是客户端,而服务可以代表双方。我们有许多不同的用例和帐户类型,它需要一些标准化以便于增长,因此我们首先建立以下命名法来向我们的用户传达最佳实践: 帐户类型 描述 用户帐号 对于人员(员工)访问,临时数据探索 示例:employee-account@uber.com 服务帐号 用于运行日常管道,即使原始管道作者离开公司,团队也会维护这些管道。 服务帐户由同名的 Linux 组支持,因此项目成员可以添加到该组并获得对服务帐户写入的数据的访问权限。 示例:uber_eats@DATA.UBER.COM 系统帐号 对于构成数据基础架构堆栈的系统。与服务帐户不同,此处不添加任何组成员以避免任何安全风险。 示例:hdfs@DATA.UBER.COM 服务主机帐户 这使我们能够将主体和 keytab 凭证的范围限定为特定的 {service, host} 组合。在 keytab 被破坏的情况下,我们只需要轮换特定的 {service, host} keytab,而不是在多个主机之间轮换服务 keytab(与服务帐户相反)。这通常由跨大量主机部署的服务使用。 示例:hdfs/us-west-123.internal@DATA.UBER.COM 除了在 wiki 中定义帐户和描述它们之外,我们还构建了自助服务功能来创建服务帐户并将它们用于访问控制策略。在加入新数据集或 ETL 作业时,如果服务没有帐户或者它是一项新服务,则拥有团队将被重定向到自助帐户创建过程。新创建的帐户可在 24 小时内使用。 图 2:服务帐户创建过程 我们还确保自动生成相应的密钥表并将其分发给具有适当权限的边缘主机。 帐户传播 图 3:将帐户传播到生产基础设施 Uber 依靠 Microsoft Active Directory("Uber AD")进行用户和群组管理。Uber AD 是人员账户和团体成员信息的真实来源。正如我们前面提到的,服务和系统帐户在 AD 中表示为具有特定属性的组,以将它们与常规用户组区分开来。 一个公司通常有多个 Kerberos 领域来分离关注点。Data org 作为 Uber 内部的一个内部组织,决定采用专门的 Kerberos 设置 ——MIT Kerberos 实现,由OpenLDAP ®数据库支持。数据 Kerberos 存储主机、服务和系统帐户的主体。Uber 的人员帐户 (employee@uber.com) 可以通过 Kerberos 进行身份验证,以访问通过与 Uber AD(不同领域)的单向信任促进的数据资源。 我们的数据服务可以部署在 Docker 容器中,也可以作为裸机主机上的常规操作系统进程。为了减少 Active Directory 上的负载,我们实施了用户和组同步过程,以将用户及其组成员资格传播到整个数据堆栈。 这奠定了基础设置,使员工和服务能够更好地利用我们的身份验证和授权基础设施。 Kerberos 架构 目前,Kerberos 基础设施总共为超过 100,000 个主体提供身份验证。为了支持这种规模的请求量并保持低延迟,我们在所有区域部署了多个 Kerberos 服务器实例。 图 4:Kerberos 架构 虽然 Kerberos 服务器可以部署在各种配置中,但我们选择了多提供商设置以实现高可用性:所有提供商节点独立运行,包含相同的信息,并且可以轻松地相互交换。 每个提供者与自身以及多个 KDC 消费者节点形成一个独立的集群。来自提供者的所有数据都被复制到其集群的消费者节点。Kerberos 支持多种方法来设置其节点之间的复制:它可以通过 KDC 或后端数据库来完成。我们使用 OpenLDAP 作为 KDC 的数据库,因此所有 Kerberos 复制都依赖于 OpenLDAP。要复制数据,只有消费者节点需要知道提供者节点,这让我们可以轻松地从集群中添加或删除消费者节点。在此设置中,将消费者节点提升为提供者也是一个相对简单快捷的操作。 为了避免提供者节点之间的写入冲突,我们在任何时间点都只以读写模式运行单个提供者,而所有其他提供者节点都是只读的。 每个集群都在相同的基于区域的 DNS 名称(kdc.region-1.data.uber、kdc.region-2.data.uber 等)下将其消费者节点添加为 DNS A 记录,因此所有客户端都进行身份验证使用简短且众所周知的 DNS 名称而不是特定主机名的 Kerberos。同时,提供者节点对客户端是隐藏的,只能在 Kerberos 基础设施服务中访问。 具有多提供商设置和数十个消费者节点的区域集群使我们能够扩展 Kerberos 以满足请求量并提高采用率。在下一节中,我们将描述围绕此 Kerberos 部署的支持基础结构。 密钥表分发管道概述 当 Kerberos 在 2016 年建立时,团队必须承担的一项新操作任务是注册新主体并将密钥表(具有主体凭据的文件)安全地分发给请求团队。我们最初的方法涉及手动登录到 Kerberos kadmin主机以注册帐户、生成密钥表并将它们 scp 到与团队预先确定的共享位置。这种方法有多个问题: 生成新主体和密钥表的临时请求的数量为已经因生产事件和基础设施可扩展性问题不堪重负的团队带来了更多工作 主体和密钥表的手动配置阻碍了实现服务的完全自动化部署的愿景 凭证在没有任何严格和定义的过程的情况下从手传递到手时的安全问题 与 kadmind 的每次手动交互都会带来意外删除或损坏生产数据的风险 在之前的博客中,我们描述了我们如何对整个 Hadoop 基础设施堆栈进行容器化,使我们能够扩展和操作 Hadoop。作为全公司范围内实现完全自动化基础设施的更大努力的一部分,我们使用我们内部称为 Keytab Distribution Pipeline 的系统自动生成和分发 keytabs,该系统实质上跨数据服务分发 keytabs 并自动执行。 Keytab 分发管道 (KDP) 主要负责以下内容: 观察元数据变化的预定义源,然后将其用作创建/删除 Kerberos 主体的输入 从上面创建和删除与主体对应的密钥表,并确保它们在安全库中可用 提供和维护可以从安全库中安全地获取密钥表的客户端 我们投入大量资金来简化任何新服务的 KDP 入职流程——服务所有者团队需要做的工作包括定义配置(约 3 行)和在服务代码库中添加客户端调用(另外约 3 行)。轻松加入 KDP 和自动管理 keytabs 极大地促进了 Kerberos 的日益普及。 图 5:Keytab 分发管道 密钥表有两大类用例: 使用服务或系统帐户运行自动化管道或作业的服务 在向服务集群添加节点期间使用服务主机主体(例如 hdfs/us-west-123)进行身份验证的大型队列服务(HDFS、YARN 等) 专注于上述用例的入职便利性,我们确定了 KDP 自动化并将其与 3 个系统集成: Active Directory (AD):服务和系统帐户的真实来源 有关每项服务及其部署主机的信息 来源 Odin:Uber 用于有状态服务的内部编排系统 b。Peloton:Uber 的无状态服务内部编排系统 Kerberos 桥 图 6:Kerberos 桥 管道中的第一个组件是 Kerberos-Bridge 服务(Kerberos 基础设施和外部元数据提供者之间的"桥梁")。它定期从元数据提供者处获取服务和主机元数据,并基于它更新内部 Git 存储库中相应的"keytab 条目"。密钥表条目还不是实际的 Kerberos 密钥表——它们是密钥表的元数据,其中包含主体名称、为密钥表设置正确权限的所有者信息,以及一些其他支持信息。选择 Git 作为内部存储库允许我们使用其内置功能,例如通过 Git 历史进行审计、使用 Git 还原进行回滚、访问控制以及在需要对条目进行手动更改时进行同行评审。 密钥表管理器 图 7:Keytab-Manager 现在我们已经到达了管道的核心部分——Kerberos 提供者主机(提供者主机对客户端是隐藏的,只有 KDP 可以与它们交互)。我们在主机上运行以下进程:KDC(用于身份验证,与此管道无关)、KDC Admin(kadmin — 管理 Kerberos 主体和密钥表的客户端)、OpenLDAP 和我们的 Uber 内部 Keytab-Manager 服务。 Keytab-Manager 是开源 KDC/OpenLDAP 系统和我们内部 Uber 服务之间的粘合剂。与 Kerberos-Bridge 类似,它监视 Keytab 条目存储库的任何新更改。一旦 Keytab-Manager 看到存储库中的更改(例如,添加了新的密钥表条目"hdfs/us-west-123@DATA.UBER.COM"(意味着 HDFS 服务部署在新主机 us-west-123 上) ), 它通过调用本地 kadmin 进程创建一个新的同名 Kerberos 主体,该进程由 OpenLDAP 数据库支持。创建主体后,服务生成相应的密钥表文件 (hdfs_us-west-123.keytab)。 keytab 文件以适当的粒度权限安全地存储在 Secrets Store 中,稍后在检索 keytab 时使用。Keytab-Manager 服务还监控 Secrets Store 并使用任何新的或删除的 keytab 文件对其进行更新,并根据相应 keytab 条目中的所有者设置其权限。 密钥表获取器 图 8:Keytab-Fetcher 我们管道中的最后一个组件是 Keytab-Fetcher,这是一个库,任何服务都可以将其集成到其代码库中并从 Secrets Store 中获取其密钥表。编排系统代理(部署在整个 Uber 车队上)负责利用 Keytab-Fetcher 下载密钥表并将其提供给服务容器。 整个 KDP 由SPIRE保护,它允许服务在更新和从秘密存储中检索秘密之前进行身份验证。然后,Secrets Store 将只允许服务访问 keytabs,前提是它们被允许这样做。 图 9:一周内生成的 Keytab KDP 已经在 Uber 投入生产超过 2 年。它每周生成和分发超过 1000 个密钥表。高度自动化使团队无需参与注册委托人和分发密钥表。自动化系统还使我们能够根据需要轮换密钥表。我们花了最少的时间监控 KDP 仪表板,以确保整个自动化系统按预期工作。 结语 我们为 Kerberos 选择的架构和我们使用 Keytab 分发管道构建的自动化提高了开发人员的工作效率、数据堆栈的安全性、可靠性(因为现在一切都是自动化的),并使我们能够轻松扩展数据服务的身份验证。 作者:Alexander Gulko,Mithun (Matt) Mathew 出处:https://www.uber.com/en-US/blog/scaling-adoption-of-kerberos-at-uber/