AsiaBSDCon 2014 Tutorial

Kerberos 認証サービスの設定と運用
佐藤 広生 <hrs@allbsd.org>
東京工業大学 / FreeBSD Project
2014/3/13

2014/3/13 (c) Hiroki Sato

終わるまでに理解できる内容• 「認証」「認可」とは？
• Kerberos 認証サービスの原理と構造• KDC の構築 (kdc, kadmind, kpasswdd)• Kerberos 認証のアプリケーション設定• login• OpenSSH• BIND (GSS-TSIG)• Apache (HTTP Basic Auth, SPNEGO)• 複数のKDCの同期 (hprop, ipropd)
2014/3/13 (c) Hiroki Sato

認証と認可• UNIX の伝統的な認証・認可の仕組み• /etc/passwd• hrs:$1$EhW6tUdUn3q.:20001:20001::0:0:Hiroki

home/hrs:/bin/tcsh• UID とパスワードハッシュの一致でログイン可否を決定

2014/3/13 (c) Hiroki Sato

Sato:/

認証と認可• 認証 (Authentication)• 「本当にその UID の持ち主かどうか」を判断する処理• 方法：「本人しか知らない情報」と「UID」のペア

情報を知っているかチェック• 例：共通鍵の事前共有 (pre-shared key)

秘密鍵・公開鍵ペアの一致を見る
二要素認証（情報を増やす）

2014/3/13 (c) Hiroki Sato

認証と認可• 認可 (Authorization)• 「その資源を使って良いかどうか」を判断する処理• 方法：「使って良い人リスト」（認可データベース）と「UID」の照合

2014/3/13 (c) Hiroki Sato

認証と認可• 違いはどこ？
• 認証と認可の身近な例：パスポート• 「パスポートを持っている」＝「本人である」ことの証明• 「パスポートを持っている」！＝「出国・入国が保証される」• 入出国は、犯罪者リスト等の別の情報と照合する• パスポートは、本人であることを証明するだけ

2014/3/13 (c) Hiroki Sato

認証と認可• /etc/passwd の認証・認可• 「パスワードハッシュが一致する」＝「UID の持ち主」• 認可は？
• ポイント：/etc/passwd が認可データベースも兼ねている• 認証される＝認可される• そもそもそんな区別は必要なのか？

2014/3/13 (c) Hiroki Sato

認証と認可• 認証・認可の区別がないと困ること• 認可のたびに認証が必要• ログインしてから、コマンドを打つたびにパスワードが必要だったら？
• 認証されたこと（＝そのUIDの正当な持ち主であること）を保持しておくことで面倒を回避• ログイン：プロセスの所有者がUIDと一致するので、子プロセスは自動的にUIDを引き継ぐ

2014/3/13 (c) Hiroki Sato

認証と認可• 認証・認可の区別がないと困ること• ログインプロセスのUIDだけで十分か？
• リモートシステムに対しては使えない• ウェブページを開くたびにパスワードを入れる？
• メールにアクセスするたびにパスワードを入れる？

2014/3/13 (c) Hiroki Sato

認証と認可• 認証・認可の区別がないと困ること• 使う人が同じなら、認証は本来一回で良い。
• 認可は、使いたい資源ごとに判断される必要がある。
• 区別がないと、不要な認証を何度もやらなければならない

2014/3/13 (c) Hiroki Sato

Kerberos が目指すもの• 信頼できる「認証」を提供するサービス• 政府がパスポートを発行するようなイメージ• 持ち主の氏名と国籍を保証する• パスポートを持ってて何ができるかは、政府は保証しない

2014/3/13 (c) Hiroki Sato

Kerberos が目指すもの• メリット• 認証データベースを一元化できる• たくさんのマシンにパスワードハッシュが分散しない• マシンをセットアップしたら、Kerberos に対応させてUIDを登録するだけで、パスワードハッシュがなくてもログイン可能• セキュリティの向上• 認証を使い回しできる（シングルサインオン）• リモートログインのたびにパスワードを打鍵しなくて良い2014/3/13 (c) Hiroki Sato

SSH じゃダメなの？
• システム管理者で SSH を知らないひとはいない（はず）• Kerberos なんか要らんのでは？

2014/3/13 (c) Hiroki Sato

SSH じゃダメなの？
• 最後に .ssh/authorized_keys を編集したのはいつ？

2014/3/13 (c) Hiroki Sato

SSH じゃダメなの？
• 公開鍵認証の欠点：revocation が難しい
• PKI には CRL (Certification Revocation List) がある。
• OpenSSH には KRL (Key Revocation lists) と RevokedKeys オプションがある。

% ssh-keygen -k -f /etc/ssh/revoke_keys -z 1 /path/pubkey.pub% ssh-keygen -u —k -f /etc/ssh/revoke_keys -z 2 /path/pubkey.pub• 多数のホストに authorized_keys ファイルのコピーをつくると、

revoke は困難

2014/3/13 (c) Hiroki Sato

Kerberos 認証の構造• 歴史と特徴• MIT の Project Athena（実体は分散システムの開発）で1980 年代に開発されたリモート認証プロトコル• 目標：種類の違う数千台規模のマシンの認証を効率的に管理• 手段：• パスワード情報を一元化（認証サーバ）• 認証を再利用できるように（認証チケット）• 現在普及しているOSのほとんどが Kerberos の技術を利用

2014/3/13 (c) Hiroki Sato

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• 共通鍵暗号を使った、安全な認証システムの構築方法• Kerberos 認証の根幹

AS

hostA
user1
2014/3/13 (c) Hiroki Sato

TGS

hostB
user2

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• シナリオ：hostA の user1 が hostB にログインしたい

AS

hostA
user1
2014/3/13 (c) Hiroki Sato

TGS

hostB
user2

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• 前提：すべての要素は、鍵（パスワード）を持っている• 前提：AS（認証サーバ）は、鍵（パスワード）をすべて持っている
user1 の鍵

hostA の鍵

TGS の鍵ASTGS の鍵TGS

hostB の鍵

user1 の鍵

2014/3/13 (c) Hiroki Sato

hostA
user1

hostA の鍵

hostB
user2

hostB の鍵

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• なぜか？
• 事前登録されていることを使って信頼性を構築

AS

hostA
user1
2014/3/13 (c) Hiroki Sato

TGS

hostB
user2

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• ステップ：user1 が AS に認証要求を出す• 認証要求は、「名前 “user1” とサービス名 “TGS”」で出す

AS

TGS

AS_REQ
hostA
user1
2014/3/13 (c) Hiroki Sato

hostB
user2

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• ステップ：AS は、user1 に初期チケットを返す• 初期チケットは、TGS へのアクセスに使う

AS

TGS

user1-TGS 間通信用暗号鍵

AS_REP"user1" と "TGS" とuser1-TGS 暗号鍵
hostA
user1
2014/3/13 (c) Hiroki Sato

hostB
user2

user1 の鍵で暗号化

TGS の鍵で暗号化

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• ステップ：AS は、user1 に初期チケットを返す• 初期チケットは、TGS へのアクセスに使う

AS

TGS

user1-TGS
session key
hostA
user1

TGSの鍵

AS_REP
user1 の鍵

2014/3/13 (c) Hiroki Satouser1-TGS
session key
hostB
user2

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• ステップ：AS は、user1 に初期チケットを返す• 初期チケットは、TGS へのアクセスに使う

AS

TGS

user1-TGS
session key
hostA
user1

TGSの鍵

AS_REP
user1 の鍵

2014/3/13 (c) Hiroki Satouser1-TGS
session key
hostB
user2

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1 の鍵（パスワード）で暗号化した部分は、user1 なら戻せる• TGS の鍵（パスワード）で暗号化した部分は、TGS でしか戻せない

AS

TGS

user1-TGS
session key
hostA
user1

TGSの鍵

AS_REP
user1 の鍵

2014/3/13 (c) Hiroki Satouser1-TGS
session key
hostB
user2

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1 の鍵（パスワード）で暗号化した部分は、user1 なら戻せる• TGS の鍵（パスワード）で暗号化した部分は、TGS でしか戻せない

user1 の鍵

AS

TGS

user1-TGS
session key
hostA

TGSの鍵

user1
2014/3/13 (c) Hiroki Sato

この2つが手に入る

user1-TGS
session keyhostB

user2

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1-TGS 間通信用暗号鍵を使ってTGSと暗号通信開始• チケットの残りと、サービス要求をTGS へ送信

AS

TGS

TGS_REQ
hostBの名前

hostA
user1
2014/3/13 (c) Hiroki Satouser1-TGS
session key
TGSの鍵

user1の名前
hostB

TGSの名前user2
user1-TGS
session key

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1-TGS 間通信用暗号鍵を使ってTGSと暗号通信開始• この時点で、user1 であることが確実に検証できる

AS

TGS

TGS_REQ
hostBの名前

hostA
user1
2014/3/13 (c) Hiroki Satouser1-TGS
session key
TGSの鍵

user1の名前
hostB

TGSの名前user2
user1-TGS
session key

user1の名前

TGSの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1-TGS 間通信用暗号鍵を使ってTGSと暗号通信開始• hostB との通信に使う暗号鍵と、要求内容が入ったデータを受信

AS

TGS

TGS_REP
user1-TGS
session key

2014/3/13 (c) Hiroki Satouser1-hostB
session key

hostA
user1

hostBの鍵

user1-hostB
session key

hostB
user2

user1の名前

hostBの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• これで user1-hostB 間の暗号鍵が手に入った！
• hostB への通信を開始

AS

TGS

TGS_REP
user1-TGS
session key

2014/3/13 (c) Hiroki Satouser1-hostB
session key

hostA
user1

hostBの鍵

user1-hostB
session key

hostB
user2

user1の名前

hostBの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• user1 であることの証明• user1-hostB の通信用の正しい暗号鍵

AS

TGS

Service_REQ
hostA
user1
2014/3/13 (c) Hiroki Satouser1-hostB
session key

user1の名前

hostBの鍵

user1-hostB
session keyhostB

user2

user1の名前

hostBの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• hostB は、両方の鍵を持っているので復元できる• 復元できる＝認証成功！

AS

TGS

Service_REQ
hostA
user1
2014/3/13 (c) Hiroki Satouser1-hostB
session key

user1の名前

hostBの鍵

user1-hostB
session keyhostB

user2

user1の名前

hostBの名前

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• 念のため逆方向にもチェック（タイムスタンプ＋１を送る）

AS

TGS

user1-hostB
session key
hostA
user1
2014/3/13 (c) Hiroki Satotime + 1

hostB
user2

Kerberos 認証の構造• キーとなる技術: Needham-Schroeder 共通鍵プロトコル• まとめ：user1 が hostB にログインするには、5 工程必要
• サーバ側(hostB)は、ASにもTGSにもアクセスしていない！

AS

AS_REQ

AS_REPTGSTGS_REQTGS_REP
Service_REQ

hostA
user1
2014/3/13 (c) Hiroki Sato

hostB
user2

Kerberos 認証の構造• 必要な要素• AS：認証データベース• TGS：認証を再利用するためのデータ（チケット）を配る• チケットをサーバに送るだけで、

user1であることを確認できる！

2014/3/13 (c) Hiroki Sato

Kerberos 認証の構造• 実際の実装• KDC = AS +TGS（鍵配布センター）• 認証データベースを保持して、TGSの機能も持つ

ネットワークデーモン• クライアントは KDC を• /etc/krb5.conf にある IP アドレスから探す• DNS の SRV RR を見て探す• Kerberos 対応のソフトウェアでないと、この認証は使われない• PAM を使って KDC を使うように変えることは可能
2014/3/13 (c) Hiroki Sato

Kerberos 認証の構造• もう一度復習• 認証サーバ・チケット配布サーバ：KDC• 鍵（パスワード）を全部知ってるサーバ• 認証クライアント（2者関係）• 主体はユーザ、アプリケーション、など• それぞれ鍵（パスワード）を持っている• 例：リモートログインの場合• 「ユーザ」と「対象ホスト」

2014/3/13 (c) Hiroki Sato

5分休憩
• 後半は設定です2014/3/13 (c) Hiroki Sato

設定方法
• KDC の構築
• kdc デーモン• kadmind デーモン• kpasswdd デーモン• クライアントの設定• login• OpenSSH• BIND• Apache2014/3/13 (c) Hiroki SatoKDC の構築• Kerberos の実装: MIT Kerberos と KTH Heimdal が有名• FreeBSD は KTH Heimdal がベースに入っている• /usr/libexec/kdc: KDC デーモン• /var/heimdal: KDC が認証データベースを置くところ• /etc/krb5.conf: クライアント用設定ファイル• /etc/krb5.keytab: デフォルト鍵ファイル

2014/3/13 (c) Hiroki SatoKDC の構築• ステップ• レルム(realm)を決める• マスタ鍵生成• 管理用プリンシパルを追加• kdc デーモンを起動• kadmind デーモンを起動

2014/3/13 (c) Hiroki SatoKDC の構築• １：レルムを決めて kadmin -l init
• レルム＝ドメイン名のようなもの（一致させても良い）• 全部大文字にするのが普通• このコマンドで認証データベース/var/heimdal/heimdal.dbが初期化# kadmin -l init ALLBSD.ORG

2014/3/13 (c) Hiroki SatoKDC の構築• １：レルムを決めて kadmin -l init
• レルム＝ドメイン名のようなもの（一致させても良い）• 全部大文字にするのが普通• このコマンドで認証データベース/var/heimdal/heimdal.dbが初期化• ２：マスタ鍵を kadmin -l stash で設定# kadmin -l stash
Master key:
Verifying - Master key:kadmin: writing key to "/var/heimdal/m-key"

2014/3/13 (c) Hiroki SatoKDC の構築• マスタ鍵：/var/heimdal/m-key• 認証データベース：/var/heimdal/heimdal.db• マスタ鍵＝認証データベースの暗号鍵• root 以外は読めないように注意すること！

# kadmin -l init ALLBSD.ORG
Realm max ticket life [unlimited]:
Realm max renewable ticket life [unlimited]:# kadmin -l stash
Master key:
Verifying - Master key:kadmin: writing key to "/var/heimdal/m-key"

2014/3/13 (c) Hiroki SatoKDC の構築• ３：管理用プリンシパルを追加

kadmin -l add hrs/admin@ALLBSD.ORG• 典型的には UID/admin や UID/root という名前にする• 「プリンシパル」とは、鍵を持つユーザ名やホスト名を指す用語• 鍵とプリンシパルは1:1関係# kadmin -l add hrs/admin@ALLBSD.ORG
Max ticket life [1 day]:Max renewable life [1 week]:
Principal expiration time [never]:Password expiration time [never]:Attributes []:hrs/admin@ALLBSD.ORG's Password:
Verifying - hrs/admin@ALLBSD.ORG's Password:

2014/3/13 (c) Hiroki SatoKDC の構築• ４：kdc と kadmind と kpasswdd を起動• rc.conf に書く• 分かりにくいので、近々変えます…

kerberos5_server_enable="YES"
kadmind5_server_enable="YES"
kpasswdd_server_enable="YES"# service kerberos start# service kadmind start# service kpasswdd start

2014/3/13 (c) Hiroki SatoKDC の構築• ４：kdc と kadmind と kpasswdd を起動• rc.conf に書く• 分かりにくいので、近々変えます…
• （↓）こうなる予定

kdc_enable=“YES"kadmind_enable="YES"
kpasswdd_enable="YES"

2014/3/13 (c) Hiroki SatoKDC の構築• ５：kadmind の ACL を設定• kadmind は、KDC と同じマシンで動かす• 認証データベースの操作を行うためのデーモン• 認証にはもちろんKerberosを使う• 認可（誰がアクセスできるのか）を決めておかないといけない

2014/3/13 (c) Hiroki SatoKDC の構築• ５：kadmind の ACL を設定• kadmind は、KDC と同じマシンで動かす• 認証データベースの操作を行うためのデーモン• 認証にはもちろんKerberosを使う• 認可（誰がアクセスできるのか）を決めておかないといけない• /var/heimdal/kadmind.acl に書く• 書式：プリンシパル
hrs/admin@ALLBSD.ORG all *2014/3/13 (c) Hiroki Satoアクション

対象プリンシパル

クライアントの設定• クライアント設定に必要なもの• KDCの場所• デフォルトレルム• サービスプリンシパル名と鍵• kadmind の例

2014/3/13 (c) Hiroki Sato

kadmind• KDCの場所• クライアントは KDC の場所を知らない• デフォルトレルム設定• プリンシパル名を hrs とした時に、hrs@ALLBSD.ORG と解釈する• いつも @ 以降を書くなら、なくても動く• どちらも /etc/krb5.conf か DNS に設定

2014/3/13 (c) Hiroki Sato

/etc/krb5.conf• すべてのクライアントに必要• kadmind, kpasswdd のデーモンの場所も書ける[libdefaults]
default_realm = ALLBSD.ORG[realms]
ALLBSD.ORG = {kdc = 192.168.2.1:88
admin_server = 192.168.2.1:749
kpasswd_server = 192.168.2.1:464}
2014/3/13 (c) Hiroki SatoDNS
• SRV RR に指定• 優先順位を指定して複数書ける• kadmind は _kerberos-adm._tcp を使う• デフォルトレルム名は、_kerberos に TXT で定義_kerberos._tcp_kerberos._udp_kerberos._tcp_kerberos._udp

SRV
SRV
SRV
SRV

10 1 88 kdc.allbsd.org.
10 1 88 kdc.allbsd.org.
20 1 88 kdc2.allbsd.org.
20 1 88 kdc2.allbsd.org.

_kpasswd._udp_kerberos-adm._tcp_kerberos

SRV
SRV
TXT

10 1 464 kdc.allbsd.org.
10 1 749 kdc.allbsd.org.
"ALLBSD.ORG"

2014/3/13 (c) Hiroki Sato

どちらが良いか？
• DNS が管理できるなら、SRV RR を使うほうが圧倒的に楽• /etc/krb5.conf は空でOK

2014/3/13 (c) Hiroki Sato

kadmind• kdc, kadmind, kpasswdd の起動# service kerberos start# service kadmind start# service kpasswdd start• /etc/rc.conf の編集を忘れずに

2014/3/13 (c) Hiroki Sato

kadmind• kadmin をリモートから使ってみる% kadmin -p hrs/admin add hrs@ALLBSD.ORG
hrs/admin@ALLBSD.ORG's Password:
Max ticket life [1 day]:Max renewable life [1 week]:
Principal expiration time [never]:Password expiration time [never]:Attributes []:• hrs/admin@ALLBSD.ORG で認証して、KDCデータベースを編集

2014/3/13 (c) Hiroki Sato

kadminユーティリティ• プリンシパルの追加% kadmin -p hrs/admin add hrs@ALLBSD.ORG• プリンシパルの削除% kadmin -p hrs/admin delete hrs@ALLBSD.ORG• プリンシパルの表示% kadmin -p hrs/admin get hrs@ALLBSD.ORG• プリンシパル属性情報の変更% kadmin -p hrs/admin modify hrs@ALLBSD.ORG• 鍵の取り出し% kadmin -p hrs/admin ext_keytab -k /tmp/keytab hrs@ALLBSD.ORG

2014/3/13 (c) Hiroki Satokpasswdユーティリティ• passwd(1) と同じように、プリンシパルのパスワードを変更できる% kpasswd hrs/admin@ALLBSD.ORG

2014/3/13 (c) Hiroki Sato

注意
• Kerberos はリプレイ攻撃を防ぐため、タイムスタンプを使う• 時刻が合ってないと動きません• NTPをちゃんと設定しましょう• DDoS の標的にならないように！

2014/3/13 (c) Hiroki Sato

5分休憩
• 次は個々のクライアントアプリケーションへの応用です。

2014/3/13 (c) Hiroki Sato

OpenSSH• リモートログインに使ってみよう• 復習• Kerberos は 2 者間の認証を行う• 認証をする主体には必ず鍵があり、KDCは全部の鍵を持っている• リモートログインの主体は「ユーザ」と「ホスト」

2014/3/13 (c) Hiroki Sato

OpenSSH
host/hostA.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

リモートアクセス

hostA.allbsd.org
host/hostA.allbsd.org@ALLBSD.ORG
hrs@ALLBSD.ORG

ユーザプリンシパル
2014/3/13 (c) Hiroki Sato

hostB.allbsd.org
host/hostB.allbsd.org@ALLBSD.ORG

ホストプリンシパル

OpenSSH• ステップ• hostBにホスト鍵をつくってKDCに登録。
• OpenSSHに、Kerberosを使うように設定。
• OpenSSHの認可データベースをチェック。

2014/3/13 (c) Hiroki Sato

OpenSSH• ホストプリンシパルの生成と登録
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

ktutilhostA.allbsd.org

hostB.allbsd.org
host/hostB.allbsd.org@ALLBSD.ORG

2014/3/13 (c) Hiroki Sato

OpenSSH• ホストプリンシパルの生成と登録• KDC と hostB の両方の置かないといけない• /etc/krb5.keytab を使う（root だけが読める）• コマンド一発# ktutil get -p hrs/admin host/`hostname`@ALLBSD.ORG• ポイント• ホストプリンシパルには「host/FQDN@realm」という名前を付ける。
• /etc/krb5.keytab はrootで書き込むので、root権限で実行すること。

2014/3/13 (c) Hiroki Sato

OpenSSH• ktutil ユーティリティ• ローカルの鍵ファイルを管理するためのツール• ちゃんとできてるか確認# ktutil list
FILE:/etc/krb5.keytab:
Vno
1
1
1
1
1
1

Type
des-cbc-md5
des-cbc-md4
des-cbc-crc
aes256-cts-hmac-sha1-96
des3-cbc-sha1
arcfour-hmac-md5

2014/3/13 (c) Hiroki Sato

Principal
host/hostB.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

Aliases

OpenSSH• OpenSSH の設定• GSSAPIAuthentication=yes を追加（サーバ・クライアントの両方）• /etc/ssh/sshd_config• /etc/ssh/ssh_config• $HOME/.ssh/config• /etc/rc.conf• 他に設定の必要なし

2014/3/13 (c) Hiroki Sato

OpenSSH• 使ってみよう• まずはユーザプリンシパルの指定% kinit
hrs@ALLBSD.ORG's Password:% klistCredentials cache: FILE:/tmp/krb5cc_20001
Principal: hrs@ALLBSD.ORG
IssuedMar 13 05:24:40 20142014/3/13 (c) Hiroki Sato

Expires
Mar 13 15:24:40 2014

Principal
krbtgt/ALLBSD.ORG@ALLBSD.ORG

OpenSSH• 使ってみよう• kinit: ユーザ鍵を使ってTGTを取ってくる操作。

一回行うと、以降の認証はパスワードの入力が不要に。

• klist: 自分の持っているチケットを表示するコマンド% kinit
hrs@ALLBSD.ORG's Password:% klistCredentials cache: FILE:/tmp/krb5cc_20001
Principal: hrs@ALLBSD.ORG
IssuedMar 13 05:24:40 20142014/3/13 (c) Hiroki Sato

Expires
Mar 13 15:24:40 2014

Principal
krbtgt/ALLBSD.ORG@ALLBSD.ORG

OpenSSH• もう一回復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

hostA.allbsd.org
krbtgt/ALLBSD.ORG@ALLBSD.ORG

2014/3/13 (c) Hiroki Sato

hostB.allbsd.org
host/hostB.allbsd.org@ALLBSD.ORG

OpenSSH• もう一回復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

kinit

hostA.allbsd.org
krbtgt/ALLBSD.ORG@ALLBSD.ORG

hostB.allbsd.org
host/hostB.allbsd.org@ALLBSD.ORG

TGTはKDCから他のチケットを取るのに必要
2014/3/13 (c) Hiroki Sato

OpenSSH• もう一回復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

OpenSSH
hostB.allbsd.org

hostA.allbsd.org

チケット
hrs@ALLBSD.ORG

2014/3/13 (c) Hiroki Satokrbtgt/ALLBSD.ORG@ALLBSD.ORG
sessionkey

host/hostB.allbsd.org@ALLBSD.ORG

host/hostB.allbsd.org@ALLBSD.ORG
sessionkey

OpenSSH• もう一回復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

OpenSSH
hostA.allbsd.org

2014/3/13 (c) Hiroki Sato

hostB.allbsd.org

krbtgt/ALLBSD.ORG@ALLBSD.ORG

host/hostB.allbsd.org@ALLBSD.ORG

sessionkey

host/hostB.allbsd.org@ALLBSD.ORG

sessionkey

セッション鍵を送る

OpenSSH• もう一回復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
host/hostB.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

sessionkey

hostA.allbsd.org

OpenSSH hostB.allbsd.org

krbtgt/ALLBSD.ORG@ALLBSD.ORG

2014/3/13 (c) Hiroki Satosessionkey

host/hostB.allbsd.org@ALLBSD.ORG

OpenSSH• 使ってみよう• あとはいつもどおり ssh でアクセス% ssh -4v hostB.allbsd.org
OpenSSH_6.3, OpenSSL 1.0.1e-freebsd 11 Feb 2013
debug1: Reading configuration data /home/hrs/.ssh/config. . .
debug1: Connecting to hostB.allbsd.org [192.168.2.2] port 22.
debug1: Connection established.
. . .
debug1: Authentications that can continue: publickey,gssapi-with-mic
debug1: Next authentication method: gssapi-with-mic
debug1: Delegating credentials
debug1: Delegating credentials
debug1: Authentication succeeded (gssapi-with-mic).
Authenticated to hostB.allbsd.org ([192.168.2.2]:22).

2014/3/13 (c) Hiroki Sato

覚えておくべきこと• 認証が必要なのは kinit でTGTを取得する時だけ• TGTは /tmp/krb5cc_${UID} に保存される。

場所を変えることも可能( KRB5CCNAME)• TGTには有効期限があり、切れると要パスワード再入力

2014/3/13 (c) Hiroki Sato

OpenSSH• 認可はどうやってやるの？
• 指定しないと、Kerberos 認証できたユーザは全員ログインできる• AllowUsers, AllowGroups オプションを使いましょう• プリンシパル名とUIDとの対応は、~/.k5login というファイルを使う% cat ~/.k5login
hrs@ALLBSD.ORG
foo@ALLBSD.ORG• foo@ALLBSD.ORG のチケットを持っているユーザは、

ssh hrs@hostB.allbsd.org でログインできる• root ユーザでログインしたい場合などに使うことが多い

2014/3/13 (c) Hiroki Sato

OpenSSH• ssh-agent のようなことはできる？
• ログイン先にチケットを転送する機能がある• ssh に GSSAPIDlegateCredentials=yes を設定（デフォルトはno）

2014/3/13 (c) Hiroki Sato

OpenSSH• 公開鍵認証と何が違うのか• ホストプリンシパルとユーザプリンシパルによる認証• ちゃんと登録されていないと認証されない• パスワードの revoke が確実にできる• 置き換えるものではなく、適材適所

2014/3/13 (c) Hiroki Sato

login• ローカルログインでも使ってみよう• PAMを使って、認証先を切り替える% cat /etc/pam.d/system# authauthsufficientauthrequisiteauthsufficient#authsufficientauthrequirednullokpam_opie.so
pam_opieaccess.so
pam_krb5.so
pam_ssh.so
pam_unix.so

no_warn no_fake_prompts
no_warn allow_local
no_warn try_first_pass
no_warn try_first_pass
no_warn try_first_pass• 注意：ホストプリンシパルがないと認証が成功しません！

2014/3/13 (c) Hiroki Sato

login• ログインしただけで、自動的にTGTを取ってくれる
login: hrs
Password:. . .
% klistCredentials cache: FILE:/tmp/krb5cc_20001
Principal: hrs@ALLBSD.ORG
IssuedMar 13 06:08:39 2014
Mar 13 06:08:39 20142014/3/13 (c) Hiroki Sato

Expires
Mar 13 16:08:39 2014
Mar 13 16:08:39 2014

Principal
host/hostB.allbsd.org@ALLBSD.ORG
krbtgt/ALLBSD.ORG@ALLBSD.ORG

BIND• TSIG認証をkerberosで行うことが可能• ここで問題• 今までの例は、kinit を手動で使っていた• TSIG認証はサーバ間で使うこともあるが、どうやって設定するの？
• nsupdate を使った例

2014/3/13 (c) Hiroki Sato

BIND
• もう一度復習
krbtgt/ALLBSD.ORG@ALLBSD.ORG
DNS/ns.allbsd.org@ALLBSD.ORG

hrs@ALLBSD.ORG

KDC

ktutilhostA.allbsd.org

ns.allbsd.org
DNS/ns.allbsd.org@ALLBSD.ORG

2014/3/13 (c) Hiroki Sato

BIND
• BIND は、サービスプリンシパルとして

host/FQDN ではなく「DNS/FQDN」を使う• このプリンシパルは、named しか使わないので、/etc/krb5.keytab ではな

く、別のファイル /etc/namedb/named.keytab に保存する# ktutil -k /etc/namedb/named.keytab get —p hrs/admin DNS/`hostname`# chown bind /etc/namedb/named.keytab

2014/3/13 (c) Hiroki Sato

BIND
• BIND の DDNS に GSS-TSIG を設定する• options セクションに tkey-gssapi-keytab• zone セクションに grant 文を入れる
options {tkey-gssapi-keytab "/etc/namedb/named.keytab";};zone “allbsd.org” {. . .
update-policy {grant hrs@ALLBSD.ORG wildcard * ANY;
grant "DNS/ns.allbsd.org@ALLBSD.ORG" wildcard * ANY;};}

2014/3/13 (c) Hiroki SatoBIND
• クライアント• kinit して TGT を取得• nsupdate -g を実行（もしくは gsstsig コマンドを実行）
gsstsig
realm ALLBSD.ORG
server 133.31.130.32
local 133.31.130.32
zone hrslab.org.
update add www.hrslab.org. 600 A 133.31.130.32
show
send

2014/3/13 (c) Hiroki Sato

BIND
• nsupdate を自動でやりたい。たとえば cron で kinit するには？
• 鍵をあらかじめKDCから取り出しておけば良い• 注意：サービス単位で鍵をつくり、鍵を守ること。
% kadmin ext_keytab -k /tmp/foo.keytab foo@ALLBSD.ORG% kinit -t /tmp/foo.keytab （パスワードは不要）• ↑ の kinit を crontab に書けば無人で動く

2014/3/13 (c) Hiroki Sato

ここまでで学んだこと• Kerberos を使うには、

使う側・サービス側の両方のプリンシパルが必要• SSH はユーザとホストプリンシパル(host/FQDN)• BIND はユーザとサービスプリンシパル(DNS/FQDN)• 「どのプリンシパルを使うのか」はマニュアルに書いてある• サービス側には認可データベースがある• 認証された後、サービスを許可するかどうか• SSHは何も設定しなければ/etc/passwdにあるかどうかだけを見る• 時刻同期が重要
2014/3/13 (c) Hiroki Sato

ここまでで学んだこと• プリンシパルの鍵は、KDCから取り出すことができる• 取り出すと、パスワードは要らなくなる• kinit するのと、鍵を取り出すのとは違う• 実はサービスプリンシパルの大半は取り出して使っている• SSH サーバは/etc/krb5.keytab を読んでいる• BINDの例では /etc/namedb/named.keytab を使った
• パスワードレスで使いたい時には取り出す• 盗まれると終わるので、取り扱いは十分注意

2014/3/13 (c) Hiroki Sato

Apache, curl
• HTTPの認証をKerberosで• HTTP Basic 認証を KDC のパスワードで行う• SPNEGO: 最もまともな Kerberos 認証 over HTTP

2014/3/13 (c) Hiroki Sato

Apache, curl
• Apache の設定• mod_auth_kreb を追加し、AuthTypeを Kerberos にする• サービスプリンシパルとして HTTP/FQDNをつくる必要あり• この例では /usr/local/etc/httpd.keytab に置いている

LoadModule auth_kerb_module

libexec/apache22/mod_auth_kerb.so

AuthType Kerberos
Authname "Kerberos Login"
KrbAuthRealms ALLBSD.ORG
KrbServiceName HTTP/www.allbsd.org
Krb5Keytab /usr/local/etc/httpd.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd off

2014/3/13 (c) Hiroki Sato

Apache, curl
• curl でアクセスしてみる% curl —negotiate http://hrs@www.allbsd.org• ユーザ名の指定が必要

2014/3/13 (c) Hiroki Sato

Apache, curl
• Apache の設定• KrbMethodNegotiate を off にし、KrbMethodK5Passwd を on にすると、単なるパスワード認証になる

LoadModule auth_kerb_module

libexec/apache22/mod_auth_kerb.so

AuthType Kerberos
Authname "Kerberos Login"
KrbAuthRealms ALLBSD.ORG
KrbServiceName HTTP/www.allbsd.org
Krb5Keytab /usr/local/etc/httpd.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd off

2014/3/13 (c) Hiroki SatoKDC 運用• KDC のログはどうやって管理すれば？
• KDC が落ちると認証できない• パケットフィルタの設定は？

2014/3/13 (c) Hiroki Satoログ
• デフォルトのログ• /var/heimdal/kdc.log• syslog (INFO)• あまり使いやすくないので、全部 syslog に飛ばすのが良い/etc/krb5.conf[logging]
kdc = SYSLOG
kadmind = SYSLOG
kpasswdd = SYSLOG
default = SYSLOG/etc/syslog.conf!kdc,kadmind,kpasswdd*.*

2014/3/13 (c) Hiroki Sato/var/log/kdc.log

スレーブサーバ• KDC が落ちると認証できない → スレーブサーバをつくる• 方法は2つ: hprop （全転送）と iprop（差分転送）• iprop のほうが新しい• ステップ• KDCを同じマスタ暗号鍵でつくる• データベースを同期させる

2014/3/13 (c) Hiroki Sato

iprop 同期の設定• マスタ鍵が同じKDCをつくる• kadmin -l init した後に m-key をマスタから手動でコピー• サービスプリンシパルをつくる• iprop/<マスタホスト名>• iprop/<スレーブホスト名>• 認可データベースをつくる（サーバのみ）• /var/heimdal/slaves• スレーブのプリンシパル名を行単位で書く

2014/3/13 (c) Hiroki Sato

iprop 同期の設定• ipropd-master を起動（サーバ）• ipropd-slave を起動（クライアント）• 2121/tcp で通信して同期# /usr/libexec/ipropd-master —detach# /usr/libexec/ipropd-slave —detach ＜マスタサーバのホスト名＞• /usr/libexec/ipropd-master と /usr/libexec/ipropd-slave（rc.d/ipropd_master, rc.d/ipropd_slave を追加する予定）

2014/3/13 (c) Hiroki Sato

iprop 同期の設定• クライアントの接続状況は、/var/heimdal/slaves-stats に記録される• 接続が切れても根気よく再接続を試みる# cat /var/heimdal/slaves-stats
Status for slaves, last updated: 2014-03-13T11:18:48
Master version: 157
Name
iprop/hrshome.allbsd.org@ALLBSD.ORG

Address
IPv4:192.168.2.4

Version
157 Up• 運用上の注意• YAT message のログ（サーバ側）は無視して良し

2014/3/13 (c) Hiroki Sato

Status Last Seen
2014-03-13T11:18:18

スレーブサーバ• KDC が 2 つになったら• SRV RR を追加する• /etc/krb5.conf に kdc= 行を追加する• あとは自動的にフェイルオーバする

2014/3/13 (c) Hiroki Sato

通信の詳細• 使うポート番号まとめ• kdc: 88/tcp, 88/udp• kpasswdd: 464/tcp• kadmind: 749/tcp• ipropd-master: 2121/tcp• NATを越えることは可能• HTTP プロキシを使うことも可能• /etc/krb5.conf に指定（相互運用性は高くない）[libdefaults]
http_proxy = http://proxy.allbsd.org/

2014/3/13 (c) Hiroki Sato

簡単な運用方法• KDC 側• kdc, kadmind, kpasswdd を起動する• SRV RR に、レルム名とサービスIPアドレスを指定する• クライアント側• SRV RR があれば、kinit するだけで良い• PAM を使って kinit させるのが簡単
authaccount

2014/3/13 (c) Hiroki Satosufficientrequired

pam_krb5.so
pam_krb5.so

no_warn try_first_pass

簡単な運用方法• SSH の公開鍵認証と組み合わせて適材適所• 新しいマシンを追加しても、パスワードハッシュを追加する

必要性を極力抑えることができる。
• 鍵の revoke が確実にできる。
• 数百台のマシンに authorized_keys ファイルをコピーする、

なんてのは悪夢です。

• ホスト鍵が登録されている相手しか認証は成功しないので、KDC上の鍵を潰せば、すべての鍵は無効に

2014/3/13 (c) Hiroki Sato

さらなる応用は？
• Kerberos のバックエンドデータベースをLDAP化• LDAP認証と統合できる• ActiveDirectory は KDC + LDAP
• UNIX から KDC として使うことも可能 （Sambaなど）• 他のアプリケーション• アプリケーションが GSSAPI に対応しているかどうか調べよう• 対応していれば、Kerberos で認証できる可能性が高い• SASL は GSSAPI を使うことができる

2014/3/13 (c) Hiroki Sato

おしまい
• 質問はありますか？

2014/3/13 (c) Hiroki Sato