実稼働環境でのApacheHBaseの保護
HBaseは、GoogleBigTableを模倣した人気のある分散型Key-Valueストアです。HBaseは、非常に高速なルックアップ、高い書き込みスループット、および強力な一貫性をサポートできるため、ユースケースデータストレージ(Facebookメッセージングなど)から分析ユースケース(Yahoo Flurryなど)までのユースケースに適しています。HBaseはデータをHDFSに保存して、線形スケーリングとフォールトトレランスを提供します。
HDFSと同様に、Kerberos統合は、認証に有効なSPNを必要とするHBaseプロトコルにSASLベースの認証レイヤーを追加することで機能します。さらに、HBase自体は、データを格納するときにKerberosを使用してHDFSを認証します。HBaseは、ユニットレベルのアクセス制御をサポートし、非常に細かい認証レイヤーを提供します。
既存のHDPクラスターにKerberosを使用してApacheHBaseをインストールします
Kerberos対応のApacheHBaseをHDPクラスターにインストールできます。
始める前に
•Kerberosが有効になっているHDPクラスターが機能している必要があります。
•Kerberos管理者のアクセス権が必要です。
Kerberosを有効にしてHBaseをインストールするには、以下の手順に従ってください。
プログラム
1.Ambariにログインします。
2. [アクション]メニューから、[サービスの追加]をクリックします。
3.サービスのリストから[HBase]を選択し、[次へ]をクリックします。
4.HBaseマスターをインストールする場所を選択します。
5.HBaseリージョナルサーバーをインストールするノードを選択します。
6.構成の詳細を表示し、パフォーマンス調整のニーズに応じて変更して、[次へ]をクリックします。
後でサービスをカスタマイズすることもできます。
7. HBaseデプロイメント用に作成されるKerberosサービスプリンシパル名(SPN)を確認し、[次へ]をクリックします。
8.構成の詳細を表示し、[展開]をクリックします。
HDFSでKerberosが有効になっているときにKerberos管理者の資格情報が保存されていない場合、Ambariは
資格情報を再度入力するように求めます。
9.資格情報を入力したら、[保存]をクリックします。
10.インストールが完了するのを待ちます。
11.インストール中に発生したエラーを確認し、[次へ]をクリックします。
KerberosがHBaseに対して有効になっていることを確認します
以下の手順に従って、ApacheHBaseでKerberosが有効になっていることを確認してください。
手順
1.HBaseクライアントがインストールされているAmbariノードにログインします。
2.HBaseシェルを起動します。
3. HBaseマスターホストで、statusコマンドを実行します。
この例では、TGTがないため、コマンドはスタックトレースで失敗します。したがって、Kerberosを使用してHBaseへの認証を行うことはできません。
4.チケット付与チケット(TGT)を取得します。
次の例は、kinit操作の実行時にローカルTGTを作成するために使用される入力と出力を示しています。
最初の例では、最初にコマンドラインで「kinit」を実行してから、アプリケーションを実行します。2番目の例では、キーテーブルを介してTGTを自動的に取得します。
安全なクライアントの例1:
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();
}
}
チケットキャッシュ出力の例1:
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
- プリンシパルとキータブからログインして、statusコマンドを再実行してください。
keytabを使用してログインしたセキュアクライアントの例2:
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 = "[email protected]";
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;
}
});
}
}
次の例は、keytabを介してログインすることによって生成された出力を示しています。
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
Javaクライアントを使用してKerberos対応のHBaseクラスターにアクセスします
Javaクライアントを使用して、Kerberos対応のHBaseクラスターにアクセスできます。
始める前に
•Kerberosが有効になっているHDPクラスター。
•Java8、Maven 3、およびEclipse開発環境で作業しています。
•KerberosKDCへの管理者アクセス権があります。
次のタスクを実行して、Javaクライアントを使用してHBaseに接続し、テーブルに対して単純なPut操作を実行します。
プログラム
1.「構成のダウンロード」
2.「顧客アカウントのセットアップ」
3.「Javaクライアントを使用してKerberos対応のHBaseクラスターにアクセスする」
構成のダウンロード
以下の手順に従って、必要な構成をダウンロードしてください。
手順
1.Ambariから、HBaseファイルとHDFSファイルをconfディレクトリに抽出します。これにより、すべての構成の詳細が保存されます。
これらのファイルは、$ HBASE_CONF_DIRディレクトリの下に抽出する必要があります。ここで、$ HBASE_CONF_DIRは、HBase構成ファイルを格納するために使用されるディレクトリです。たとえば、/ etc / hbase / confです。
2. KDCから、krb5.confファイルを/etc/krb5.conからダウンロードします。構成の概要をディレクトリに配置することもできます。
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = HWFIELD.COM
default_ccache_name = KEYRING:persistent:%{
uid}
[realms]
HWFIELD.COM = {
kdc = ambud-hdp-3.field.hortonworks.com
admin_server = ambud-hdp-3.field.hortonworks.com
}
[domain_realm]
.hwfield.com = HWFIELD.COM
hwfield.com = HWFIELD.COM
クライアントアカウントを設定する
以下の手順に従って、クライアントのKerberosアカウントを設定し、HBaseでこのアカウントにアクセス許可を付与し
て、テーブルを作成、読み取り、および書き込みできるようにしてください。
手順
1.KDCにログインします。
2.ルートディレクトリに切り替えます。
3.kadmin.localを実行します。
$ sudo kadmin.local
kadmin.local: addprinc myself
WARNING: no policy specified for [email protected]; defaulting to no
policy
Enter password for principal "[email protected]":
Re-enter password for principal "[email protected]":
Principal "[email protected]" created.
kadmin.local: xst -k /etc/security/keytabs/myself.keytab -norandkey
myself
Entry for principal myself with kvno 1, encryption type aes256-cts-hmacsha1-96 added to keytab
WRFILE:/etc/security/keytabs/myself.keytab.
Entry for principal myself with kvno 1, encryption type aes128-cts-hmacsha1-96 added to keytab
WRFILE:/etc/security/keytabs/myself.keytab.
- キーテーブルファイルをconfディレクトリにコピーします。
- HBaseで権限を付与します。詳細については、アクセス制御リスト(ACL)用のHBaseの構成を参照してください。
klist -k /etc/security/keytabs/hbase.headless.keytab
オプションの手順:HBaseプロセスのみがキータブにアクセスできるように、キータブファイルを保護する必要があります。これは、コマンドを実行することで実行できます。
$>sudo chmod 700 /etc/security/keytabs/hbase.headless.keytab
$ kinit -kt /etc/security/keytabs/hbase.headless.keytab hbase
$ hbase shell
hbase(main):001:0> status
1 active master, 0 backup masters, 4 servers, 1 dead, 1.2500 average load
- ユーザーに管理者権限を付与します。このオプションをカスタマイズして、アカウントへのアクセスを制限することもできます。詳細については、https://hbase.apache.org/0.94/book/ hbase.accesscontrol.configuration.html#d1984e4744の
例を参照してください。
hbase(main):001:0> grant 'myself', 'C'
Javaクライアントの作成Javaクライアント
を作成するには、以下の手順に従ってください。
プログラム
1.Eclipseを起動します。
2.単純なMavenプロジェクトを作成します。
3.hbase-clientとhadoop-authの依存関係を追加します。
クライアントは、Hadoop UGIユーティリティクラスを使用して、keytabファイルを使用してKerberos認証を実行します。すべての操作がhbase-user2セキュリティコンテキストで実行されるようにコンテキストを設定します。次に、必要なHBase操作、つまりテーブルのチェック/作成、およびputおよびget操作の実行を実行します。
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>${hbase.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-aws</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
4.DNS解決を逆引きできるノードからHBaseJavaクライアントコードを実行します。
これはKerberos認証の一部です。したがって、HDPクラスターと同じDNSインフラストラクチャを共有しないコンピューターで実行すると、認証が失敗します。
5. Kerberos認証/キータブ/プリンシパルが実際に有効であるかどうかを確認するために、Javaから単純なKerberos認証を実行することもできます。これにより、JavaJAASとKerberosがどのように機能するかをある程度理解できます。
MavenShadeプラグインまたはMavenJarプラグインを使用して、依存関係をシッククライアントJARに自動的にパッケージ化することを強くお勧めします。Eclipseエクスポート関数を使用することもできますが、本番コードベースでこの関数を使用することはお勧めしません。