Kerberos認証とは何なのか

今まで当たり前のように使ってきたがあまり理解できてなかったのでまとめる。

## Kerberos認証って何？
Kerberos認証はサーバ-クライアント間の認証方法の一つで、**シングルサインオン**の一種である。

## シングルサインオンて何？
例えば複数のサーバから成るシステムがあるとする。
ユーザ（クライアント）である僕たちはそれぞれのサーバにログインするたびにパスワード入力したりして認証を通さないといけない。
サーバが一つならそれでいいんだけど、サーバの数が増えてくると毎回認証するのがしんどくなってくる。

**一回認証すれば全部のサーバ使えるようにしくてれない？**

というのがシングルサインオンの考え方。
簡単にログインできるという**利便性**以外にも認証情報を一元管理できるという**セキュリティ**上のメリットもある。


## Kerberosの仕組み
Kerberos認証では一番最初にパスワードなどの認証情報を入力することでチケットを発行してもらえる。
そしてチケットを見せることで**他のサーバにパスワードを入力しなくても楽々ログインできる**ようになる。
これらの認証情報を一元管理しているデータベースを`KDC (Key Distribution Center)`という。
KDCに認証をしてほしいユーザやサーバ（つまり僕たち）のことを`プリンシパル （Principal）`という。
僕たちが認証情報をKDC側に送ると、KDC側では`AS (Authentication Server)`という認証サーバが受け付けてくれて、`TGS（Ticket Granting Server)`と呼ばれるサーバがチケットを発行してくれる。
KDC配下のドメインは`レルム(realm)`と呼ばれる単位で管理されていてFDQN（hogehoge.comみたいなの）がよく用いられる。

認証手順は以下の画像のようになっている。
出典：https://www.infraexpert.com/study/security18.html

![スクリーンショット 2021-03-19 15.40.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547532/80108c60-66e1-f8d7-2df9-db88331b9849.png)

まず、ユーザはIDやパスワードなどの認証情報を入力する。
これらの情報はASで受け取ったあとにTGSがチケット発行のものになる`TGT (TIcket Grating Ticket)`というのを発行してくれる。
今、ログインしたいファイルサーバAがあったとする。
ユーザはこのTGTを見せることで「**こいつはファイルサーバAの認証チケット発行してもいい信用できるやつだ**」
という認識をしてもらい、サーバA用のチケットを発行してもらえる。
サーバB、サーバCなど次々アクセスした場合も毎回裏側ではこれらの処理が行われていることになるが、ユーザからすると
「**一回パスワード入力したらあとはABC全部ログインできるようになったぞ！**」
という状態になる。
なので、ユーザ側はこのあたりの手続きを毎回意識しなくても良い。


## 初期設定
クライアント側の設定。
Kerberos認証を行うにはkinitコマンドを使う。
CentOSの場合は

``` bash
$ yum install -y krb5-workstation krb5-libs
```
などと打ってinstallを行うことでkinitが使えるようになる。
krb5というのは現在使われているKerberosバージョン5を指している。
KDCなどのクライアント側の設定は`krb5.conf`で設定する。
参考：https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system-level_authentication_guide/configuring_a_kerberos_5_client

``` bash:/etc/krb5.conf
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = EXAMPLE.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 allow_weak_crypto = true

[realms]
  EXAMPLE.COM = {
  kdc = kdc.example.com.:88
  admin_server = kdc.example.com
  default_domain = example.com
 }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
```

ドメインやレルム、デフォルトの設定などを行っている。

## kinitコマンド (passwordを使う)

``` bash
$ kinit
```
とコマンドを打つとパスワードを要求されるので、パスワードを入力すれば認証を通すことができる。

``` bash
$ klist
```
で発行してもらったチケットを確認できる。
オプションとして

- -l 一覧表示
- -A すべて表示


など。
他にもいっぱいあるが割愛。
チケットには期限が設定されており、24hで失効するケースが多い。
チケットを破棄する場合は

``` bash
$ kdestroy
```
を打てば良い。

## kinitコマンド (keytabを使う)
kinitにはもう一つkeytabを使った方法がある。
keytabとは暗号化された鍵ペアなどの認証情報が含まれたファイルで、事前にこれを作成しとけばパスワード入力の代わりに使える。

``` bash
$ kinit -Vkt ${keytab_path}/hoge.keytab <user>@<realm>
```

`-kt`というオプションをつけてその後にkeytabのpathを入れればkeytabを使った認証をしてくれる。
厳密には

- k：keytabを使うよというオプション
- t：keytabを使う場合にfilenameをその後に指定するよというオプション

なのだけど、セットで覚えちゃって良い気がする。
`-V`はV：verbose (詳細)という意味で、つけとくと詳細な結果をいろいろ出力してくれる。
最後に(認証したいユーザ名)@(realm)の形式で入力する。
@以下を省略するとデフォルトのrealmが適用される。
## キャッシュ
kinitには他に `-c`というオプションがあり、これを指定するとキャッシュの名前を指定することができる。
キャッシュはデフォルトだと`krb5cc_<uid>`みたいな名前で保存され、毎回そのキャッシュを読みに行くことで認証が可能になる。
キャッシュの名前は`KRB5CCNAME`で環境変数として指定することもでき、

``` bash
export KRB5CCNAME='DIR:/tmp/krb/
```
などと`DIR:`をつけることでディレクトリを指定することもできる。
これによりディレクトリ内部に複数のキャッシュを用意して認証を使い分けしたりできるようになる。
逆に特別なことをしないのであれば特に気にせずデフォルトのキャッシュで良い。


## まとめ

- kerberos認証を使う上でとりあえず知っとくべきことをまとめた
- あくまでクライアントとして使う上での設定なので、ゼロから全部構築する場合はもっといろいろ必要なはず