Configuring Authentication with Kerberos
Also available as:
PDF
loading table of contents...

Verify if kerberos is enabled for HBase

Follow these steps to verify, if kerberos is enabled for Apache HBase:

  1. Log in to the Ambari node where HBase client is installed.
  2. Start the HBase shell.
  3. On the HBase Master host machine, execute the status command:

    In this example, the command fails with a stack trace, because there is no TGT. therefore can’t authenticate to HBase using Kerberos.

  4. Get a Ticket Granting Ticket (TGT).

    Here are the examples that shows the input and the output for creating a local TGT when you run a kinit operation. In the first example, you run a `kinit` on the command line first and then run the application. The second example automatically obtains a TGT through a keytab.

    Examplen 1 of secure client:

    
    package com.hortonworks.hbase.examples;
    
    import java.io.IOException;
    import java.util.Objects;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.TableName;
    import org.apache.hadoop.hbase.client.Admin;
    import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
    import org.apache.hadoop.hbase.client.Connection;
    import org.apache.hadoop.hbase.client.ConnectionFactory;
    import org.apache.hadoop.hbase.client.Get;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.client.Result;
    import org.apache.hadoop.hbase.client.Table;
    import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * Write and read data from HBase, expects HBASE_CONF_DIR and HADOOP_CONF_DIR on the classpath and a valid Kerberos
     * ticket in a ticket cache (e.g. kinit).
     */
    public class ExampleSecureClient implements Runnable {
      private static final Logger LOG = LoggerFactory.getLogger(ExampleSecureClient.class);
      private static final TableName TABLE_NAME = TableName.valueOf("example_secure_client");
      private static final byte[] CF = Bytes.toBytes("f1");
    
      private final Configuration conf;
    
      public ExampleSecureClient(Configuration conf) {
        this.conf = Objects.requireNonNull(conf);
      }
    
      @Override public void run() {
        try (Connection conn = ConnectionFactory.createConnection(conf)) { 
          writeAndRead(conn, TABLE_NAME, CF);
          LOG.info("Success!");
        } catch (Exception e) {
          LOG.error("Uncaught exception running example", e);
          throw new RuntimeException(e);
        }
      }
    
      void writeAndRead(Connection conn, TableName tn, byte[] family) throws IOException {
        final Admin admin = conn.getAdmin();
    
        // Delete the table if it already exists
        if (admin.tableExists(tn)) {
          admin.disableTable(tn);
          admin.deleteTable(tn);
        }
    
        // Create our table
        admin.createTable(TableDescriptorBuilder.newBuilder(tn).setColumnFamily(
            ColumnFamilyDescriptorBuilder.of(family)).build());
    
        final Table table = conn.getTable(tn);
        Put p = new Put(Bytes.toBytes("row1"));
        p.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("value"));
        LOG.info("Writing update: row1 -> value");
        table.put(p);
    
        Result r = table.get(new Get(Bytes.toBytes("row1")));
        assert r.size() == 1;
        LOG.info("Read row1: {}", r);
      }
    
      public static void main(String[] args) {
        final Configuration conf = HBaseConfiguration.create();
        new ExampleSecureClient(conf).run();
      }
    }
    Example 1 of Ticket Cache output:
    2018-06-12 13:44:40,144 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    2018-06-12 13:44:40,975 INFO  [main] zookeeper.ReadOnlyZKClient: Connect 0x62e136d3 to my.fqdn:2181 with session timeout=90000ms, retries 6, retry interval 1000ms, keepAlive=60000ms
    2018-06-12 13:44:42,806 INFO  [main] client.HBaseAdmin: Started disable of example_secure_client
    2018-06-12 13:44:44,159 INFO  [main] client.HBaseAdmin: Operation: DISABLE, Table Name: default:example_secure_client completed
    2018-06-12 13:44:44,590 INFO  [main] client.HBaseAdmin: Operation: DELETE, Table Name: default:example_secure_client completed
    2018-06-12 13:44:46,040 INFO  [main] client.HBaseAdmin: Operation: CREATE, Table Name: default:example_secure_client completed
    2018-06-12 13:44:46,041 INFO  [main] examples.ExampleSecureClient: Writing update: row1 -> value
    2018-06-12 13:44:46,183 INFO  [main] examples.ExampleSecureClient: Read row1: keyvalues={row1/f1:q1/1528825486175/Put/vlen=5/seqid=0}
    2018-06-12 13:44:46,183 INFO  [main] examples.ExampleSecureClient: Success!
    2018-06-12 13:44:46,183 INFO  [main] client.ConnectionImplementation: Closing master protocol: MasterService
    2018-06-12 13:44:46,183 INFO  [main] zookeeper.ReadOnlyZKClient: Close zookeeper connection 0x62e136d3 to my.fqdn:2181
    
  5. Execute the status command again by logging in through principal and keytab.

    Example 2 of secure client with keytab login:

    
    package com.hortonworks.hbase.examples;
    
    import java.io.File;
    import java.security.PrivilegedAction;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.security.UserGroupInformation;
    
    public class ExampleSecureClientWithKeytabLogin {
    
      public static void main(String[] args) throws Exception {
        final Configuration conf = HBaseConfiguration.create();
    
        final String principal = "myself@EXAMPLE.COM";
        final File keytab = new File("/etc/security/keytabs/myself.keytab");
    
        assert keytab.isFile() : "Provided keytab '" + keytab + "' is not a regular file.";
    
        UserGroupInformation.setConfiguration(conf);
        UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(
            principal, keytab.getAbsolutePath());
    
        ugi.doAs(new PrivilegedAction<Void>() {
          @Override public Void run() {
            new ExampleSecureClient(conf).run();
            return null;
          }
        });
      }
    }
    

    The following example shows the output resulting from the keytab login:

    2018-06-12 13:29:23,057 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    2018-06-12 13:29:23,574 INFO  [main] zookeeper.ReadOnlyZKClient: Connect 0x192d43ce to my.fqdn:2181 with session timeout=90000ms, retries 6, retry interval 1000ms, keepAlive=60000ms
    2018-06-12 13:29:29,172 INFO  [main] client.HBaseAdmin: Started disable of example_secure_client
    2018-06-12 13:29:30,456 INFO  [main] client.HBaseAdmin: Operation: DISABLE, Table Name: default:example_secure_client completed
    2018-06-12 13:29:30,702 INFO  [main] client.HBaseAdmin: Operation: DELETE, Table Name: default:example_secure_client completed
    2018-06-12 13:29:33,005 INFO  [main] client.HBaseAdmin: Operation: CREATE, Table Name: default:example_secure_client completed
    2018-06-12 13:29:33,006 INFO  [main] examples.ExampleSecureClient: Writing update: row1 -> value
    2018-06-12 13:29:33,071 INFO  [main] examples.ExampleSecureClient: Read row1: keyvalues={row1/f1:q1/1528824573066/Put/vlen=5/seqid=0}
    2018-06-12 13:29:33,071 INFO  [main] examples.ExampleSecureClient: Success!
    2018-06-12 13:29:33,071 INFO  [main] client.ConnectionImplementation: Closing master protocol: MasterService
    2018-06-12 13:29:33,071 INFO  [main] zookeeper.ReadOnlyZKClient: Close zookeeper connection 0x192d43ce to my.fqdn:2181