%%Title: Heimdalを使ってみる
%%Created: Mon Oct 20 19:00:14 JST 2003
%%Updated: Wed May 26 14:29:55 JST 2004
Heimdal
o Heimdalのインストール
FreeBSD4.9に Heimdalをインストールしてみる。
NOTE:
pkg_add(8)やportsから普通にインストールすると/usr/localの
ftpとかtelnetが置き換わるので注意する。
# pkg_add -p /usr/local/heimdal -rv heimdal-0.6.tgz
とかして、/etc/rc.confのldconfig_pathsに/usr/local/heimdalを追加して、
# ldconfig $ldconfig_paths しといてもいい。
以下の暗号がサポートされている
des-cbc-crc
des-cbc-md4
des-cbc-md5
des3-cbc-sha1
以下のプログラムがインストールされる
/usr/local/sbin
dump_log: kdcのログをダンプする
kadmin # マスターデータベース管理プログラム
kstash
ktutil
replay_log # log_fileを読んで履歴を再実行する
truncate_log # log_fileを削除する
/usr/local/libexec
kdc # KDCプログラム
ipropd-master # incremental propagationサーバ
ipropd-slave # incremental propagationクライアント
kpasswdd # ユーザが鍵を変更するためのデーモン
hprop # slaveサーバにデータを転送するプログラム
hpropd # slaveサーバ用デーモン
kfd # キャッシュを転送するためのデーモン
kadmind # 遠隔からkadmin(8)するためのデーモン
ftpd
popper
push
rshd
telnetd
/usr/local/bin
kinit # TGT取得プログラム
kauth # 実体は kinit
klist # キャッシュをダンプするプログラム
kdestroy # キャッシュを破棄するプログラム
kpasswd # ユーザが鍵を変更するためのプログラム
verify_krb5_conf # krb5.confの文法チェックプログラム
kf # キャッシュを転送するプログラム
krb5-config # コンパイラオプションを自動的に生成してくれる
login
telnet <-- 要チェック v6サポートされたないぽい
ftp <-- 要チェック v6サポートされたないぽい
su
rcp
rsh
otp
otpprint
afslog
--------- 以下謎
kgetcred
mk_cmds
pfrom
pagsh
string2key
マスターデータベースは /var/heimdal/heimdal.db
ディレクトリ名 /var/heimdal がコード埋め込みなっているので
場所は変更できないぽい。
コンパイル時に/lib/hdb/hdb.hのHDB_DB_DIRを書き換えれば可能。
ただしマスターキーの場所はkstash(8)のオプションで変更可能。
gethostname(3)で返されるFQDNからホスト部を取った文字列が
デフォルトのREALMに設定される。
kstash(8)はオプションでREALMを指定できないので、
ホスト名をFQDNぽく適切に設定しないと動かない。
o kdcの設定ファイル
Kerberosの設定を記述する。ライブラリの挙動やREALMの情報も
設定できるので KDC以外のホストでも設定すべき。
デフォルトは /etc/krb5.conf
設定ファイルの文法チェックには verify_krb5_conf(8) が使える。
ticket_lifetime
renew_lifetime
lifetime の指定には以下の単位が使える。
year, month, week, day, hour, h, minute, m, second, s, unlimited
o 動作の準備
kadmin(8)を使って新規REALM ZOOを作る。
# kadmin -l
kadmin> init ZOO
Realm max ticket life [unlimited]:
Realm max renewable ticket life [unlimited]:
この時点で /var/heimdal/heimdal.dbには以下のPRINCIPALが出来る。
default@ZOO
krbtgt/ZOO@ZOO # TGS_REQ用PRINCIPAL
kadmin/admin@ZOO # kadmind(8)用PRINCIPAL
kadmin/hprop@ZOO # incremental propagation用
kadmin/changepw@ZOO #
changepw/kerberos@ZOO #
# dump
で、現在の heimdal.dbの内容を確認できる。
XXX 出力ファイルが 644なんだけどいいのかな?
新規PRINCIPALとして doggy@ZOOを追加。
kadmin> add doggy@ZOO
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
doggy@ZOO's Password:
Verifying - doggy@ZOO's Password:
パスワード無しでも作れる
同じく kitty@ZOOを追加。
kadmin> add kitty@ZOO
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kitty@ZOO's Password:
Verifying - kitty@ZOO's Password:
master.dbのリストを見るには listコマンドを使う
kadmin> list -l doggy@ZOO
Principal: doggy@ZOO
Principal expires: never
Password expires: never
Last password change: never
Max ticket life: 1 day
Max renewable life: 1 week
Kvno: 1
Mkvno: 0
Policy: none
Last successful login: never
Last failed login: never
Failed login count: 0
Last modified: 2004-05-26 02:37:35 UTC
Modifier: kadmin/admin@ZOO
Attributes:
Keytypes(salttype[(salt-value)]): des-cbc-crc(pw-salt), des-cbc-md4(pw-salt), des-cbc-md5(pw-salt), des3-cbc-sha1(pw-salt)
o keytabの作成
Kerberosアプリケーションは何度か鍵を使う場面がある。
この時にユーザが入力しなくてもいいようにファイルに鍵を保存できる。
このファイルを keytabと呼ぶ。
keytabを作るには kadmin(8)の ext_keytabコマンドを使う。
以下は doggy@ZOOの鍵を doggy.ktabに保存している。
# kadmin -l
kadmin> ext_keytab -k doggy.ktab doggy@ZOO
ユーザは鍵を入力する必要がないのでランダムな数値を
鍵として使う事が望ましいだろう。この場合、addコマンドに
-r を付ける。
以下は piggy@ZOOを-rオプション付きで追加しpiggy.ktabに鍵を保存している。
doggy@ZOOを追加した時のように Passwordを聞いて来ない。
kadmin> add -r piggy@ZOO
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab -k piggy.ktab piggy@ZOO
keytabには複数のPRINCIPALの鍵を保存できる。
例えば、以下のようにすると doggy,kitty,piggyの鍵がzoo.ktabに保存される。
kadmin> ext_keytab -k zoo.ktab doggy@ZOO
kadmin> ext_keytab -k zoo.ktab kitty@ZOO
kadmin> ext_keytab -k zoo.ktab piggy@ZOO
keytabは ktutil(1)を使って管理できる。
keytabをダンプするには listコマンドを使う。
% root ktutil -v -k zoo.ktab list
zoo.ktab:
Vno Type Principal Date
1 des3-cbc-sha1 doggy@ZOO 2004-01-29
1 des-cbc-md5 doggy@ZOO 2004-01-29
1 des-cbc-md4 doggy@ZOO 2004-01-29
1 des-cbc-crc doggy@ZOO 2004-01-29
1 des3-cbc-sha1 kitty@ZOO 2004-01-29
1 des-cbc-md5 kitty@ZOO 2004-01-29
1 des-cbc-md4 kitty@ZOO 2004-01-29
1 des-cbc-crc kitty@ZOO 2004-01-29
1 des-cbc-crc piggy@ZOO 2004-01-29
1 des-cbc-md4 piggy@ZOO 2004-01-29
1 des-cbc-md5 piggy@ZOO 2004-01-29
1 des3-cbc-sha1 piggy@ZOO 2004-01-29
鍵を変更すると Vnoが増加する
o HostAddressesについて
ローカルにKDCを起動して実験していたが kinit(8)で以下のメッセージを出して失敗していた。
% kinit doggy@ZOO
kinit: krb5_get_init_creds: Incorrect net address
/var/log/auth.log には以下の行
Bad address list requested -- doggy@ZOO
127.0.0.1 に対して AS_REQを投げていたのでIPヘッダに 127.0.0.1が、
AS_REQのHostAddresses部に別のIPアドレス(この時は lnc0についた
10.21.32.176) が入っていて、この2つをKDCで比較していたのが原因。
解決策はいくつかあるけど処事情により1番を採用。
1. Kerberosアプリケーションではアドレスを添付しない
/etc/krb5.conf
[appdefaults]
no-addresses = 1
2. KDCでアドレスチェックをしない
/etc/krb5.conf
[kdc]
check-ticket-addresses = 0
3. アプリケーションのデフォルト動作として 127.0.0.1 を添付する
/etc/krb5.conf
[libdefaults]
extra_addresses = 127.0.0.1
4. kinitのオプションで127.0.0.1 を添付する
% kinit -a 127.0.0.0.1
o KDCサーバの起動
# /usr/local/libexec/kdc &
o KDCサーバの多重化
MASTERとして位置付けたサーバと何台かのSLAVEサーバを作る。
MASTERサーバのマスターデータベースをSLAVEサーバにコピーする。
MASTERサーバ
# /usr/local/libexec/ipropd-master &
SLAVEサーバ
# /usr/local/libexec/ipropd-slave (master hostname) &
これはマスターデータベースの変更分だけをコピーする仕組み
Incremental Propagation と呼ばれる。
この仕組みとは違い毎回全てをコピーする hprop もある。
o TGTの取得
PRINCIPAL doggy@ZOOのためのTGTを取得しCredentialをファイル
doggy.ccに格納する。 このファイルを Credential Cacheと呼ぶ。
これには kinit(1)を使う。
kinit(1)は krb5_cc_initialize()をコールするので Cacheには
PRINCIPALに対して1つのチケットしか入らない事に注意。
% kinit -c doggy.cc doggy@ZOO
doggy@ZOO's Password:
同様に kitty@ZOOのTGTを kitty.ccに格納する。
% kinit -c kitty.cc kitty@ZOO
kitty@ZOO's Password:
keytabを使うとPasswordの入力を省略できる。
% kinit -c kitty.cc -t kitty.ktab kitty@ZOO
klist(1)でキャッシュの内容を確認できる。
% klist -vc doggy.cc
Credentials cache: FILE:doggy.cc
Principal: doggy@ZOO
Cache version: 4
Server: krbtgt/ZOO@ZOO
Ticket etype: des3-cbc-sha1, kvno 1
Auth time: Jan 29 14:34:33 2004
End time: Jan 30 00:34:33 2004
Ticket flags: initial
Addresses:
% klist -vc kitty.cc
Credentials cache: FILE:kitty.cc
Principal: kitty@ZOO
Cache version: 4
Server: krbtgt/ZOO@ZOO
Ticket etype: des3-cbc-sha1, kvno 1
Auth time: Jan 29 14:35:52 2004
End time: Jan 30 00:35:52 2004
Ticket flags: initial
Addresses:
o キャッシュの破棄
Credentialは有効期限まで使えるので破棄したい場合は kdestroy(1)を使う。
単にファイルを消してるぽい。コード未確認。
% kdestroy -c piggy.ktab
o PRINCIPALの鍵の変更
kadminを使う場合
kadmin> passwd -r doggy@ZOO
XXX
# /usr/local/libexec/kpasswdd &
% kpasswd piggy@ZOO
o libkrb5 メモ
krb5_sendauth()問題その1
KRB_AP_REQを送信するときに krb5_net_write()をコールするが、
この関数は send()を使っているので connected socketじゃないと
エラーになる。
krb5_contextに相手のIPアドレスを入れられるのでそれを使ってsendto()
してみては?
send(strlen("KRB5_SENDAUTH_V1.0"))
send("KRB5_SENDAUTH_V1.0")
send(strlen(application version))
send(application version)
recv(reply)
send(AP_REQ)
recv(reply)
if (AP_OPTS_MUTUAL_REQUIRED)
recv(AP_REP)
krb5_recvauth()問題
krb5_sendauth()は KRB5_SENDAUTH_VERSIONを送信した後に
krb5_net_read()を呼び出しサーバからの応答を待つ。
この時にサーバからの応答がないと krb5_net_read()でブロックして
しまう。
if (KRB5_RECVAUTH_IGNORE_VERSION)
read(len, 4)
read(version, len)
recv(len, 4)
recv(application version, len)
send(0, 1)
recv(AP_REQ)
send(0, 4)
if (AP_OPTS_MUTUAL_REQUIRED)
send(AP_REP)
krb5_net_read()問題
引数にバッファ bufと読みだしたい長さ lenを渡している。
読みだしが lenに達しないと無限ループになってしまう。
Kerberosのネゴシエーションの途中で何らかの問題起きると
プログラムはブロックしてしまう。
これを回避するには signal()を使うしかない。の???