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 ファイルを移動したりするテクノロジーです。本来コンピューター自身に勝手なことをさせるのは危険なのですが、「特定のサービスだけ許可するよ」とコンピューターに特権を与えるときに「制約付き委任」の設定を行います。

image

ここまで書くと「制約付き」の意味がなんとなく分かってきますよね。

そもそも KCD というものがなぜ Windows Server に実装されたのかといえば、ドメインの枠を超えて安全にサービス間連携をさせるためです。サービスが連携できるということは、あるプロセスとプロセスの間に「人」が介在する必要が無くなります。つまり「プロセス間の自動化」が実現でき、結果として管理や制御コストを削減できます。

Windows 2000 Server に実装されていた Kerberos でも「Delegation(委任)」は可能でした。しかしこの時代の委任は、「あとはまかせた。よしなによろしく!」という委任でした。つまり、丸投げです。

サービスアカウントに対して、「お前を信頼しているよ。サービスチケットが欲しかったら KDC(キー配布センター)に言えば発行してくれるから」てな感じす。なので、今となっては非常に危険だったんですね。かといって、委任ができないと処理を自動化することもできないという、不便な環境になってしまいます。

image

そこで「制約付き」の委任が 2003 で実装されたわけですね。

ライブマイグレーションの例で言いましょう。コンピューターに「ライブマイグレーションに限っては、管理者の許可を得ずに相手のサービスと通信してもよい」と許可することで、本来は管理者がその都度許可しなければならなかった「仮想マシン作成」「メモリ転送」や「仮想ディスク移動」といった作業を、ライブマイグレーションサービスの判断で行えるようになります。そうなると、「CPU 100% が続いているから仮想マシンを別のサーバーに移動しよう」ということが、プログラムの判断で行えるようになります。

この委任を「怪しげなサービス」に対して許可してしまったらどうでしょう?仮想マシンが勝手にライブマイグレーションされて、仮想マシンごと盗まれる可能性があります。こんな危険なことはできません。

今後は、デバイスとして Android や iPad を使ったり、自宅から社内のリソースにアクセスしたりと、業務をドメイン内にとどめておくことが難しくなりつつあります。クラウドサービスとの連携を考えればなおさらです。つまり、ドメインの枠を超えたサービス間連携の仕組みが必要になるわけです。その鍵となるのが、「KCD: 制約付き委任」なのです。

ここからは、Azure Application Proxy を例に、KCD の仕組みについて理解していきましょう。うまく書けるかな。。。

前提として、社内の Web アプリ は 統合 Windows 認証(IWA)を使用しており、Azure アプリケーションプロキシでは Azure AD による事前認証が設定されているものとします。

image

以下は上に示した Azure Application Proxy を使用する場合の流れを簡単に説明したものです。

  1. ユーザーが URL を入力して、オンプレミスのアプリケーションにアクセスしようとする
  2. アクセス要求は Azure アプリケーション プロキシによって Azure AD 認証サービスにリダイレクトされ、事前認証が行われる
  3. 設定されていれば多要素認証が行われる
  4. 認証が完了すると Azure AD からトークンが発行される
  5. ユーザーはトークンをアプリケーション プロキシに渡す。アプリケーション プロキシはトークンを検証し、ユーザー プリンシパル名 (UPN) をトークンから取り出す
  6. アプリケーション プロキシは、通信のリクエスト、UPN、サービス プリンシパル名 (SPN) を Azure アプリケーションプロキシ コネクタに送信する
  7. Azure アプリケーション プロキシ コネクタは、オンプレミス AD との KCD ネゴシエーションを実行。これにより、UPN で示されたユーザーの代理でアプリケーションに対する Kerberos トークンを取得する。
  8. Active Directory ドメインサービスは、「ユーザーがアプリケーションにアクセスするための Kerberos トークン」をコネクタに送信
  9. コネクタは、AD から受信したユーザー用の Kerberos トークンを使用して、元の要求(ユーザーによるアクセス)をアプリケーション サーバーに送信
  10. アプリケーションからの応答がプロキシコネクタに送信される
  11. 応答が 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 に遷移させることができます(結果的にプロトコル「変換」ですが、「変換」と書くと、なんか違う)。

image

これにより、以下のような認証プロトコルを 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