11.3 Hadoop安全机制实现
在1.0.0之后的版本中,Hadoop在RPC、HDFS和MapReduce等方面引入了安全机制。在本节中,我们将分别介绍RPC、HDFS和MapReduce中涉及的安全机制实现方法。
11.3.1 RPC
Hadoop RPC安全机制包括基于Kerberos和令牌的身份认证机制和基于ACL的服务访问控制机制。
1.身份认证机制
为了保证网络通信的安全性,Hadoop中所有RPC连接均采用了SASL。在11.2.1小节中,我们已经介绍了SASL的原理。SASL本身不包含认证机制,需由用户指定一个第三方实现,而Hadoop正是将Kerberos和DIGEST-MD5两种认证机制添加到SASL中实现了RPC安全认证。在Hadoop中,除了NameNode,其他服务仅支持Kerberos认证方法。下面简要介绍这两种认证机制。
❑Kerberos:客户端(如JobClient)获取一个服务票据,然后才可以访问对应的服务器。
❑Kerberos+DIGEST-MD5:在这种机制中,Kerberos用于在客户端和服务器端之间建立一条安全的网络连接,之后客户端可通过该连接从服务器端获取一个密钥。由于该密钥仅有客户端和服务器端知道,因此,接下来客户端可使用该共享密钥获取服务的认证。使用共享密钥进行安全认证(使用DIGEST-MD5协议)有多方面的好处:由于它只涉及认证双方而不必涉及第三方应用(比如Kerberos中的KDC),因此安全且高效;客户端也可以很方便地将该密钥授权给其他客户端,以让其他客户端安全访问该服务。我们将基于共享密钥生成的安全认证凭证称为令牌(Token)。在Hadoop中,所有令牌主要由identifier和password两部分组成,其中,identifier包含了该令牌中的基本信息,而password则是通过HMAC-SHA1作用在identifier和一个密钥上生成的,该密钥长度为20个字节并由Java的SecureRamdom类生成。Hadoop中共有三种令牌,分别如下。
(1)授权令牌(Delegation Token)
授权令牌主要用于NameNode为客户端进行认证。当客户端初始访问NameNode时,如果通过Kerberos认证,则NameNode会为它返回一个密钥,之后客户端只需借助该密钥便可进行NameNode认证。为了防止重启后密钥丢失,NameNode将各个客户端对应的密钥持久化保存到镜像文件中。默认情况下,所有密钥每隔24小时更新一次,且NameNode总会保存前7小时的密钥以保证之前的密钥可用。
(2)数据块访问令牌(Block Access Token)
数据块访问令牌主要用于DataNode、SecondaryNameNode和Balancer为客户端存取数据块进行认证。当客户端向NameNode发送文件访问请求时,如果通过NameNode认证以及文件访问权限检查,则NameNode会将该文件对应的数据块位置信息和数据块访问密钥发送给客户端,客户端需凭借数据块访问密钥才可以读取一个DataNode上的数据块。NameNode会通过心跳将各个数据块访问密钥分发给DataNode、SecondaryNameNode和Balancer。需注意的是,数据块访问密钥并不会持久化保存到磁盘上,默认情况下,它们每隔10小时更新一次并通过心跳通知各个相关组件。
(3)作业令牌(Job Token)
作业令牌主要用于TaskTracker对任务进行认证。用户提交作业到JobTracker后,JobTracker会为该作业生成一个作业令牌,并写到该作业对应的HDFS系统目录下。当该作业的任务调度到各个TaskTracker上后,将从HDFS上获取作业令牌。该令牌可用于任务与TaskTracker之间进行相互认证(比如Shuffle阶段的安全认证)。与数据块访问令牌一样,作业令牌也不会持久化保存到内存中,一旦JobTracker重新启动,就会生成新的令牌。由于每个作业对应的令牌已经写入HDFS,所以之前的仍然可用。
相比于单纯使用Kerberos,基于令牌的安全认证机制有很多优势,具体如下。
❑性能:在Hadoop集群中,同一时刻可能有成千上万的任务正在运行。如果我们使用Kerberos进行服务认证,则所有任务均需要KDC中AS提供的TGT,这可能使得KDC成为一个性能瓶颈,而采用令牌机制则可避免该问题。
❑凭证更新:在Kerberos中,为了保证TGT或者服务票据的安全,通常为它们设置一个有效期,一旦它们到期,会对其进行更新。如果直接采用Kerberos验证,则需要将更新之后的TGT或者服务票据快速推送给各个Task,这必将带来实现上的烦琐。如果采用令牌,当令牌到期时,只需延长它的有效期而不必重新生成令牌。此外,Hadoop允许令牌在过期一段时间后仍可用,从而为过期令牌更新留下足够时间。
❑安全性:用户从Kerberos端获取TGT后,可凭借该TGT访问多个Hadoop服务,因此,泄露TGT造成的危害远比泄露令牌大。
❑灵活性:在Hadoop中,令牌与Kerberos之间没有任何依赖关系,Kerberos仅仅是进行用户身份验证的第一道防线,用户完全可以采用其他安全认证机制替换Kerberos。因此,基于令牌的安全机制具有更好的灵活性和扩展性。
2.服务访问控制机制
服务访问控制是Hadoop提供的最原始的授权机制,用于确保只有那些经过授权的客户端才能访问对应的服务。比如管理员可限制只允许若干用户/用户组向Hadoop提交作业。
服务访问控制是通过控制各个服务之间的通信协议实现的。它通常发生在其他访问控制机制之前,比如文件权限检查、队列权限检查等。
为了启用该功能,管理员需在core-site.xml中将参数hadoop.security.authorization置为true,并在hadoop-policy.xml中为各个通信协议指定具有访问权限的用户或者用户组。我们将具有访问权限的用户或者用户组称为访问控制列表(Access Control List, ACL)。管理员可为9个协议添加访问控制列表,如表11-1所示。
这9个ACL的配置方法相同,即每个ACL可配置多个用户和用户组,用户之间和用户组之间都用“,”分割,而用户和用户组之间用空格分割。注意,如果只有用户组,前面必须保留一个空格,比如:
<property>
<name>security.job.submission.protocol.acl</name>
<value>alice, bob group1,group2</value>
</property>
上述代码表示用户alice和bob、用户组group1和group2可向Hadoop集群中提交作业。又如:
<property>
<name>security.client.protocol.acl</name>
<value>group3</value>
</property>
上述代码表示只有用户组group3可访问HDFS。
再如:
<property>
<name>security.client.protocol.acl</name>
<value>*</value>
</property>
上述代码表示所有用户和分组均可访问HDFS。
注意 默认情况下,这9个通信协议对任何用户和分组开放。
hadoop-policy. xml文件可使用以下命令动态加载。
❑更新NameNode相关配置:bin/hadoop dfsadmin-refreshServiceAcl。
❑更新JobTracker相关配置:bin/hadoop mradmin-refreshServiceAcl。
注意,只有属性security.refresh.policy.protocol.acl指定的用户才可以更新该配置文件。