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