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.AuthUtil; 027import org.apache.hadoop.hbase.HBaseConfiguration; 028import org.apache.hadoop.hbase.HBaseTestingUtility; 029import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil; 030import org.apache.hadoop.hdfs.DFSConfigKeys; 031import org.apache.hadoop.http.HttpConfig; 032import org.apache.hadoop.yarn.conf.YarnConfiguration; 033import org.apache.yetus.audience.InterfaceAudience; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036import org.apache.hbase.thirdparty.com.google.common.base.Strings; 037import org.apache.hadoop.security.UserGroupInformation; 038 039@InterfaceAudience.Private 040public class HBaseKerberosUtils { 041 private static final Logger LOG = LoggerFactory.getLogger(HBaseKerberosUtils.class); 042 043 public static final String KRB_PRINCIPAL = SecurityConstants.REGIONSERVER_KRB_PRINCIPAL; 044 public static final String MASTER_KRB_PRINCIPAL = SecurityConstants.MASTER_KRB_PRINCIPAL; 045 public static final String KRB_KEYTAB_FILE = SecurityConstants.REGIONSERVER_KRB_KEYTAB_FILE; 046 public static final String CLIENT_PRINCIPAL = AuthUtil.HBASE_CLIENT_KERBEROS_PRINCIPAL; 047 public static final String CLIENT_KEYTAB = AuthUtil.HBASE_CLIENT_KEYTAB_FILE; 048 049 public static boolean isKerberosPropertySetted() { 050 String krbPrincipal = System.getProperty(KRB_PRINCIPAL); 051 String krbKeytab = System.getProperty(KRB_KEYTAB_FILE); 052 if (Strings.isNullOrEmpty(krbPrincipal) || Strings.isNullOrEmpty(krbKeytab)) { 053 return false; 054 } 055 return true; 056 } 057 058 public static void setPrincipalForTesting(String principal) { 059 setSystemProperty(KRB_PRINCIPAL, principal); 060 } 061 062 public static void setKeytabFileForTesting(String keytabFile) { 063 setSystemProperty(KRB_KEYTAB_FILE, keytabFile); 064 } 065 066 public static void setClientPrincipalForTesting(String clientPrincipal) { 067 setSystemProperty(CLIENT_PRINCIPAL, clientPrincipal); 068 } 069 070 public static void setClientKeytabForTesting(String clientKeytab) { 071 setSystemProperty(CLIENT_KEYTAB, clientKeytab); 072 } 073 074 public static void setSystemProperty(String propertyName, String propertyValue) { 075 System.setProperty(propertyName, propertyValue); 076 } 077 078 public static String getKeytabFileForTesting() { 079 return System.getProperty(KRB_KEYTAB_FILE); 080 } 081 082 public static String getPrincipalForTesting() { 083 return System.getProperty(KRB_PRINCIPAL); 084 } 085 086 public static String getClientPrincipalForTesting() { 087 return System.getProperty(CLIENT_PRINCIPAL); 088 } 089 090 public static String getClientKeytabForTesting() { 091 return System.getProperty(CLIENT_KEYTAB); 092 } 093 094 public static Configuration getConfigurationWoPrincipal() { 095 Configuration conf = HBaseConfiguration.create(); 096 conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); 097 conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos"); 098 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true); 099 return conf; 100 } 101 102 public static Configuration getSecuredConfiguration() { 103 Configuration conf = HBaseConfiguration.create(); 104 setSecuredConfiguration(conf); 105 return conf; 106 } 107 108 /** 109 * Set up configuration for a secure HDFS+HBase cluster. 110 * @param conf configuration object. 111 * @param servicePrincipal service principal used by NN, HM and RS. 112 * @param spnegoPrincipal SPNEGO principal used by NN web UI. 113 */ 114 public static void setSecuredConfiguration(Configuration conf, 115 String servicePrincipal, String spnegoPrincipal) { 116 setPrincipalForTesting(servicePrincipal); 117 setSecuredConfiguration(conf); 118 setSecuredHadoopConfiguration(conf, spnegoPrincipal); 119 } 120 121 public static void setSecuredConfiguration(Configuration conf) { 122 conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); 123 conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos"); 124 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true); 125 conf.set(KRB_KEYTAB_FILE, System.getProperty(KRB_KEYTAB_FILE)); 126 conf.set(KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)); 127 conf.set(MASTER_KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)); 128 } 129 130 private static void setSecuredHadoopConfiguration(Configuration conf, 131 String spnegoServerPrincipal) { 132 // if we drop support for hadoop-2.4.0 and hadoop-2.4.1, 133 // the following key should be changed. 134 // 1) DFS_NAMENODE_USER_NAME_KEY -> DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY 135 // 2) DFS_DATANODE_USER_NAME_KEY -> DFS_DATANODE_KERBEROS_PRINCIPAL_KEY 136 String serverPrincipal = System.getProperty(KRB_PRINCIPAL); 137 String keytabFilePath = System.getProperty(KRB_KEYTAB_FILE); 138 // HDFS 139 conf.set(DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY, serverPrincipal); 140 conf.set(DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY, keytabFilePath); 141 conf.set(DFSConfigKeys.DFS_DATANODE_USER_NAME_KEY, serverPrincipal); 142 conf.set(DFSConfigKeys.DFS_DATANODE_KEYTAB_FILE_KEY, keytabFilePath); 143 conf.setBoolean(DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_KEY, true); 144 // YARN 145 conf.set(YarnConfiguration.RM_PRINCIPAL, KRB_PRINCIPAL); 146 conf.set(YarnConfiguration.NM_PRINCIPAL, KRB_PRINCIPAL); 147 148 if (spnegoServerPrincipal != null) { 149 conf.set(DFSConfigKeys.DFS_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY, 150 spnegoServerPrincipal); 151 } 152 153 conf.setBoolean("ignore.secure.ports.for.testing", true); 154 155 UserGroupInformation.setConfiguration(conf); 156 } 157 158 /** 159 * Set up SSL configuration for HDFS NameNode and DataNode. 160 * @param utility a HBaseTestingUtility object. 161 * @param clazz the caller test class. 162 * @throws Exception if unable to set up SSL configuration 163 */ 164 public static void setSSLConfiguration(HBaseTestingUtility utility, Class clazz) 165 throws Exception { 166 Configuration conf = utility.getConfiguration(); 167 conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name()); 168 conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0"); 169 conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0"); 170 171 File keystoresDir = new File(utility.getDataTestDir("keystore").toUri().getPath()); 172 keystoresDir.mkdirs(); 173 String sslConfDir = KeyStoreTestUtil.getClasspathDir(clazz); 174 KeyStoreTestUtil.setupSSLConfig(keystoresDir.getAbsolutePath(), sslConfDir, conf, false); 175 } 176 177 public static UserGroupInformation loginAndReturnUGI(Configuration conf, String username) 178 throws IOException { 179 String hostname = InetAddress.getLocalHost().getHostName(); 180 String keyTabFileConfKey = "hbase." + username + ".keytab.file"; 181 String keyTabFileLocation = conf.get(keyTabFileConfKey); 182 String principalConfKey = "hbase." + username + ".kerberos.principal"; 183 String principal = org.apache.hadoop.security.SecurityUtil 184 .getServerPrincipal(conf.get(principalConfKey), hostname); 185 if (keyTabFileLocation == null || principal == null) { 186 LOG.warn("Principal or key tab file null for : " + principalConfKey + ", " 187 + keyTabFileConfKey); 188 } 189 UserGroupInformation ugi = 190 UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keyTabFileLocation); 191 return ugi; 192 } 193}