Active Directory認証を使用してApacheでホストされているWebサイトにシングルサインオンを設定する際に見つけたすべてのチュートリアルは、安全でない設定でKerberosを構成することによって行います。しばらくの間、 Active DirectoryでKerberosのRC4-HMAC暗号化を無効にする を行うのがベストプラクティスですが、多くのチュートリアルでは、krb5.confのデフォルトをオーバーライドし、すべてをRC4-HMACで機能させる必要があります。
AES256暗号化を使用してシングルサインオンを設定してみたかったのですが、それを機能させることができたので、サイトのセキュリティを強化したい人のために、この質問と回答を記録しています。
最初にRC4-HMACで動作させることから始めます。これは、これが簡単だからです。 SSOを設定するための標準的な手順は、関連付けられたSPNを使用してドメインアカウントを作成することから始まります。このアカウントを使用して、ブラウザーは暗号化された資格情報を取得してサーバーに送信します。この例では、私のユーザーはREALM\HostServiceAccountです。
ターゲットサーバーの/etc/krb5.confに次のエントリを追加します。
[libdefaults]
default_realm = REALM.COM
[domain_realm]
.realm.com = REALM.COM
realm.com = REALM.COM
キータブを作成し、サーバーに読み取らせます。
# ktutil
ktutil: add_entry -password -p HTTP/[email protected] -k 1 -e rc4-hmac
Password for HTTP/[email protected]: <enter password here>
ktutil: write_kt /etc/Apache2/service.keytab
ktutil: q
# chown -v www-data:root /etc/Apache2/service.keytab
# chmod -v 440 /etc/Apache2/service.keytab
(もちろん、この時点で、kinit -kt service.keytab -S HTTP/[email protected] [email protected]
を使用してキータブをテストすることをお勧めします。)
最後に、キータブを使用してユーザーを認証するようにApacheを設定します。
KrbDelegateBasic off
KrbAuthoritative on
KrbMethodK5Passwd off
Krb5Keytab /etc/Apache2/service.keytab
KrbAuthRealms REALM.COM
LogLevel debug
Apacheを再起動した後、すべてがうまくいけば、Windowsドメインマシンからサーバーにリクエストを実行し、Apacheのエラーログに次のように表示されます。
[debug] src/mod_auth_kerb.c(1641): [client ****] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos, referer: ****
[debug] src/mod_auth_kerb.c(1395): [client ****] Verifying client data using KRB5 GSS-API , referer: ****
[debug] src/mod_auth_kerb.c(1411): [client ****] Client didn't delegate us their credential, referer: ****
[debug] src/mod_auth_kerb.c(1430): [client ****] GSS-API token of length 185 bytes will be sent back, ****
クライアントマシン(またはリクエスト内のチケットを確認するためにWireshark)でklistを実行すると、実際にRC4-HMACチケットを使用して認証したことがわかります。
#4> Client: fluggo @ REALM.COM
Server: HTTP/Host.example.com @ REALM.COM
KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
すべてが順調ですが、これも私たちの目標ではありません。 RC4-HMACは安全でないと見なされるため、それを無効にして、AES256で同じセットアップが機能するようにしてみましょう。
まず、友好的な近隣ドメイン管理者に、REALM\HostServiceAccountで高度な暗号化を有効にするように依頼します。これには次のラベルが付いた2つのチェックボックスがあります。
これらは、使用しているツールに応じてさまざまな場所に表示されます。最終結果は、LDAP属性msDS-SupportedEncryptionTypesが0x18または10進数の24になるはずです。これは、AES128とAES256のみがサポートされていることを表します。
これを効果的にするために、ローカルクライアントのチケットを削除します。
C:>klist purge
Current LogonId is 0:0xdeadbeef
Deleting all tickets:
Ticket(s) purged!
リクエストを再度実行すると、リクエストが失敗したことがわかりますが、更新されたチケットがあります。
C:>klist
...
#3> Client: fluggo @ REALM.COM
Server: HTTP/Host.example.com @ REALM.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
これで、キータブを新しいアルゴリズムで更新する必要があり、ゴールデンになるはずです。
# mv /etc/Apache2/service.keytab ~/old.keytab
# ktutil
ktutil: add_entry -password -p HTTP/[email protected] -k 1 -e aes256-cts-hmac-sha1-96
Password for HTTP/[email protected]: <enter password here>
ktutil: add_entry -password -p HTTP/[email protected] -k 1 -e aes128-cts-hmac-sha1-96
Password for HTTP/[email protected]: <enter password here>
ktutil: write_kt /etc/Apache2/service.keytab
ktutil: q
# chown -v www-data:root /etc/Apache2/service.keytab
# chmod -v 440 /etc/Apache2/service.keytab
Apacheを再起動する必要すらありません。リクエストを再送信するだけです。
おっと...それは動作しません。 Apacheのエラーログを見ると、次のことがわかります。
[debug] src/mod_auth_kerb.c(1641): [client ****] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[debug] src/mod_auth_kerb.c(1249): [client ****] Acquiring creds for [email protected]
[debug] src/mod_auth_kerb.c(1395): [client ****] Verifying client data using KRB5 GSS-API
[debug] src/mod_auth_kerb.c(1411): [client ****] Client didn't delegate us their credential
[debug] src/mod_auth_kerb.c(1430): [client ****] GSS-API token of length 9 bytes will be sent back
[debug] src/mod_auth_kerb.c(1110): [client ****] GSS-API major_status:000d0000, minor_status:000186a5
[error] [client ****] gss_accept_sec_context() failed: Unspecified GSS failure. Minor code may provide more information (, )
それはばかげて役に立たないエラーメッセージですが、何が問題だったのでしょうか。答え、そして従うべき1つの解決策!
ここでの主要な問題は、AES256が解決しようとした問題の1つであることがわかりました。
TL; DR:キータブのプリンシパル名がアカウント名と一致する必要があります。
実行した場合KRB5_TRACE=/dev/stderr kinit [email protected]
アカウントがRC4-HMAC暗号化のみに対して有効にされていたとき、出力に次の行が表示されていました。
[8192] 1441829478.537451: Selected etype info: etype rc4-hmac, salt "", params ""
AES256が有効になったので、その行は次のようになります。
[8200] 1441829508.947208: Selected etype info: etype aes256-cts, salt "REALM.COMHostServiceAccount", params ""
NTLM認証からKerberosへの切り替えが行われたとき、NTLMハッシュを再利用するためにRC4-HMACアルゴリズムが指定されました。 Microsoftは、既存のシステムがKerberosと相互運用しやすくするために、ハッシュにソルトを入れることを拒否しました。ユーザーがアップグレードできるようになったので、AES256およびAES128アルゴリズムにsaltが指定され、saltがユーザー名になります。
異なるユーザー名を使用してRC4-HMACとAES256のキータブを生成すると、これを確認できます。 RC4-HMACの場合:
fluggo@Host:~$ ktutil
ktutil: add_entry -password -p HTTP/[email protected] -k 1 -e rc4-hmac
Password for HTTP/[email protected]: 12345
ktutil: add_entry -password -p [email protected] -k 1 -e rc4-hmac
Password for [email protected]: 12345
ktutil: write_kt rc4.keytab
ktutil: q
fluggo@Host:~$ klist -Kek rc4.keytab
Keytab name: FILE:rc4.keytab
KVNO Principal
---- --------------------------------------------------------------------------
1 HTTP/[email protected] (arcfour-hmac) (0x7a21990fcd3d759941e45c490f143d5f)
1 [email protected] (arcfour-hmac) (0x7a21990fcd3d759941e45c490f143d5f)
...ハッシュは同じであるため、これら2つのエントリは同等です。しかし、AES256の場合:
fluggo@Host:~$ ktutil
ktutil: add_entry -password -p HTTP/[email protected] -k 1 -e aes256-cts-hmac-sha1-96
Password for HTTP/[email protected]: 12345
ktutil: add_entry -password -p [email protected] -k 1 -e aes256-cts-hmac-sha1-96
Password for [email protected]: 12345
ktutil: write_kt aes.keytab
ktutil: q
fluggo@Host:~$ klist -Kek aes.keytab
Keytab name: FILE:aes.keytab
KVNO Principal
---- --------------------------------------------------------------------------
1 HTTP/[email protected] (aes256-cts-hmac-sha1-96) (0x5746fa6f9b0c990ba7fb20acd85065040d66e843a043508569841768ef2b7917)
1 [email protected] (aes256-cts-hmac-sha1-96) (0x6a98fdccbce4db77f40192f4e916e0900a1b9cba2f6ca8bc737d968e4b961c25)
...ハッシュは異なります。プリンシパル名は重要であり、アカウントのUPNと一致する必要があります。
キータブが機能するにはユーザー名が正しい必要があるため、ActiveDirectoryがチケットで使用するプリンシパル名を使用して新しいキータブを生成します。
# rm /etc/Apache2/service.keytab
# ktutil
ktutil: add_entry -password -p [email protected] -k 1 -e aes256-cts-hmac-sha1-96
Password for [email protected]: <enter password here>
ktutil: add_entry -password -p [email protected] -k 1 -e aes128-cts-hmac-sha1-96
Password for [email protected]: <enter password here>
ktutil: write_kt /etc/Apache2/service.keytab
ktutil: q
# chown -v www-data:root /etc/Apache2/service.keytab
# chmod -v 440 /etc/Apache2/service.keytab
Apacheはキータブのプリンシパル名を気にするため、これらのエントリを単独で見つけることはありません。代わりに、Apacheに、検出できる動作プリンシパルを使用するように指示します。
KrbServiceName Any
Apacheに正しい名前でプリンシパルを見つけてもらいたかったのですが、キータブにあるのはプリンシパルだけなので、ほとんど問題になりません。
Apacheを再起動し、ページを更新すると、認証が機能するはずです。