001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security; 019 020import java.io.File; 021import java.io.IOException; 022import java.net.InetAddress; 023 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.fs.CommonConfigurationKeys; 026import org.apache.hadoop.hbase.HBaseConfiguration; 027import org.apache.hadoop.hbase.HBaseTestingUtility; 028import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil; 029import org.apache.hadoop.hdfs.DFSConfigKeys; 030import org.apache.hadoop.http.HttpConfig; 031import org.apache.hadoop.yarn.conf.YarnConfiguration; 032import org.apache.yetus.audience.InterfaceAudience; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035import org.apache.hbase.thirdparty.com.google.common.base.Strings; 036import org.apache.hadoop.security.UserGroupInformation; 037 038@InterfaceAudience.Private 039public class HBaseKerberosUtils { 040 private static final Logger LOG = LoggerFactory.getLogger(HBaseKerberosUtils.class); 041 042 public static final String KRB_PRINCIPAL = "hbase.regionserver.kerberos.principal"; 043 public static final String MASTER_KRB_PRINCIPAL = "hbase.master.kerberos.principal"; 044 public static final String KRB_KEYTAB_FILE = "hbase.regionserver.keytab.file"; 045 046 public static boolean isKerberosPropertySetted() { 047 String krbPrincipal = System.getProperty(KRB_PRINCIPAL); 048 String krbKeytab = System.getProperty(KRB_KEYTAB_FILE); 049 if (Strings.isNullOrEmpty(krbPrincipal) || Strings.isNullOrEmpty(krbKeytab)) { 050 return false; 051 } 052 return true; 053 } 054 055 public static void setPrincipalForTesting(String principal) { 056 setSystemProperty(KRB_PRINCIPAL, principal); 057 } 058 059 public static void setKeytabFileForTesting(String keytabFile) { 060 setSystemProperty(KRB_KEYTAB_FILE, keytabFile); 061 } 062 063 public static void setSystemProperty(String propertyName, String propertyValue) { 064 System.setProperty(propertyName, propertyValue); 065 } 066 067 public static String getKeytabFileForTesting() { 068 return System.getProperty(KRB_KEYTAB_FILE); 069 } 070 071 public static String getPrincipalForTesting() { 072 return System.getProperty(KRB_PRINCIPAL); 073 } 074 075 public static Configuration getConfigurationWoPrincipal() { 076 Configuration conf = HBaseConfiguration.create(); 077 conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); 078 conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos"); 079 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true); 080 return conf; 081 } 082 083 public static Configuration getSecuredConfiguration() { 084 Configuration conf = HBaseConfiguration.create(); 085 setSecuredConfiguration(conf); 086 return conf; 087 } 088 089 /** 090 * Set up configuration for a secure HDFS+HBase cluster. 091 * @param conf configuration object. 092 * @param servicePrincipal service principal used by NN, HM and RS. 093 * @param spnegoPrincipal SPNEGO principal used by NN web UI. 094 */ 095 public static void setSecuredConfiguration(Configuration conf, 096 String servicePrincipal, String spnegoPrincipal) { 097 setPrincipalForTesting(servicePrincipal); 098 setSecuredConfiguration(conf); 099 setSecuredHadoopConfiguration(conf, spnegoPrincipal); 100 } 101 102 public static void setSecuredConfiguration(Configuration conf) { 103 conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); 104 conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos"); 105 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true); 106 conf.set(KRB_KEYTAB_FILE, System.getProperty(KRB_KEYTAB_FILE)); 107 conf.set(KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)); 108 conf.set(MASTER_KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)); 109 } 110 111 private static void setSecuredHadoopConfiguration(Configuration conf, 112 String spnegoServerPrincipal) { 113 // if we drop support for hadoop-2.4.0 and hadoop-2.4.1, 114 // the following key should be changed. 115 // 1) DFS_NAMENODE_USER_NAME_KEY -> DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY 116 // 2) DFS_DATANODE_USER_NAME_KEY -> DFS_DATANODE_KERBEROS_PRINCIPAL_KEY 117 String serverPrincipal = System.getProperty(KRB_PRINCIPAL); 118 String keytabFilePath = System.getProperty(KRB_KEYTAB_FILE); 119 // HDFS 120 conf.set(DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY, serverPrincipal); 121 conf.set(DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY, keytabFilePath); 122 conf.set(DFSConfigKeys.DFS_DATANODE_USER_NAME_KEY, serverPrincipal); 123 conf.set(DFSConfigKeys.DFS_DATANODE_KEYTAB_FILE_KEY, keytabFilePath); 124 conf.setBoolean(DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_KEY, true); 125 // YARN 126 conf.set(YarnConfiguration.RM_PRINCIPAL, KRB_PRINCIPAL); 127 conf.set(YarnConfiguration.NM_PRINCIPAL, KRB_PRINCIPAL); 128 129 if (spnegoServerPrincipal != null) { 130 conf.set(DFSConfigKeys.DFS_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY, 131 spnegoServerPrincipal); 132 } 133 134 conf.setBoolean("ignore.secure.ports.for.testing", true); 135 136 UserGroupInformation.setConfiguration(conf); 137 } 138 139 /** 140 * Set up SSL configuration for HDFS NameNode and DataNode. 141 * @param utility a HBaseTestingUtility object. 142 * @param clazz the caller test class. 143 * @throws Exception if unable to set up SSL configuration 144 */ 145 public static void setSSLConfiguration(HBaseTestingUtility utility, Class clazz) 146 throws Exception { 147 Configuration conf = utility.getConfiguration(); 148 conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name()); 149 conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0"); 150 conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0"); 151 152 File keystoresDir = new File(utility.getDataTestDir("keystore").toUri().getPath()); 153 keystoresDir.mkdirs(); 154 String sslConfDir = KeyStoreTestUtil.getClasspathDir(clazz); 155 KeyStoreTestUtil.setupSSLConfig(keystoresDir.getAbsolutePath(), sslConfDir, conf, false); 156 } 157 158 public static UserGroupInformation loginAndReturnUGI(Configuration conf, String username) 159 throws IOException { 160 String hostname = InetAddress.getLocalHost().getHostName(); 161 String keyTabFileConfKey = "hbase." + username + ".keytab.file"; 162 String keyTabFileLocation = conf.get(keyTabFileConfKey); 163 String principalConfKey = "hbase." + username + ".kerberos.principal"; 164 String principal = org.apache.hadoop.security.SecurityUtil 165 .getServerPrincipal(conf.get(principalConfKey), hostname); 166 if (keyTabFileLocation == null || principal == null) { 167 LOG.warn("Principal or key tab file null for : " + principalConfKey + ", " 168 + keyTabFileConfKey); 169 } 170 UserGroupInformation ugi = 171 UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keyTabFileLocation); 172 return ugi; 173 } 174}