Cloudera Manager によるクラスタのKerberos化

# はじめに
[Cloudera Manager Advent Calendar](http://qiita.com/advent-calendar/2015/cm) の25日目です。

本番はKerberosを使ってセキュアにしている、という環境も増えていると思いますが、自分で検証用の環境を構築するとなるとKerberosの構成が面倒だったりして手元でセキュアクラスタを構築するということはまだあまりないのかなと思います。

また、Sentryなどがユースケースに合うかを確認したいという場合にも検証のための環境を用意するのが面倒だと二の足を踏むということもあると思います。
今回は動作の検証のためにセキュアクラスタの環境を構築したい、という場合を想定したKerberos化について説明していきます。
principalとパスワードが同じだったりとセキュアクラスタなのにセキュアではない構成なので今回の内容はあくまで動作検証のためのもので本番環境を想定したものではない点は注意してください。


# 検証環境と前提
- 検証環境は CentOS6.6
- 使用したバージョンは Clouera Manager/CDH 5.5.1
- Cloudera Manager ServerのノードにKDCと認証サーバを構築
- デプロイメントの全ノードが対象になるのでクラスタが一つだけある環境で実施すること
- 作業はrootユーザで実施
- Cloudera Managerのユーザ/パスワードは admin

# 作業
## Linux 側の作業

検証用のKerberos設定スクリプト [krb-bootstrap](https://github.com/daisukebe/krb-bootstrap) を使ってKDCと認証サーバを構成したあと、各ノードでクライアントのインストール、という流れになっています。


````
#!/bin/sh

BASE=http://localhost:7180/api/v8
USERNAME="admin"
USERPASS="admin"
nodes=$(curl -X GET -u "$USERNAME:$USERPASS" -i $BASE/hosts | grep hostname | awk -F'"' '{print $4}')

# install KDC/krb5.conf
yum -y install git; git clone https://github.com/daisukebe/krb-bootstrap.git; cd krb-bootstrap; ./configure_krb5.sh

# install client and deply krb5.conf
for i in $(echo $nodes | cut -d' ' -f2-);do ssh $i yum -y install krb5-workstation; scp /etc/krb5.conf $i:/etc ;done
````

上記が終了すれば用意ができたことになります。
[krb-bootstrap](https://github.com/daisukebe/krb-bootstrap)スクリプトが何をしているかについてはlink先のReadmeを見てみてください。

## Cloudera Manager 側の作業
ここからは設定ウィザードの進め方について説明していきます。

まずはセキュリティメニューを選択します

------
![1-sec.png](https://qiita-image-store.s3.amazonaws.com/0/58396/cdab9199-a360-e0c0-965b-51db69af144e.png)
------
対象クラスタのEnable Kerberosボタンからウィザードを開始します

------
![2-kerberise.png](https://qiita-image-store.s3.amazonaws.com/0/58396/95dff50a-672c-c215-7801-f06b8f5c51dc.png)
------

前提条件の確認です。前述のLinux側の作業が完了していれば全てチェックして次に進んでください

------
![3-firstquestions.png](https://qiita-image-store.s3.amazonaws.com/0/58396/731453c0-9f5c-5662-cdc8-39d1c3d3325b.png)
------
Kerberos側の設定情報を聞かれますので下記のように設定してください
KDC サーバホスト: Cloudera Manager Serverをインストールしたノードのhostname
Kerberos セキュリティのレルム: HADOOP ([krb-bootstrap](https://github.com/daisukebe/krb-bootstrap) で指定しているもの)

------
![4-realm.png](https://qiita-image-store.s3.amazonaws.com/0/58396/fa5c3320-b47d-1913-4436-734aaa4b0314.png)
------

Linux側の作業内で手動でkrb5.confを配布しているのでチェックしなくても大丈夫です

------
![5-krbconf.png](https://qiita-image-store.s3.amazonaws.com/0/58396/fc5f46ae-8f06-6bae-9965-8d729d6e131d.png)
------
Adminユーザの情報を下記のように入力してください
ユーザ名: cloudera-scm/admin
パスワード: cloudera
共に[krb-bootstrap](https://github.com/daisukebe/krb-bootstrap) で指定している内容です

------
![6-userpass.png](https://qiita-image-store.s3.amazonaws.com/0/58396/06b5866b-f37e-8051-eb6e-1549e995a3bb.png)
------
各サービスで使用する Principalの設定です。変更する必要はありません

------
![7-comp.png](https://qiita-image-store.s3.amazonaws.com/0/58396/060e53ac-4246-9f81-7f20-afb6f5c7fd54.png)
------

こちらも値を変更する必要はありません
クラスタの再起動についてチェックして進んでください

------
![8-port.png](https://qiita-image-store.s3.amazonaws.com/0/58396/d18959f9-8e55-324d-fdf2-b25196faf21b.png)
------

コマンドが実行されていきますので終了まで待ってください

------
![9-command.png](https://qiita-image-store.s3.amazonaws.com/0/58396/ce9ba62e-5ccd-fdf5-6f78-e2d2871c9b76.png)
------

ここまで終了すれば完了の画面が表示されて終了です

ケルベロス化されていればセキュリティから下記のように状況を確認できます。

------
![10-kerberized.png](https://qiita-image-store.s3.amazonaws.com/0/58396/90e395cd-756e-6d81-027a-1d01b37b300d.png)
------

# 構築後
Kerberos化されていれば下記のようにOSユーザではなく、kinitで認証したprincipalでコマンドを実行できるようになります。
下記でのhdfs@HADOOPのパスワードはhdfsになります。

````
[root@n1 ~]# kinit hdfs
Password for hdfs@HADOOP:
[root@n1 ~]# hdfs dfs -ls /user/history
Found 2 items
drwxrwx---   - mapred hadoop          0 2015-12-25 11:17 /user/history/done
drwxrwxrwt   - mapred hadoop          0 2015-12-25 11:17 /user/history/done_intermediate
````

逆にOSのhdfsユーザであってもprincipalとして認証がされなければ下記のようにエラーになることも確認できます。

````
[root@n1 ~]# sudo -u hdfs hdfs dfs -ls /user/history
15/12/25 15:57:29 WARN security.UserGroupInformation: PriviledgedActionException as:hdfs (auth:KERBEROS) cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
15/12/25 15:57:29 WARN ipc.Client: Exception encountered while connecting to the server : javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
15/12/25 15:57:29 WARN security.UserGroupInformation: PriviledgedActionException as:hdfs (auth:KERBEROS) cause:java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
ls: Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]; Host Details : local host is: "n1.lab.cloudera.com/10.17.81.194"; destination host is: "n1.lab.cloudera.com":8020;
````

Sentryを使う場合には[こちら](http://hdif.tumblr.com/post/104400949099/apache-sentryで始めるアクセス制御-hive編)が参考になります。
Hive, Impalaを使う場合には是非試してみてください。
(impalaのprincipal は今回の手順では作っていないので検証時には `echo "addprinc -pw impala impala" | kadmin.local` などのようにして作ってください)

# おわりに
いかがでしたでしょうか。

動くものがあるかどうかで大分敷居が下がると思います。検証環境などでクラスタを構成できる、という場合には是非試してみてください。

下記は参考までにCloudera Manager側の作業をAPIでやってみた例です。

````
wget https://gist.githubusercontent.com/azurecube/040aa92d8da605e68a28/raw/83218685ab0f8ab16407c53f0e856cb7dc771155/cm_kerberize.sh
bash cm_kerberize.sh
````

セキュアクラスタのファーストステップ、もしくは検証の敷居が少しでも低くなれば幸いです。