概述

由认证(authentication)和授权(authorization)两部分组成。

认证

概述

Hadoop认证机制同时采用Kerberos和Token两种机制。
Client通过Kerberos与Server完成认证,并从Server获取相应的Delegation Tokens。
Client与Server之间后续的认证都是通过Delegation Tokens,而不进过Kerberos。
Client和NameNode、ResourceManager初次通信均采用Kerberos进行身份认证,之后换Delegation Token减少开销。DataNode和NameNode以及NodeManager和ResourceManager之间始终采用Kerberos机制。默认Kerberos认证关闭。

Kerberos

hadoop.security.authenticaiton设置为”kerberos”开启,默认值为”simple”。

Token

概述
Tokens有一个过期时间的概念,需要周期性的更新以保证其有效性。但是,它也不能无限制的更新,这由最大生命周期控制。此外,在Delegation Token过期前也被取消。
Delegation Tokens可以避免分发Kerberos TGT 或 keytab,而这些信息一旦泄露,将获得所有服务的访问权限。另一方面,每个Delegation Token与其关联服务严格的绑定在一起,且最终会过期。所以,即使Delegation Token泄露,也不会造成太大损失。

Client可以指定Token的renewer(不一定是自己)。renewer可以刷新Token。其他人不行。
Delegation Tokens的生成和验证主要依赖于HMAC机制。
org.apache.hadoop.security.token.Token类定义

  1. byte[] identifier;
  2. byte[] password;
  3. Text kind; //TokenIdentifier 类型
  4. Text service; //此Token属于什么服务
  5. TokenRenewer renewer;

配置

  1. renew-interval #token更新周期 默认24小时
  2. #最大生命周期 默认7天

ResourceManager Delegation Token

YARN Application Token

Application Token用于保证ApplicationMaster与ResourceManager之间的通信安全。该Token的密钥(masterKey)由ResourceManager传递给NodeManager,并保存到ApplicationMaster Container的私有目录下。当NodeManager启动ApplicationMaster时,所有的Token将被加载到ApplicationMaster的UGI中(NodeManager通过环境变量HADOOP_TOKEN_FILE_LOCATION将Token所在目录传递给UGI,这样UGI可以直接从文件中读取Token信息,所有其他Token的传递过程也是一样的),以在与ResourceManager通信时进行安全认证,需要注意的是,该Token的生命周期与ApplicationMaster实例一致。该Token由ResourceManager中的AMRMTokenSecretManager管理和维护。

YARN NodeManager Token

ApplicationMaster与NodeManager通信时,需出示NodeManager Token以表明ApplicationMaster自身的合法性。该Token是由ResourceManager通过RPC函数ApplcationMasterProtocol#allocate的应答中发送给ApplicationMaster的,它的密钥是各个NodeManager向ResourceManager注册(ResourceTracker#registerNodeManager)和发送心跳信息(ResourceTracker#nodeHeartbeat)时领取的。ApplicationMaster通过ContainerManagementProtocol协议与NodeManager通信时,需要出示该Token。该Token由ResourceManager中的NMTokenSecretManagerInRM管理和维护。

YARN Container Token

ApplicationMaster与NodeManager通信启动Container时,需出示Container Token以表明Container的合法性。该Token是由ResourceManager通过RPC函数ApplcationMasterProtocol.allocate的应答存放到Container中发送给ApplicationMaster的,它的密钥是各个NodeManager向ResourceManager注册和发送心跳信息时领取的。ApplicationMaster通过RPC函数ContainerManagementProtocol.startContainer与NodeManager通信启动Container时,需要出示相应的Container Token。该Token由ResourceManager中的RMContainerTokenSecretManager管理和维护。

YARN Localizer Token

保证ContainerLocalizer与NodeManager之间的通信安全。ContainerLocalizer负责在任务运行 之前从HDFS上下载各类所需的文件资源,以构建一个本地执行环境,在文件下载过程中,ContainerLocalizer通过RPC协议LocalizationProtocol不断向NodeManager汇报状态信息。

其他

MapReduce Client Token、MapReduce Job Token、MapReduce Shuffle Secret

授权

概述

授权采用访问控制列表(Access Control List, ACL)机制。
三大访问控制列表:队列访问控制列表、应用访问控制列表、服务访问控制列表。

队列访问控制列表

为了方便管理集群中的用户,YARN将用户/用户组分成若干队列,并可指定每个用户/用户组所属的队列。通常而言,每个队列包含两种权限:提交应用程序权限和管理应用程序权限(比如杀死任意应用程序),这些是通过配置文件etc/hadoop/mapred-queue-acls.xml设置的。

应用访问控制列表

应用程序访问控制机制的设置方法已经在5.5节进行了介绍,主要方法是在客户端设置为每类ApplicationAccessType(目前只有VIEW_APP和MODIFY_APP两种类型)设置对应的用户列表,这些信息传递到ResourceManager端后,由它维护和使用。通常而言,为了用户使用方便,应用程序可对外提供一些特殊的可直接设置的参数(而不是通过API设置),以MapReduce作业为例,用户可以通过参数mapreduce.job.acl-view-job和mapreduce.job.acl-modify-job为每个作业单独设置查看和修改权限。需要注意的是,默认情况下,作业拥有者和超级用户(可配置)拥有以上两种权限且不可以修改。

服务访问控制列表

服务访问控制是Hadoop提供的最原始的授权机制,它用于确保只有那些经过授权的客户端才能访问对应的服务。比如可通过为ApplicationClientProtocol协议设置访问控制列表以指定哪些用户可以向集群中提交应用程序。
服务访问控制是通过控制各个服务之间的通信协议实现的,它通常发生在其他访问控制机制之前,比如文件权限检查、队列权限检查等。

Hadoop源码

image.png
SaslRpcClient authTypes里面取编号最小的auth方式去连接Hadoop的server。
在非Simple模式中,Client和Server用什么认证方式建立连接是要协商的
Server类中。当Auth方法有TOKEN的话,Server会创建TOKEN认证模式的Server。

  1. private RpcSaslProto buildSaslNegotiateResponse()
  2. throws IOException, InterruptedException {
  3. RpcSaslProto negotiateMessage = negotiateResponse;
  4. // accelerate token negotiation by sending initial challenge
  5. // in the negotiation response
  6. if (enabledAuthMethods.contains(AuthMethod.TOKEN)) {
  7. saslServer = createSaslServer(AuthMethod.TOKEN);
  8. byte[] challenge = saslServer.evaluateResponse(new byte[0]);
  9. RpcSaslProto.Builder negotiateBuilder =
  10. RpcSaslProto.newBuilder(negotiateResponse);
  11. negotiateBuilder.getAuthsBuilder(0) // TOKEN is always first
  12. .setChallenge(ByteString.copyFrom(challenge));
  13. negotiateMessage = negotiateBuilder.build();
  14. }
  15. sentNegotiate = true;
  16. return negotiateMessage;
  17. }

创建Server的时候如果是Kerberos认证方式会把TOKEN认证方式添加到列表最前端。
image.png

  1. private List<AuthMethod> getAuthMethods(SecretManager<?> secretManager,
  2. Configuration conf) {
  3. AuthenticationMethod confAuthenticationMethod =
  4. SecurityUtil.getAuthenticationMethod(conf);
  5. List<AuthMethod> authMethods = new ArrayList<AuthMethod>();
  6. if (confAuthenticationMethod == AuthenticationMethod.TOKEN) {
  7. if (secretManager == null) {
  8. throw new IllegalArgumentException(AuthenticationMethod.TOKEN +
  9. " authentication requires a secret manager");
  10. }
  11. } else if (secretManager != null) {
  12. LOG.debug(AuthenticationMethod.TOKEN +
  13. " authentication enabled for secret manager");
  14. // most preferred, go to the front of the line!
  15. authMethods.add(AuthenticationMethod.TOKEN.getAuthMethod());
  16. }
  17. authMethods.add(confAuthenticationMethod.getAuthMethod());
  18. LOG.debug("Server accepts auth methods:" + authMethods);
  19. return authMethods;
  20. }

参考资料

https://blog.cloudera.com/hadoop-delegation-tokens-explained/#1
https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/hadoop_tokens.html
https://www.jianshu.com/p/617fa722e057