kerberos学习笔记
来源:互联网 发布:恩施宏观经济数据分析 编辑:程序博客网 时间:2024/06/05 11:19
之所以搞kerberos,是因为我们一个项目是基于华为的fusioninsght开发的,华为的这套大数据平台处处有kerberos认证,搞得我很是懵逼,下面是我的学习参考资料。不要参考我的。你一定会懵逼的。我自己记着自己用的。
记住,如果用华为的fusioninght平台,zookeeper包要用华为自己的,要不然验证会不通过,血的教训。
1.kerberos认证原理
2.kerberos安装和常用命令并与cdh集成
以下是我的学习收获
1.想要获得认证有两种途径
第一种:通过kinit admin,输入用户密码,这种是通过shell命令
第二种:通过krb5.conf和keytab文件,这种一般是通过程序获得认证,代码如下init()、login()方法加在需要连接服务器某个服务(比如zookepeer)程序之前运行
private static void login() throws IOException { if (User.isHBaseSecurityEnabled(conf)) { String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator; userName = "admin"; userKeytabFile = userdir + "user.keytab"; krb5File = userdir + "krb5.conf"; /* * if need to connect zk, please provide jaas info about zk. of course, * you can do it as below: * System.setProperty("java.security.auth.login.config", confDirPath + * "jaas.conf"); but the demo can help you more : Note: if this process * will connect more than one zk cluster, the demo may be not proper. you * can contact us for more help */ // System.out.println(); LoginUtil.setJaasConf(ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME, userName, userKeytabFile); LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, ZOOKEEPER_DEFAULT_SERVER_PRINCIPAL); LoginUtil.login(userName, userKeytabFile, krb5File, conf); } } private static void init() throws IOException { // Default load from conf directory conf = HBaseConfiguration.create(); String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator; conf.addResource(new Path(userdir + "core-site-dev.xml")); conf.addResource(new Path(userdir + "hdfs-site-dev.xml")); conf.addResource(new Path(userdir + "hbase-site-dev.xml")); conf.addResource(new Path(userdir + "hive-site-dev.xml")); }
还有一个LoginUtil.java类
package cn.tongdun.datacompute.biz.suppport;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.security.UserGroupInformation;import org.apache.hadoop.security.authentication.util.KerberosUtil;import org.apache.log4j.Logger;import javax.security.auth.login.AppConfigurationEntry;import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;import java.io.File;import java.io.IOException;import java.util.HashMap;import java.util.Map;public class LoginUtil { private static final Logger LOG = Logger.getLogger(LoginUtil.class); private static final String JAVA_SECURITY_KRB5_CONF_KEY = "java.security.krb5.conf"; private static final String LOGIN_FAILED_CAUSE_PASSWORD_WRONG = "(wrong password) keytab file and user not match, you can kinit -k -t keytab user in client server to check"; private static final String LOGIN_FAILED_CAUSE_TIME_WRONG = "(clock skew) time of local server and remote server not match, please check ntp to remote server"; private static final String LOGIN_FAILED_CAUSE_AES256_WRONG = "(aes256 not support) aes256 not support by default jdk/jre, need copy local_policy.jar and US_export_policy.jar from remote server in path /opt/huawei/Bigdata/jdk/jre/lib/security"; private static final String LOGIN_FAILED_CAUSE_PRINCIPAL_WRONG = "(no rule) principal format not support by default, need add property hadoop.security.auth_to_local(in core-site.xml) value RULE:[1:$1] RULE:[2:$1]"; private static final String LOGIN_FAILED_CAUSE_TIME_OUT = "(time out) can not connect to kdc server or there is fire wall in the network"; private static final boolean IS_IBM_JDK = System.getProperty("java.vendor").contains("IBM"); private static final boolean IS_WINDOWS_OS = System.getProperty("os.name").toLowerCase() .contains("windows"); public synchronized static void login(String userPrincipal, String userKeytabPath, String krb5ConfPath, Configuration conf) throws IOException { // 1.check input parameters if ((userPrincipal == null) || (userPrincipal.length() <= 0)) { LOG.error("input userPrincipal is invalid."); throw new IOException("input userPrincipal is invalid."); } if ((userKeytabPath == null) || (userKeytabPath.length() <= 0)) { LOG.error("input userKeytabPath is invalid."); throw new IOException("input userKeytabPath is invalid."); } if ((krb5ConfPath == null) || (krb5ConfPath.length() <= 0)) { LOG.error("input krb5ConfPath is invalid."); throw new IOException("input krb5ConfPath is invalid."); } if ((conf == null)) { LOG.error("input conf is invalid."); throw new IOException("input conf is invalid."); } // 2.check file exsits File userKeytabFile = new File(userKeytabPath); if (!userKeytabFile.exists()) { LOG.error("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") does not exsit."); throw new IOException("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") does not exsit."); } if (!userKeytabFile.isFile()) { LOG.error("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") is not a file."); throw new IOException("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") is not a file."); } File krb5ConfFile = new File(krb5ConfPath); if (!krb5ConfFile.exists()) { LOG.error("krb5ConfFile(" + krb5ConfFile.getAbsolutePath() + ") does not exsit."); throw new IOException("krb5ConfFile(" + krb5ConfFile.getAbsolutePath() + ") does not exsit."); } if (!krb5ConfFile.isFile()) { LOG.error("krb5ConfFile(" + krb5ConfFile.getAbsolutePath() + ") is not a file."); throw new IOException("krb5ConfFile(" + krb5ConfFile.getAbsolutePath() + ") is not a file."); } // 3.set and check krb5config setKrb5Config(krb5ConfFile.getAbsolutePath()); setConfiguration(conf); // 4.login and check for hadoop loginHadoop(userPrincipal, userKeytabFile.getAbsolutePath()); LOG.info("Login success!!!!!!!!!!!!!!"); } private static void setConfiguration(Configuration conf) throws IOException { UserGroupInformation.setConfiguration(conf); } private static boolean checkNeedLogin(String principal) throws IOException { if (!UserGroupInformation.isSecurityEnabled()) { LOG.error("UserGroupInformation is not SecurityEnabled, please check if core-site.xml exists in classpath."); throw new IOException( "UserGroupInformation is not SecurityEnabled, please check if core-site.xml exists in classpath."); } UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); if ((currentUser != null) && (currentUser.hasKerberosCredentials())) { if (checkCurrentUserCorrect(principal)) { LOG.info("current user is " + currentUser + "has logined."); if (!currentUser.isFromKeytab()) { LOG.error("current user is not from keytab."); throw new IOException("current user is not from keytab."); } return false; } else { LOG.error("current user is " + currentUser + "has logined. please check your enviroment , especially when it used IBM JDK or kerberos for OS count login!!"); throw new IOException("current user is " + currentUser + " has logined. And please check your enviroment!!"); } } return true; } private static void setKrb5Config(String krb5ConfFile) throws IOException { System.setProperty(JAVA_SECURITY_KRB5_CONF_KEY, krb5ConfFile); String ret = System.getProperty(JAVA_SECURITY_KRB5_CONF_KEY); if (ret == null) { LOG.error(JAVA_SECURITY_KRB5_CONF_KEY + " is null."); throw new IOException(JAVA_SECURITY_KRB5_CONF_KEY + " is null."); } if (!ret.equals(krb5ConfFile)) { LOG.error(JAVA_SECURITY_KRB5_CONF_KEY + " is " + ret + " is not " + krb5ConfFile + "."); throw new IOException(JAVA_SECURITY_KRB5_CONF_KEY + " is " + ret + " is not " + krb5ConfFile + "."); } } public static void setJaasConf(String loginContextName, String principal, String keytabFile) throws IOException { if ((loginContextName == null) || (loginContextName.length() <= 0)) { LOG.error("input loginContextName is invalid."); throw new IOException("input loginContextName is invalid."); } if ((principal == null) || (principal.length() <= 0)) { LOG.error("input principal is invalid."); throw new IOException("input principal is invalid."); } if ((keytabFile == null) || (keytabFile.length() <= 0)) { LOG.error("input keytabFile is invalid."); throw new IOException("input keytabFile is invalid."); } File userKeytabFile = new File(keytabFile); if (!userKeytabFile.exists()) { LOG.error("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") does not exsit."); throw new IOException("userKeytabFile(" + userKeytabFile.getAbsolutePath() + ") does not exsit."); } javax.security.auth.login.Configuration.setConfiguration(new JaasConfiguration( loginContextName, principal, userKeytabFile.getAbsolutePath())); javax.security.auth.login.Configuration conf = javax.security.auth.login.Configuration .getConfiguration(); if (!(conf instanceof JaasConfiguration)) { LOG.error("javax.security.auth.login.Configuration is not JaasConfiguration."); throw new IOException("javax.security.auth.login.Configuration is not JaasConfiguration."); } AppConfigurationEntry[] entrys = conf.getAppConfigurationEntry(loginContextName); if (entrys == null) { LOG.error("javax.security.auth.login.Configuration has no AppConfigurationEntry named " + loginContextName + "."); throw new IOException( "javax.security.auth.login.Configuration has no AppConfigurationEntry named " + loginContextName + "."); } boolean checkPrincipal = false; boolean checkKeytab = false; for (int i = 0; i < entrys.length; i++) { if (entrys[i].getOptions().get("principal").equals(principal)) { checkPrincipal = true; } if (IS_IBM_JDK) { if (entrys[i].getOptions().get("useKeytab").equals(keytabFile)) { checkKeytab = true; } } else { if (entrys[i].getOptions().get("keyTab").equals(keytabFile)) { checkKeytab = true; } } } if (!checkPrincipal) { LOG.error("AppConfigurationEntry named " + loginContextName + " does not have principal value of " + principal + "."); throw new IOException("AppConfigurationEntry named " + loginContextName + " does not have principal value of " + principal + "."); } if (!checkKeytab) { LOG.error("AppConfigurationEntry named " + loginContextName + " does not have keyTab value of " + keytabFile + "."); throw new IOException("AppConfigurationEntry named " + loginContextName + " does not have keyTab value of " + keytabFile + "."); } } public static void setZookeeperServerPrincipal(String zkServerPrincipalKey, String zkServerPrincipal) throws IOException { System.setProperty(zkServerPrincipalKey, zkServerPrincipal); String ret = System.getProperty(zkServerPrincipalKey); if (ret == null) { LOG.error(zkServerPrincipalKey + " is null."); throw new IOException(zkServerPrincipalKey + " is null."); } if (!ret.equals(zkServerPrincipal)) { LOG.error(zkServerPrincipalKey + " is " + ret + " is not " + zkServerPrincipal + "."); throw new IOException(zkServerPrincipalKey + " is " + ret + " is not " + zkServerPrincipal + "."); } } private static void loginHadoop(String principal, String keytabFile) throws IOException { try { UserGroupInformation.loginUserFromKeytab(principal, keytabFile); } catch (IOException e) { LOG.error("login failed with " + principal + " and " + keytabFile + "."); LOG.error("perhaps cause 1 is " + LOGIN_FAILED_CAUSE_PASSWORD_WRONG + "."); LOG.error("perhaps cause 2 is " + LOGIN_FAILED_CAUSE_TIME_WRONG + "."); LOG.error("perhaps cause 3 is " + LOGIN_FAILED_CAUSE_AES256_WRONG + "."); LOG.error("perhaps cause 4 is " + LOGIN_FAILED_CAUSE_PRINCIPAL_WRONG + "."); LOG.error("perhaps cause 5 is " + LOGIN_FAILED_CAUSE_TIME_OUT + "."); throw e; } } private static void checkAuthenticateOverKrb() throws IOException { UserGroupInformation loginUser = UserGroupInformation.getLoginUser(); UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); if (loginUser == null) { LOG.error("current user is " + currentUser + ", but loginUser is null."); throw new IOException("current user is " + currentUser + ", but loginUser is null."); } if (!loginUser.equals(currentUser)) { LOG.error("current user is " + currentUser + ", but loginUser is " + loginUser + "."); throw new IOException("current user is " + currentUser + ", but loginUser is " + loginUser + "."); } if (!loginUser.hasKerberosCredentials()) { LOG.error("current user is " + currentUser + " has no Kerberos Credentials."); throw new IOException("current user is " + currentUser + " has no Kerberos Credentials."); } if (!UserGroupInformation.isLoginKeytabBased()) { LOG.error("current user is " + currentUser + " is not Login Keytab Based."); throw new IOException("current user is " + currentUser + " is not Login Keytab Based."); } } private static boolean checkCurrentUserCorrect(String principal) throws IOException { UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); if (ugi == null) { LOG.error("current user still null."); throw new IOException("current user still null."); } String defaultRealm = null; try { defaultRealm = KerberosUtil.getDefaultRealm(); } catch (Exception e) { LOG.warn("getDefaultRealm failed."); throw new IOException(e); } if ((defaultRealm != null) && (defaultRealm.length() > 0)) { StringBuilder realm = new StringBuilder(); StringBuilder principalWithRealm = new StringBuilder(); realm.append("@").append(defaultRealm); if (!principal.endsWith(realm.toString())) { principalWithRealm.append(principal).append(realm); principal = principalWithRealm.toString(); } } return principal.equals(ugi.getUserName()); } /** * copy from hbase zkutil 0.94&0.98 A JAAS configuration that defines the * login modules that we want to use for login. */ private static class JaasConfiguration extends javax.security.auth.login.Configuration { private static final Map<String, String> BASIC_JAAS_OPTIONS = new HashMap<String, String>(); static { String jaasEnvVar = System.getenv("HBASE_JAAS_DEBUG"); if (jaasEnvVar != null && "true".equalsIgnoreCase(jaasEnvVar)) { BASIC_JAAS_OPTIONS.put("debug", "true"); } } private static final Map<String, String> KEYTAB_KERBEROS_OPTIONS = new HashMap<String, String>(); static { if (IS_IBM_JDK) { KEYTAB_KERBEROS_OPTIONS.put("credsType", "both"); } else { KEYTAB_KERBEROS_OPTIONS.put("useKeyTab", "true"); KEYTAB_KERBEROS_OPTIONS.put("useTicketCache", "false"); KEYTAB_KERBEROS_OPTIONS.put("doNotPrompt", "true"); KEYTAB_KERBEROS_OPTIONS.put("storeKey", "true"); } KEYTAB_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS); } private static final AppConfigurationEntry KEYTAB_KERBEROS_LOGIN = new AppConfigurationEntry( KerberosUtil.getKrb5LoginModuleName(), LoginModuleControlFlag.REQUIRED, KEYTAB_KERBEROS_OPTIONS); private static final AppConfigurationEntry[] KEYTAB_KERBEROS_CONF = new AppConfigurationEntry[] { KEYTAB_KERBEROS_LOGIN }; private javax.security.auth.login.Configuration baseConfig; private final String loginContextName; private final boolean useTicketCache; private final String keytabFile; private final String principal; public JaasConfiguration(String loginContextName, String principal, String keytabFile) throws IOException { this(loginContextName, principal, keytabFile, keytabFile == null || keytabFile.length() == 0); } private JaasConfiguration(String loginContextName, String principal, String keytabFile, boolean useTicketCache) throws IOException { try { this.baseConfig = javax.security.auth.login.Configuration.getConfiguration(); } catch (SecurityException e) { this.baseConfig = null; } this.loginContextName = loginContextName; this.useTicketCache = useTicketCache; this.keytabFile = keytabFile; this.principal = principal; initKerberosOption(); LOG.info("JaasConfiguration loginContextName=" + loginContextName + " principal=" + principal + " useTicketCache=" + useTicketCache + " keytabFile=" + keytabFile); } private void initKerberosOption() throws IOException { if (!useTicketCache) { if (IS_IBM_JDK) { KEYTAB_KERBEROS_OPTIONS.put("useKeytab", keytabFile); } else { KEYTAB_KERBEROS_OPTIONS.put("keyTab", keytabFile); KEYTAB_KERBEROS_OPTIONS.put("useKeyTab", "true"); KEYTAB_KERBEROS_OPTIONS.put("useTicketCache", useTicketCache ? "true" : "false"); } } KEYTAB_KERBEROS_OPTIONS.put("principal", principal); } public AppConfigurationEntry[] getAppConfigurationEntry(String appName) { if (loginContextName.equals(appName)) { return KEYTAB_KERBEROS_CONF; } if (baseConfig != null) return baseConfig.getAppConfigurationEntry(appName); return (null); } }}
阅读全文
0 0
- kerberos学习笔记
- Kerberos 认证原理笔记
- Kerberos协议学习报告
- Kerberos
- Kerberos
- Kerberos
- Kerberos
- Kerberos
- kerberos
- Kerberos
- kerberos
- Kerberos
- Kerberos
- Kerberos
- Kerberos
- 《tcp/ip 最佳入门》与Kerberos笔记
- Kerberos Hadoop Java代码原理学习
- Logstash output Kafka with Kerberos学习
- Android学习笔记16-JNI
- 字符设备驱动学习(1)
- * 24种设计模式——状态模式
- 1.C子空间
- 《零基础入门学习Python》学习过程笔记【36,37类】
- kerberos学习笔记
- SpringMVC使用JSR 303校验
- 畅通工程
- 最长公共子序列—C语言
- Python之道-爬虫1
- python的基础语法
- 常见集合类源码分析
- 重构和回流
- linux下ping加时间戳