概述
由认证(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
类定义
byte[] identifier;
byte[] password;
Text kind; //TokenIdentifier 类型
Text service; //此Token属于什么服务
TokenRenewer renewer;
配置
renew-interval #token更新周期 默认24小时
#最大生命周期 默认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源码
SaslRpcClient authTypes里面取编号最小的auth方式去连接Hadoop的server。
在非Simple模式中,Client和Server用什么认证方式建立连接是要协商的
Server类中。当Auth方法有TOKEN的话,Server会创建TOKEN认证模式的Server。
private RpcSaslProto buildSaslNegotiateResponse()
throws IOException, InterruptedException {
RpcSaslProto negotiateMessage = negotiateResponse;
// accelerate token negotiation by sending initial challenge
// in the negotiation response
if (enabledAuthMethods.contains(AuthMethod.TOKEN)) {
saslServer = createSaslServer(AuthMethod.TOKEN);
byte[] challenge = saslServer.evaluateResponse(new byte[0]);
RpcSaslProto.Builder negotiateBuilder =
RpcSaslProto.newBuilder(negotiateResponse);
negotiateBuilder.getAuthsBuilder(0) // TOKEN is always first
.setChallenge(ByteString.copyFrom(challenge));
negotiateMessage = negotiateBuilder.build();
}
sentNegotiate = true;
return negotiateMessage;
}
创建Server的时候如果是Kerberos认证方式会把TOKEN认证方式添加到列表最前端。
private List<AuthMethod> getAuthMethods(SecretManager<?> secretManager,
Configuration conf) {
AuthenticationMethod confAuthenticationMethod =
SecurityUtil.getAuthenticationMethod(conf);
List<AuthMethod> authMethods = new ArrayList<AuthMethod>();
if (confAuthenticationMethod == AuthenticationMethod.TOKEN) {
if (secretManager == null) {
throw new IllegalArgumentException(AuthenticationMethod.TOKEN +
" authentication requires a secret manager");
}
} else if (secretManager != null) {
LOG.debug(AuthenticationMethod.TOKEN +
" authentication enabled for secret manager");
// most preferred, go to the front of the line!
authMethods.add(AuthenticationMethod.TOKEN.getAuthMethod());
}
authMethods.add(confAuthenticationMethod.getAuthMethod());
LOG.debug("Server accepts auth methods:" + authMethods);
return authMethods;
}
参考资料
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