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 */
018
019package org.apache.hadoop.hbase.security.token;
020
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.fs.Path;
023import org.apache.hadoop.hbase.HBaseTestingUtility;
024import org.apache.hadoop.hbase.LocalHBaseCluster;
025import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
026import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil;
027import org.apache.hadoop.hbase.security.HBaseKerberosUtils;
028import org.apache.hadoop.hbase.util.FSUtils;
029import org.apache.hadoop.hdfs.DFSConfigKeys;
030import org.apache.hadoop.http.HttpConfig;
031import org.apache.hadoop.minikdc.MiniKdc;
032import org.apache.hadoop.security.UserGroupInformation;
033import org.junit.AfterClass;
034import org.junit.BeforeClass;
035
036import java.io.File;
037
038/**
039 * The class for set up a security cluster with kerberos, hdfs, hbase.
040 */
041public class SecureTestCluster {
042  protected static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
043
044  protected static String USERNAME;
045
046  private static LocalHBaseCluster CLUSTER;
047
048  private static final File KEYTAB_FILE = new File(TEST_UTIL.getDataTestDir("keytab").toUri()
049      .getPath());
050  private static MiniKdc KDC;
051
052  private static String HOST = "localhost";
053
054  private static String PRINCIPAL;
055
056  private static String HTTP_PRINCIPAL;
057
058  /**
059   * Setup the security configuration for hdfs.
060   */
061  private static void setHdfsSecuredConfiguration(Configuration conf) throws Exception {
062    // change XXX_USER_NAME_KEY to XXX_KERBEROS_PRINCIPAL_KEY after we drop support for hadoop-2.4.1
063    conf.set(DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY, PRINCIPAL + "@" + KDC.getRealm());
064    conf.set(DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY, KEYTAB_FILE.getAbsolutePath());
065    conf.set(DFSConfigKeys.DFS_DATANODE_USER_NAME_KEY, PRINCIPAL + "@" + KDC.getRealm());
066    conf.set(DFSConfigKeys.DFS_DATANODE_KEYTAB_FILE_KEY, KEYTAB_FILE.getAbsolutePath());
067    conf.set(DFSConfigKeys.DFS_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY, HTTP_PRINCIPAL + "@"
068        + KDC.getRealm());
069    conf.setBoolean(DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_KEY, true);
070    conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name());
071    conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0");
072    conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0");
073
074    File keystoresDir = new File(TEST_UTIL.getDataTestDir("keystore").toUri().getPath());
075    keystoresDir.mkdirs();
076    String sslConfDir = KeyStoreTestUtil.getClasspathDir(TestGenerateDelegationToken.class);
077    KeyStoreTestUtil.setupSSLConfig(keystoresDir.getAbsolutePath(), sslConfDir, conf, false);
078
079    conf.setBoolean("ignore.secure.ports.for.testing", true);
080  }
081
082  /**
083   * Setup and start kerberos, hbase
084   */
085  @BeforeClass
086  public static void setUp() throws Exception {
087    KDC = TEST_UTIL.setupMiniKdc(KEYTAB_FILE);
088    USERNAME = UserGroupInformation.getLoginUser().getShortUserName();
089    PRINCIPAL = USERNAME + "/" + HOST;
090    HTTP_PRINCIPAL = "HTTP/" + HOST;
091    KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL, HTTP_PRINCIPAL);
092    TEST_UTIL.startMiniZKCluster();
093
094    HBaseKerberosUtils.setPrincipalForTesting(PRINCIPAL + "@" + KDC.getRealm());
095    HBaseKerberosUtils.setSecuredConfiguration(TEST_UTIL.getConfiguration());
096
097    setHdfsSecuredConfiguration(TEST_UTIL.getConfiguration());
098    UserGroupInformation.setConfiguration(TEST_UTIL.getConfiguration());
099    TEST_UTIL.getConfiguration().setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
100        TokenProvider.class.getName());
101    TEST_UTIL.startMiniDFSCluster(1);
102    Path rootdir = TEST_UTIL.getDataTestDirOnTestFS("TestGenerateDelegationToken");
103    FSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootdir);
104    CLUSTER = new LocalHBaseCluster(TEST_UTIL.getConfiguration(), 1);
105    CLUSTER.startup();
106  }
107
108  @AfterClass
109  public static void tearDown() throws Exception {
110    if (CLUSTER != null) {
111      CLUSTER.shutdown();
112    }
113    CLUSTER.join();
114    if (KDC != null) {
115      KDC.stop();
116    }
117    TEST_UTIL.shutdownMiniCluster();
118  }
119}