1.kerberos安全认证原理:
客户端跟服务端可以对对方进行身份认证,防止窃听,防止replay攻击。保护数据完成性,是一种应用对称密钥体制进行密钥管理的系统。
2.基本概念
Principal(安全个体):被认证的个体,有一个名字和口令
KDC(key distribution center):一个网络服务服务,提供ticket和临时会话密钥
Ticket:一个记录,客户用它来向服务器证明自己的身份,客户标识,会话密钥和时间戳
TGT:由kerberos服务生成,提供给应用程序与kerberos服务器简历认证安装全会话,该票据默认有效期为24 小时,24 小时后票据自动过期。
3.kerberos协议
kerberos协议分为两个部分
1.client想KDC发送自己的身份信息,KDC从ticket granting Servive 的得到tgt,并用协议开始前client与kdc的密钥将tgt加密回复给client
此时直有真正的client才能例用它与kdc之间的密钥将加密后的tgt解密,从而获得tgt
2.client例用之前获得的tgt向kdc请求其他service的ticket从而通过其他service身份鉴别(调用hadoop 的接口访问文件系统此时底层rpc会自动携带tgt去kerberos认证)
4.客户端二次开发流程
若待连接的hdfs服务端开启了kerberos认证,则在使用改hdfs提供的api之前需要按照如下的方法进行Kerberos安全认证,认证通过之后才能实例化Filesystem,使用hdfs的api。
4.1配置文件准备
1.修改配置文件core-site.xml,令其使用Kerberos安全认证,配置如下
hadoop.security.authentucation
kerberos
修改配置文件hive-site.xml,令其使用Kerberos安全认证,配置如下
matestore开关
hadoop.matestore.sasl.enabled
true
修改配置文件hive-site.xml,令其使用Kerberos安全认证,配置如下
hive2开关
hive.server2.authentucation
KERBEROS
2.去的安全认证账号,及线管凭证文件(keytab文件或者密码和krb5文件)。如hdfs用户的凭据文件一般为krb5.conf和hdfs.keytab。
4.2代码示例
两种方式
4.1.1hadoop登录模块
需要keytab文件,优点市票据过期会自动刷新,只要服务器端的凭据文件不重新生成,都可以一直有效,而应用所在机器不需要部署kerberos 。缺点市对于已经存在的应用程序需要改造代码(改造代价很小)
代码如下:即在实例化hdfs文件系统之前需要先加载配置文件,进行kerberos安全认证
public class HelloKerberosHadoop{
public static void main(String [] args){
Cinfiguration conf =loadConfig();
FileSystem hdfs= null;
//本地文件
Path scr =new Path("E:\\zte.txt");
//hdfs文件
Path dst=nwe Path("/");
try{
authenticatuib(conf."hdfs/aaa@cdh.com",
"/src/main/resource/krb5.conf",
"/src/main/resource/krb5.conf")
hdfs=Filesystem.get(conf);
hdfs.copyFromLocalFile(src,dst);
}catch(ioexception,e){
sout("io异常")
}finally{
try{
hdfs.close()}catch(ioexception,e){
e.printStackTrace();
}
//kerberos security authentication
private static void authentication(Cinfiguration conf ,String principal,Stringkrb5Path,String keytabPath) whrows oiex{
if("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication")))
{System.setProperty("java.security.krb5.conf".krb5Path);
UserGroupInformation.setCinfiguration(conf);
UserGroupInformation.loginUserFromkeytab(principal,keytabPath);
}
}
private static Cinfiguration loadConfig(){
Cinfiguration conf =new Cinfiguration();
//conf.addResource(new Path(PATH_TO_HDFS_SITE_XML));
//conf.addResource(new Path(PATH_TO_CORE_SITE_XML));
return conf;
}
}
4.1.2kinit命令
需要keytab文件或者输入密码,缺点是票据过期(可以配置),而应用所在机器需要部署kerberos,要使用kinit命令行 。优点是不需要代码。
具体的命令行如下:
方法一使用keytab文件
kinit -k -t hdfs.keytab hdfs/aaa.CDH.COM
方法二输入密码
kinit me@CL2.CDH.COM
password for me@CL2.CDH.COM:
若使用keytab文件,加入代码中,示例如下:
public class HelloKerberosHadoopViaSH{
public static void main(String [] args){
Cinfiguration conf =loadConfig();
FileSystem hdfs= null;
//本地文件
Path scr =new Path(arg[0]);
//hdfs文件
Path dst=nwe Path("/");
try{
if("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))){
String command ="kinit -k -t hdfs.keytab hdfs/aaa.CDH.COM";
Porcess process=Runtime.getRuntime().exec(command);
if(process.waitFor()!=0){
sout("exec kiinit failed");
}
hdfs=Filesystem.get(conf);
hdfs.copyFromLocalFile(src,dst);
}catch(ioexception,e){
sout("io异常")
}catch(InterruptedException ,e){
sout("exec kinit InterruptedException!")
}finally{
try{
hdfs.close()}catch(ioexception,e){
e.printStackTrace();
}
}
}
private static Cinfiguration loadConfig(){
Cinfiguration conf =new Cinfiguration();
//conf.addResource(new Path(PATH_TO_HDFS_SITE_XML));
//conf.addResource(new Path(PATH_TO_CORE_SITE_XML));
return conf;
}
}