KCD(Kerberos Constrained Delegation) を理解する (1)
Azure アプリケーションプロキシーや Windows Server Web Application Proxy では、KCD(Kerberos Constrained Delegation)という機能を使用して、オンプレミス Active Directory との SSO を実現しています。
KDC(Key Destribution Center:キー配布センター)ではありません。KCD です。3文字略語が多くてイヤになりますね。
で、KCD ってなんのこっちゃわかります?
あらためて聞かれると、「とあるサービスに、特定の別のサービスに対するアクセス権限を委任してごにょごにょ。まぁ、細かいことは気にすんな。」な感じになってしまって、きっちり説明する自信がありません。
そんな中、以下のホワイトペーパーがリリースされました。
Understanding Kerberos Constrained Delegation for Azure Active Directory Application Proxy Deployments with Integrated Windows Authentication
https://aka.ms/KCDPaper
投稿元は本社の Azure Application Proxy ブログです。
All you want to know about Kerberos Constrained Delegation (KCD)
https://blogs.technet.com/b/applicationproxyblog/archive/2015/09/21/all-you-want-to-know-about-kerberos-constrained-delegation-kcd.aspx
ホワイトペーパー全体を翻訳するのはアレなので、ざっくり理解できる程度にサマっておきたいと思います。
Kerberos Constrained Delegation (KCD) は、日本語で書くと「ケルベロス制約付き委任」です。長いので、通常は「制約付き委任」と言います。特別新しい機能ってわけでもなく、Windows Server 2003 SP1 で Kerberos の拡張機能として実装され、その後 OS のアップデートとともに拡張され続けています。ちなみに、Windows Server 2012 では Service for User to Proxy (S4U2Proxy) という拡張が行われています。詳細は後程。
そういえば、「制約付き委任」って、Hyper-V Live Migration over SMB とかの設定をするときに出てきますね。ライブマイグレーションとは、ライブマイグレーション サービスが相手側コンピューターのサービスと通信をしてメモリ内データを転送したり、CIFS サービスを使用して VHD ファイルを移動したりするテクノロジーです。本来コンピューター自身に勝手なことをさせるのは危険なのですが、「特定のサービスだけ許可するよ」とコンピューターに特権を与えるときに「制約付き委任」の設定を行います。
ここまで書くと「制約付き」の意味がなんとなく分かってきますよね。
そもそも KCD というものがなぜ Windows Server に実装されたのかといえば、ドメインの枠を超えて安全にサービス間連携をさせるためです。サービスが連携できるということは、あるプロセスとプロセスの間に「人」が介在する必要が無くなります。つまり「プロセス間の自動化」が実現でき、結果として管理や制御コストを削減できます。
Windows 2000 Server に実装されていた Kerberos でも「Delegation(委任)」は可能でした。しかしこの時代の委任は、「あとはまかせた。よしなによろしく!」という委任でした。つまり、丸投げです。
サービスアカウントに対して、「お前を信頼しているよ。サービスチケットが欲しかったら KDC(キー配布センター)に言えば発行してくれるから」てな感じす。なので、今となっては非常に危険だったんですね。かといって、委任ができないと処理を自動化することもできないという、不便な環境になってしまいます。
そこで「制約付き」の委任が 2003 で実装されたわけですね。
ライブマイグレーションの例で言いましょう。コンピューターに「ライブマイグレーションに限っては、管理者の許可を得ずに相手のサービスと通信してもよい」と許可することで、本来は管理者がその都度許可しなければならなかった「仮想マシン作成」「メモリ転送」や「仮想ディスク移動」といった作業を、ライブマイグレーションサービスの判断で行えるようになります。そうなると、「CPU 100% が続いているから仮想マシンを別のサーバーに移動しよう」ということが、プログラムの判断で行えるようになります。
この委任を「怪しげなサービス」に対して許可してしまったらどうでしょう?仮想マシンが勝手にライブマイグレーションされて、仮想マシンごと盗まれる可能性があります。こんな危険なことはできません。
今後は、デバイスとして Android や iPad を使ったり、自宅から社内のリソースにアクセスしたりと、業務をドメイン内にとどめておくことが難しくなりつつあります。クラウドサービスとの連携を考えればなおさらです。つまり、ドメインの枠を超えたサービス間連携の仕組みが必要になるわけです。その鍵となるのが、「KCD: 制約付き委任」なのです。
ここからは、Azure Application Proxy を例に、KCD の仕組みについて理解していきましょう。うまく書けるかな。。。
前提として、社内の Web アプリ は 統合 Windows 認証(IWA)を使用しており、Azure アプリケーションプロキシでは Azure AD による事前認証が設定されているものとします。
以下は上に示した Azure Application Proxy を使用する場合の流れを簡単に説明したものです。
- ユーザーが URL を入力して、オンプレミスのアプリケーションにアクセスしようとする
- アクセス要求は Azure アプリケーション プロキシによって Azure AD 認証サービスにリダイレクトされ、事前認証が行われる
- 設定されていれば多要素認証が行われる
- 認証が完了すると Azure AD からトークンが発行される
- ユーザーはトークンをアプリケーション プロキシに渡す。アプリケーション プロキシはトークンを検証し、ユーザー プリンシパル名 (UPN) をトークンから取り出す
- アプリケーション プロキシは、通信のリクエスト、UPN、サービス プリンシパル名 (SPN) を Azure アプリケーションプロキシ コネクタに送信する
- Azure アプリケーション プロキシ コネクタは、オンプレミス AD との KCD ネゴシエーションを実行。これにより、UPN で示されたユーザーの代理でアプリケーションに対する Kerberos トークンを取得する。
- Active Directory ドメインサービスは、「ユーザーがアプリケーションにアクセスするための Kerberos トークン」をコネクタに送信
- コネクタは、AD から受信したユーザー用の Kerberos トークンを使用して、元の要求(ユーザーによるアクセス)をアプリケーション サーバーに送信
- アプリケーションからの応答がプロキシコネクタに送信される
- 応答が Azure アプリケーション プロキシに返され、最終的にユーザーに返される
社内 Web アプリケーションに設定されている IWA(統合 Windows 認証)についてはご存知の方も多いと思います。IWA には、SPNEGO や Kerberos、NTLM といった複数の認証メカニズムが実装されていますが、ここでは Kerberos を使用していると考えてください。Kerberos が使われている環境でないと KCD は動作しません。そりゃそうです。
KCD を理解するには、まずはプロトコル トランジション(Protocol Transition)」という機能について理解しておく必要があります。これも Windows Server 2003 SP1 の Kerberos 拡張として実装された機能です。「プロトコル遷移」とも言います。
Windows Server 2003 がリリースされた当時のことを思い出してください。まだクラウドコンピューティングが一般的でない時代です。この当時の企業のニーズとして大きなものの1つは「社内の業務用 WEB アプリケーションを社外に公開し、社外からアクセスしたい」というものでした。まだ、残念ながら IIS があまり信用されていなかった時代ですね。トホホ。
Active Directory ドメインによって守られた IIS 環境では Kerberos によって保護することが推奨されていたものの、Kerberos(Port 88)と Firewall の相性は言うまでもなく良くありません。そこで、外部からのユーザー認証に使用する認証プロトコルを、内部で使用している Kerberos に遷移(トランジション)させる仕組みが必要になりました。これが「Kerberos プロトコル トランジション」です。今じゃ当たり前に行っていますが、当時アプリケーションを開発していた方は結構苦労されたはずです。
プロトコル トランジション を使用すると、例えば、外部からフォーム認証を使用してアクセスしたとしても、それを Kerberos に遷移させることができます(結果的にプロトコル「変換」ですが、「変換」と書くと、なんか違う)。
これにより、以下のような認証プロトコルを Kerberos に遷移させることができるようになりました。
- NTLM
- Basic
- Digest
- SSL Client Certificate
- Forms-based Authentication
- Claims Based Authentication
- その他の独自に実装した認証プロトコル
このように、プロトコル トランジションはアプリケーションの設計に柔軟性を与えることができます。つまり、ユーザーの認証レイヤにおいては Kerberos とは異なるプロトコルを使用していても(例えば独自実装の認証とか)、その上のレイヤで Kerberos にスイッチできるわけです。
プロトコルトランジションを行うには、誰が、何に対して委任するのかを明確にする必要があるわけですが、「何」の部分を識別するために使用するのが サービスプリンシパルネーム(SPN)です。
長くなったので、次回は SPN の話から始めます。
※すんません、力尽きました。。。
KCD(Kerberos Constrained Delegation) を理解する (2)
https://blogs.technet.com/b/junichia/archive/2015/10/24/3656265.aspx