ad_apache.png
ウェブで事例を見かけて以来、やってみたいと考えていた。
↓このページを見て何度かトライしてみたんだけどずーっと上手くいってなかった。
using mod_auth_kerb and Windows 2000/2003 as KDC

けど、ついに自分ところの環境で動いたのでメモ。

手順や設定はほぼ上のURLに書いてあるとおりなんだけど、自分のところでは
KrbServiceName HTTP
だとダメで
KrbServiceName HTTP/ウェブサーバのFQDN
にしたらあっさり通った。
ネットで見かけた設定例だと「HTTP」か設定なしなので自分ところだけおかしいのか~。わからん。

LogLevelをdebugにしてerror.logを見る。

KrbServiceNameをHTTPに設定していると以下の通り「HTTP@ウェブサーバのFQDN」に対するcredentialを得ようとしているっぽい。
[debug] src/mod_auth_kerb.c(1147): [client 192.*.*.*] Acquiring creds for HTTP@ウェブサーバのFQDN
[error] [client 192.*.*.*] gss_acquire_cred() failed: An invalid name was supplied (Hostname cannot be canonicalized)
keytabのプリンシパルはHTTP/www.example.cc@EXAMPLE.CCという感じなので@以降が補完されたとしても合致しないことになる。

mod_auth_kerb.c(これは5.4のソース)のget_gss_credsを見ると「/」が含まれるかどうかで挙動が変わるっぽい。
   have_server_princ = conf->krb_service_name && strchr(conf->krb_service_name,'/') != NULL;
   if (have_server_princ)
      strncpy(buf, conf->krb_service_name, sizeof(buf));
   else if (conf->krb_service_name && strcmp(conf->krb_service_name,"Any") == 0) {
      *server_creds = GSS_C_NO_CREDENTIAL;
      return 0;
   }
   else
      snprintf(buf, sizeof(buf), "%s@%s",
           (conf->krb_service_name) ? conf->krb_service_name : SERVICE_NAME,
           ap_get_server_name(r));
とにかく僕のところの環境ではKrbServiceNameにサービスプリンシパル名を記述することにした。
副作用というかなんというか結果的にプリンシパル名中のFQDNとウェブサーバのFQDNが異なってても認証が通るのでVirtualHostを使っててもkeytabが同じでいいので手間は少ない?

サーバ側の準備

  • ADサーバとドメイン構築
    • ADサーバからwebサーバのFQDNを引けるように。
  • ADサーバで
    • サービスマップ用のダミーアカウントを作成
    • ktpass.exeでサービスプリンシパルをダミーアカウントにマップしつつkeytabファイル作成
      ktpass.exe -princ HTTP/ウェブサーバのFQDN@EXAMPLE.CC 
      -crypto rc4-hmac-nt -ptype KRB5_NT_SRV_HST
      -mapuser ダミーアカウント@EXAMPLE.CC -pass パスワード -out 出力先ファイル名
    • 古いktpass.exeには問題があるそうなので、MSから最新版を入手して使った
      http://support.microsoft.com/kb/926027
  • webサーバで
    • /etc/krb5.conf設定
      [libdefaults]
       default_realm = EXAMPLE.CC
       dns_lookup_realm = false
       dns_lookup_kdc = false
       ticket_lifetime = 24h
       forwardable = yes

      [realms]
       EXAMPLE.CC = {
        kdc = ADサーバ
        default_domain = example.cc
       }

      [domain_realm]
       .example.cc = EXAMPLE.CC
       example.cc = EXAMPLE.CC
    • ADサーバ上で作ったkeytabファイルをwebサーバに持ってくる
    • apacheユーザから参照できるようにowner/groupを設定しchmodで400に
    • 認証領域設定。locationでもdirectoryでも。
          <Location /認証領域/>
              AuthType  Kerberos
              KrbAuthRealms EXAMPLE.CC
              KrbServiceName HTTP/ウェブサーバのFQDN(keytab作成したときと同じ名前)
              Krb5Keytab keytabファイルのpath
              KrbMethodNegotiate on
              KrbMethodK5Passwd off
              Require valid-user
    • reloadなり再起動なり

クライアント側の準備

  • クライアントPCをドメインに参加させる
  • ドメインユーザでログオン
  • IEの場合
    • オプションから統合Windows認証を有効に。デフォルトは有効
    • 統合Windows認証の対象にしたいサイトのドメインを「イントラネット」扱いに設定
      • [ツール]→[オプション]→セキュリティタブ→「サイト」ボタン→「詳細設定」ボタン
      • ドメインを入力して→「追加」ボタン
      • httpsを必要とするかどうかは適宜
  • Firefoxの場合
    • about:configを開く
    • network.negotiate-auth.trusted-urisを編集、統合Windows認証の対象にしたいドメイン名を設定

環境

CentOS: 5.2
  mod_auth_kerb-5.1-3.el5
  httpd-2.2.3-11.el5_2.centos.4
W2k3 R2 EE SP2
  SupportToolsの更新版
  IE7
Windows XP
  IE6
  Fx3.0.5

おまけ

統合Windows認証を通過するとREMOTE_USERが「user1@EXAMPLE.CC」のようにrealm付きの値になる。
mod_auth_kerbが5.4の場合、KrbLocalUserMappingをonにしておくとrealm部分がstripされて上記例なら「user1」になる。