一、身份认证
Hadoop系统的身份认证方法
服务 | 协议 | 方法 |
HDFS | RPC | Kerberos,委托令牌 |
HDFS | Web UI | SPNEGO(Kerberos),可插拔式 |
HDFS | REST(WebHDFS) | SPNEGO(Kerberos),委托令牌 |
HDFS | REST(HttpFS) | SPNEGO(Kerberos),委托令牌 |
MapReduce | RPC | Kerberos,委托令牌 |
MapReduce | Web UI | SPNEGO(Kerberos),可插拔式 |
YARN | RPC | Kerberos,委托令牌 |
YARN | Web UI | SPNEGO(Kerberos),可插拔式 |
- Kerberos
Hadoop支持两种身份验证机制:简单机制和Kerberos机制。
简单机制是默认设置,根据客户进程的有效uid确认用户名,该用户不会附带任何额外凭证,直接传给
Hadoop。这种模式下,Hadoop完全信任使用者,对于任何访问集群的使用者都能被完全信任,直接访问所有数据和管理员级功能。一般只在概念验证性系统或者实验环境下运行该模式。
Kerberos:
Kerberos中的身份识别称为主体(principal),每个参与Kerberos协议认证的用户和服务都需要一个主体来唯一的标识自己。主体分为两种:用户主体和服务主体。用户主体名称(user principal name,
UPN)代表常规用户,类似于操作系统中的用户名或者账号。 服务主体名称(service principal name,SPN)代表用户需要访问的服务,例如特定服务器上的数据库。
域(realm)。一个Kerberos域就是一个身份验证管理域,所有主体都被分配到特定的Kerberos域。域确立了边界,这使得管理更为容易。
密钥分发中心(key distribution center,KDC)。 KDC 由三部分组成:Kerberos 数据库、认证服务
(authentication service,AS)和票据授予服务(ticket-granting service,TGS)。 Kerberos 数据库存储的内容包含主体及其所属域的所有相关信息。
Kerberos术语缩写:
术语 | 名称 | 描述 |
UPN | 用户主体名 | 定义给定域中一个用户的主体,格式为 < 短名称 ><@ 域 > 或 < 短名称 >/ admin@< 域 >。比如alice@EXAMPLE.com,唯一标识了 Kerberos 域 EXAMPLE.COM 中用户(也叫作短名称)alice 的UPN。 |
SPN | 服务主体名 | 定义给定域中特定主机上一个服务的主体,格式为 < 短名称 >/< 主 机名 >@< 域 >。比如hdfs/node1.example.com@EXAMPLE.COM,该主体表示一个 hdfs 服务的 SPN,该服务在 Kerberos 域 EXAMPLE.COM 中的主机 node1.example.com上。SPN 中的斜杠(/)用于分隔短名称 hdfs 和主机名node.example.com。 |
TGT | 票据授予票据 | AS 认证成功后授予用户的一种特殊票据 |
KDC | 密钥分发中心 | 一种 Kerberos 服务器,包含 3 部分:Kerberos 数据库、AS和TGS |
AS | 认证服务 | 分发 TGT 的 KDC 服务 |
TGS | 票据授予服务 | 验证 TGT 和授予服务票据的 KDC 服务 |
下面是一个工作流示例,展示 Kerberos 大概是怎么工作的。首先定义所有出现的组件。
EXAMPLE.COM
Kerberos 域。
Alice是一个系统用户,其 UPN 为 alice@EXAMPLE.COM。 myservice
server1.example.com 上运行的一个服务,其 SPN 为 myservice/server1.example.com@EXAMP
kdc.example.com Kerberos 域 EXAMPLE.COM 的 KDC。
Alice 要想使用 myservice,需要向 myservice 提供一个有效的服务票据,具体方法如下所述。
(1)Alice 需要获取一个 TGT。为此,她向 kdc.example.com 上的 AS 发起一个请求,表明自己是主体 alice@EXAMPLE.COM
(2)AS 做出响应,为主体 a lice@EXAMPLE.COM 提供一个使用密钥(密 码)加密的 TGT。
(3)接收到加密信息后,Alice 被提示输入主体 a lice@EXAMPLE.COM 的 正确密码,从而解密信息。
(4)成功解密包含 TGT 的信息后,Alice 向 kdc.example.com 上的 TGS 请求服务myservice/server1.example.com@EXAMPLE.COM的一个服务票据,并在请求中提供出TGT信息
(5) TGS对TGT进行验证,并提供给Alice一个使用主体myservice/server1.example.com@EXAMPLE.COM的密钥加密的服务票据。
(6) Alice现在将服务票据提供给myservice,myservice随后使用myservice/server1.example.com@EXAMPLE.COM的密钥对其解密,并验证票据有效性。
(7)由于Alice已经正确验证其身份,因此服务myservice允许其使用。
HDFS、MapReduce、YARN、HBase、Oozie和ZooKeeper都支持Kerberos作为客户端的身份验证机制,但在具体实现方面会由于服务与接口的区别而有所不同。对基于RPC的协议,简单认证与安全层
(Simple Authentication and Security Layer,SASL)框架被用于向下层协议添加认证。理论上,任意
SASL协议都能得到支持;但实际上,真正仅支持的机制是GSSAPI(Kerberos V5)和DIGEST-MD5。
SASL和SPNEGO的身份验证过程遵循标准的Kerberos协议,只有提交服务票据的机制发生改变。下面是一个用户Alice通过Kerberos与HDFS的NameNode进行验证交互的过程:
(1)Alice为由hdfs/namenode.example.com@EXAMPLE.COM标识的HDFS服务,从
kdc.example.com的TGS请求一个服务票据,并随请求附上她的TGT。
(2)TGS验证TGT之后,提供给Alice一个服务票据,使用hdfs/namenode.example.com@EXAMPLE.COM的主体密钥。
(3)Alice把服务票据提交给NameNode(通过SASL),NameNode能够使用hdfs/namenode.example.com@EXAMPLE.COM的密钥对票据进行解密和认证。
2.令牌
任何分布式系统内,以用户名义执行的所有行为都有必要验证该用户身份。仅仅验证服务的归属者是不够的,验证必须发生在每一次交互中。以运行一个MapReduce作业为例,想要扩展命令行参数中的任意通配符,需要在客户端和NameNode之间进行身份验证;为了提交作业,则需要在客户端和
JobTracker之间均进行身份验证。
JobTracker将工作分解为被每个集群中的TaskTracker顺序执行的任务,每个任务必须与NameNode
通信,以打开组成输入分片(input split)的文件。为了加强文件系统的许可控制,每个任务必须通过
NameNode的身份验证。若Kerberos是唯一的身份验证机制,用户的TGT需要分派给每一个任务。这样做会允许任务向任意一个受Kerberos保护的服务发起身份验证请求,如果在一个高负载集群上
Kerberos协议来认证每次交互,会对服务器造成很大的压力。而这种做法是不合适的。通过签发能分派
给每个任务、但被限制在某个特定服务内的认证令牌来解决该问题。
委托令牌
Hadoop有多种令牌,用于在没有TGT或Kerberos服务票据的情况下进行认证后的访问。通过
Kerberos与NameNode完成身份验证后,一个客户端能够获得一个委托令牌。委托令牌其实是客户端和NameNode之间共享的密钥,能够通过DIGEST-MD5机制用于RPC身份验证。
客户端和NameNode之间的两次交互。首先,客户端使用Kerberos服务票据进行了
getDelegationToken()的RPC调用,以请求一个委托令牌(1)。
NameNode回复了一个委托令牌(2)。
客户端发起getListing()的RPC调用,以请求目录列表,但这次客户端使用的是供身份验证用的委托令牌(3)。
验证令牌后,NameNode会给客户端响应,内容为DirectoryListing(4)。
令牌既有失效日期,也有最大发行日期。令牌在失效日期之后会失效,但直至其最大发行日期前,仍然能够被更新。客户端能够在完成向NameNode的初始Kerberos认证之后,发起对委托令牌的请求。令牌会有一个指定的更新机制。为用户更新令牌时,令牌更新器使用其Kerberos凭证进行认证。委托令牌最常见的用法是在MapReduce任务中,客户端指定JobTracker为令牌更新器。委托令牌由
NameNode的URL生成,且存储在JobTracker的系统目录下,以便将其传给任务。该方法使得任务
访问HDFS时,不会将用户的TGT置于泄露风险中。
块访问令牌
块访问令牌由NameNode生成,在客户端通过身份验证,且NameNode已执行完访问文件/块的必要授权检查后,会将其发送给客户端。块访问令牌包括客户端ID、块ID和允许访问模式(READ、
WRITE、COPY、REPLACE),并且使用NameNode和DataNode之间的共享密钥进行签名。该共享密钥永远不会让客户端获得,且块访问令牌过期时,客户端必须向NameNode重新请求一个令牌。
客户端使用Kerberos凭证,通过getBlockLocations()的RPC调用,向NameNode请求所需的块位置(1)。
NameNode会响应一个LocatedBlock对象,该对象包括针对被请求块的块访问令牌(2)。
客户端使用块访问令牌,通过数据传输协议中的readBlock()方法,向DataNode进行身份验证并请求数据(3)。
DataNode将响应请求的数据(4)。
作业令牌
提交一个MapReduce作业时,JobTracker会创建一个名为“作业令牌”的密钥,该令牌被作业中的任务用于向TaskTracker发起身份验证。JobTracker将作业令牌放置在HDFS中JobTracker的系统目录下,并通过RPC分发给各个TaskTracker。TaskTracker会将该令牌存放在本地磁盘的作业目录下,该目录仅能被作业用户访问。作业令牌用于给任务和TaskTracker之间的RPC通信进行身份验证,也用于生成一种散列值,该散列值确保通过HTTP传输的中间输出在shuffle阶段仅能被该作业的任务访问。此外,返回shuffle数据的TaskTracker会计算一个散列值,供每个任务验证它是在同真实的
TaskTracker——而不是伪装者——进行对话。
下面的时序图展示了作业建立阶段使用的身份验证方法:
客户端通过Kerberos认证请求建立一个新作业(1)。
JobTracker给客户端响应作业ID,用于该作业的唯一标识(2)。
客户端随之向NameNode请求委托令牌,并使用JobTracker作为更新器(3)。
NameNode给客户端响应委托令牌(4)。
只有客户端通过Kerberos身份验证后,才会被分发委托令牌。最后,通过Kerberos与JobTracker进行身份验证的客户端将委托令牌与其他所需的作业细节发送给JobTracker
开始执行作业时,时序图如下:
JobTracker会生成一个作业令牌,并将作业令牌、委托令牌和其他所需信息打包发送给
TaskTracker(1)。
JobTracker与TaskTracker对话时,需经过Kerberos身份验证。TaskTracker会把接收到的令牌存储至一个仅能被提交作业的用户访问的目录,然后运行任务(2)。
任务通过委托令牌打开文件,并请求块地址以获得输入分片(3)。
NameNode会将块地址和相应的块访问令牌响应给发起请求的任务(4)。
该任务随之使用获得的块访问令牌,从DataNode请求读取数据(5),
DataNode随之给予响应(6)。
作业执行过程中,任务会通过作业令牌进行身份验证,向TaskTracker报告任务状态(7)。
然后TaskTracker会通过Kerberos身份验证,并向JobTracker报告状态,从而收集整体作业状态
(8)。
二、数据加密
加密数据的时候,密钥的大小很重要。通常来说,密钥越大,越难破解,但缺点是加密速度就越慢。处
理很小的数据时,加密密钥的大小应该不超过数据本身。
在Hadoop中分为动态数据加密和静态数据加密
静态数据加密
静态数据加密主要是在hdfs中的数据进行加密。
动态数据加密
Hadoop有多种网络通信方式,包括RPC、TCP/IP和HTTP。MapReduce、JobTracker、
TaskTracker、NameNode和DataNode的API客户端均使用RPC调用。HDFS客户端使用TCP/IP套接字进行数据传输。HTTP协议用于MapReduce shuffle,很多Web UI的守护进程也使用HTTP协
议。这三种网络通信每种都有不同的动态加密方法。
1.Hadoop RPC加密
Hadoop的RPC实现支持SASL(Simple Authentication and Security Layer,简单验证与安全层),
SASL除了支持身份认证外,还提供了可选的信息完整性和信息加密。Hadoop使用Java的SASL实现,支持以下几种模式:
auth:用于客户端和服务端之间的身份验证
auth-int:用于身份验证和完整性
auth-conf:用于身份验证、完整性和机密性
Hadoop中的RPC保护在core-site.xml文件中的hadoop.rpc.protection属性中配置。该属性可以被设置成如下值。
authentication:默认值,将SASL设置为auth模式,仅提供身份验证。
integrity:将SASL设置为auth-int模式,在身份验证之外增加完整性验证。
privacy:将SASL设置为auth-conf模式,增加加密以保证完全的机密性。
配置Hadoop RPC保护,需要在core-site.xml中进行设置。(要重启所有守护进程后才能使设置生效。)
<property>
<name>hadoop.rpc.protection</name><value>privacy</value>
</property>
2.HDFS数据传输协议加密
HDFS数据从一个DataNode传输到另一个DataNode时,或者在DataNode和客户端之间传输时,会使用一个名为HDFS数据传输协议(HDFS data transfer protocol)的TCP/IP直连套接字。数据传输加密启用时(在hdfs-site.xml文件中配置,下面是配置代码,使配置生效需要重启DataNode和
NameNode),会使用Hadoop RPC协议交换数据传输协议中使用的加密密钥。
<property>
<name>dfs.encrypt.data.transfer</name>
<value>true</value><!--配置数据传输加密-->
</property>
<property>
<name>dfs.encrypt.data.transfer.cipher.suites</name><value>AES/CTR/NoPadding</value><!--加密算法配置成使用AES-->
</property>
<property>
<name>dfs.encrypt.data.transfer.cipher.key.bitlength</name><value>256</value><!--canalsobesetto128or192-->
</property>
3.Hadoop HTTP加密
HTTP加密—般使用HTTPS加密传输中的数据。HTTPS是一个使用SSL/TLS的HTTP增强。虽然
HTTPS是很标准化的,但在Hadoop中对它进行配置并非如此。一些Hadoop组件支持HTTPS,但它
们的配置步骤并不都一样,下面是加密shuffle和加密web Web UI。
加密shuffle与加密web Web UI在MR1与MR2的版本中设置有所区别。
<!--core-sitexml-->
.
<!--在MR1和MR2中,设置core-site.xml中的ssl属性都能启用加密WebUI。在MR1中,该设置还会启用加密shuffle。-->
<property>
<name>hadoop.ssl.enabled</name>
<value>true</value>
<final>true</final>
</property>
<!--mapred-site.xml-->
<!--仅对于MR2,要在mapred-site.xml中设置加密shuffleSSL属性。-->
<property>
<name>mapreduce.shuffle.ssl.enabled</name>
<value>true</value>
<final>true</final>
</property>
加密的Shuffle功能允许使用HTTPS加密MapReduce Shuffle,可以配置hadoop.ssl.hostname.verifier
使用可选的客户端身份验证(也称为双向HTTPS或带客户端证书的HTTPS)。它包括:
用于在HTTP和HTTPS之间切换SHUFFLE的HADOOP配置设置。
Hadoop配置设置,用于指定Shuffle服务使用的密钥库和信任库属性(位置,类型,密码)和获取
Shuffle数据的reducers任务。
以群集重新加载信任库(添加或删除节点时)的方法。