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