2017年1月10日火曜日

Office365管理者は要対応。外部共有により不要なアクセス権が付与される

こんにちは、富士榮です。

OneDrive for Business上のコンテンツやSharePoint Onlineのチームサイトを他組織のユーザと共有をするB2Bシナリオで利用している企業・組織が増えている中、Office365(およびそのID基盤であるAzure AD)の構造上の問題により、意図しないアクセス権を外部ユーザへ付与してしまう場合があるので、注意喚起の意味で本エントリを書きます。

[3/7 Update]
一部修正が行われ、ポータルからのディレクトリ構成情報へのアクセスがデフォルトでブロックされるようになりました。
詳しくはこちらをご覧ください。
 http://idmlab.eidentity.jp/2017/03/office365.html

現在、この課題については米国マイクロソフトのAzure AD開発チームへエスカレーションしており早期の改善を求めていますが、場合によっては長期化する可能性もあるため、自組織でOffice365を管理しており、外部ユーザとのコンテンツ共有をエンドユーザへ開放している管理者は一読の上、対応を行うことをお勧めします。
(いわゆる製品やサービスの脆弱性の類ではないため)


◆課題の概要

OneDrive for Business上のコンテンツ共有やSharePoint Onlineのチームサイトへの招待を受けた外部ユーザは、共有されたコンテンツ以外にも、「Azure AD上ですべてのユーザに対して割り当てを行われたアプリケーションや、Azure Portalを経由したディレクトリ情報へのアクセスが許可されてしまいます。かつ、事前に共有した本人および管理者がこのことに気が付くことはほぼ不可能です(どこにもそのような記述はないため)」。

これは招待されたユーザが自組織でOffice365やAzure ADを使っておらず個人でマイクロソフトアカウントを使っている場合においても発生します。


◆実際の動き

実際にどのような動きになるのか、動画を撮っていますので、まずはこちらをご覧ください。
わかりにくいですが、以下が環境です。

<組織「eIdentity」:招待する側>
・Office365を運用しています
・一般ユーザ「test001@ems.adfs20.net」でOneDrive for Businessで外部ユーザ「test001@gapps21.adfs20.net」に対してコンテンツを共有します
・Azure AD上で「ts2016」というアプリケーションをAll Usersグループに対して公開しています

<組織「InternetWeek」:招待される側>
・Office365は使っていませんが、Azure ADを利用しています
 (マイクロソフトアカウントの場合も同じ動きになります)
・「test001@gapps21.adfs20.net」という一般ユーザが所属しています




単純にeIdentityテナントのユーザでOneDrive for Businessでフォルダを共有しただけなのに、共有前はInternetWeekテナントのユーザがアクセス出来なかったts2016アプリへアクセスが出来てしまい、かつAzure Portal経由でeIdentityディレクトリの構成情報(ドメイン一覧)が参照できてしまっています。
※アプリケーションのURLを知らなくてもアクセスパネル(https://myapps.microsoft.comへアクセスすると利用できるアプリケーション一覧が表示されてしまいます。
※SharePoint Onlineのチームサイトへの招待の場合は、アプリケーションアクセスは出来ませんが、Azure Portal経由でのディレクトリ情報の参照は可能な状態になります。
(「All Usersグループ」へ自動追加されないため)


ディレクトリ上(ドメイン一覧)の参照


アプリケーションへのアクセス

上記のスクリーンショットはいずれもゲストユーザによりアクセスした状態で撮っています。


管理者としては、特定のコンテンツのみの共有なら、、という気持ちで許可した外部共有がこのような形で他の情報へのアクセスへ影響を与えるということは意図していないことが多いと思われるため、非常に大きな問題となる可能性があります。


◆なぜ発生するのか

OneDrive for BusinessやSharePoint Onlineで外部ユーザを招待すると、招待されたユーザが招待したOffice365側のAzure AD上にゲストユーザとして登録されます。
これはAzure AD B2Bで外部ユーザを招待するのと同じ動作であり、Office365が内部的にAzure AD B2Bの機能を利用しているために発生しています。

そして現状では、ゲストとして登録されたユーザは、
1.ディレクトリへのサインイン(認証)
2.ディレクトリ上の自プロファイルへのアクセス
に加えて、
3.ディレクトリ構成情報へのアクセス(少なくともドメイン一覧の参照)
4.(場合により)All Usersグループへの自動登録
が行われてしまいます。

1、2については本来のゲストユーザとしてアクセスを行うために最低限必要な機能なので、仕方がありませんが、問題は3、4です。


◆Office365/Azure ADの内部構造の課題

ここまで見てきたとおり、Azure ADにゲストとして登録された外部ユーザが想定以上に権限を持ってしまっていることが根本的な課題です。
少なくとも、
・自プロファイル以外のディレクトリ情報へのアクセス
・ディレクトリに登録されたアプリケーションへのアクセス
はデフォルトでは禁止されるべきでしょう。

早々にマイクロソフトが対応してくれることを望みます。


◆推奨される対応

このような状況なので管理者が出来ることと出来ないことがあるのですが、少なくとも以下の対応をしておくべきでしょう。

1.ゲストユーザが自ディレクトリ上に存在するかどうかの確認

まず、自ディレクトリ上にゲストユーザが存在しているかどうかは定期的に確認をしておくべきでしょう。
以下のAzure Active DirectoryのPowerShellを使い、以下のコマンドレットを実行することでゲストの存在を確認できます。
Get-MsolUser | Where-Object { $_.userType -eq 'Guest' }



2.All Usersではなく、自ディレクトリ上の本来のメンバだけが含まれるグループの作成

動的メンバシップグループをカスタムで作成し、userType=Memberのユーザだけが所属する様に構成することで自ディレクトリ上で作成されたユーザのみが含まれるグループを作成することが可能です。


逆にuserType=Guestだけが含まれるグループを作成するとゲストだけが含まれるグループを作成することが出来ます。



3.All Usersグループへ割り当てられているアプリケーションの割り当て変更

All Usersグループへのアプリケーション割り当ては非常に便利なので使ってしまいがちなのですが、ここは先の2で作成したメンバだけが所属しているグループへの付け替えを検討しましょう。

こうしておけば、Azure ADからプロビジョニングを行っているアプリケーションであっても、ゲストユーザはプロビジョニングされませんし、アクセスパネル(https://myapps.microsoft.com)にもアプリケーションは出てきませんので安心です。

<変更前>

<変更後>



4.アプリケーション側でしっかり認可を行う

この問題は最終的にはアプリケーションの作りに依存するので、認証されただけでは利用できないようにアプリケーションを構成する(きちんと認可する)ことが最も大切です。

例えば、今回の動画の中でアクセスしている「ts2016」というアプリケーションはディレクトリ上にユーザが存在していれば使える、という簡易な実装にしてしまっているためゲストであっても使えてしまいます。

しかし、アプリケーション側の実装で、認証されてアクセスしてきたユーザへのアクセス制御を他の属性(所属など)を用いてしっかりと管理を行うことで、少なくとも重要なデータへのアクセスを防ぐことが出来ます。

5.ポータルへのアクセスを禁止する(要注意:影響度大)

設定を間違えると管理者でさえ管理ポータルへアクセスできなくなったり、他のAPIを使うアプリケーションへのアクセスが一切できなくなるので、この設定を行う場合は十分にテストを行った上で慎重に実施してください。著者は一切責任をとれません。

かなり強引なやり方ですが、条件付きアクセスを利用してゲストユーザからWindows Azure Service Management APIへのアクセスをブロックしてしまえば管理ポータルへのアクセスが出来なくなります。

以下の条件付きアクセスポリシーを作成します。
・Users and groups:All Guests(先ほど作成したゲストだけのグループ)
・Cloud apps:Windows Azure Service Management API
・Grant:Block access
・Enable policy:On






このポリシーを有効にすると、管理ポータルへアクセスしようとするとアクセスがブロックされます。

ディレクトリを切り替えようとすると、

アクセスがブロックされます。

◆今後の対応

現状、この動作はサービスの仕様の問題であり、いわゆるバグ等の不具合には該当しないためサービスのエンハンス要求を挙げている状態です。

この状態で出来ることは管理者の自衛が中心となりますので、動作および自テナントの状態をよく理解して運用をしていってください。

今後、動作に変更などあれば本ブログでも更新情報を発信していきたいと思います。

2017年1月8日日曜日

CentOS+Apacheの認証をAzure AD/OpenID Connectで行う

こんにちは、富士榮です。

某普通な人がnode.jsとPAMを使ったApache+Azure ADの認証(Basic認証)の記事を書いていたので、そういえばPingIdentityの人が作ってるmod_auth_openidc使ってなかった事を思い出したのでやってみました。

 参考)割と普通なブログ
  Linux+Apache の認証で Azure Active Directory を利用する
  http://normalian.hatenablog.com/entry/2017/01/08/031209


やりたいことは、CentOSにホストされたApache上のWebコンテンツへのアクセスAzure ADで保護する、という非常にシンプルなシナリオです。
※意外と実案件でもこの手の引き合い多いんですよね。オンプレのWebサーバでスタティックコンテンツの場合はAzure AD WAP(Web Application Proxy)で提案しちゃうことが多いんですけどね。

◆環境(必要なもの)

CentOSは手元に転がっていたVMをそのまま流用しました。
uname -aの結果はこんな感じ。ちなみに面倒なのでSELinuxとFirewallは無効にしてあります。
[root@oidc conf]# uname -a
Linux oidc.eidentity.local 3.10.0-514.2.2.el7.x86_64 #1 SMP Tue Dec 6 23:06:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

mod_auth_openidcは最新版(2.1.3)のrpmが以下からダウンロードできますが、色々と前提となるパッケージなどを入れる必要があったので、ついでにソースからコンパイルしてしまいました。
 https://github.com/pingidentity/mod_auth_openidc/releases

以下が必要となるパッケージ群です。

yumでインストールするもの。(*-develがこんなに必要だったのはコンパイルしたからです)

  • git
  • httpd-devel
  • curl-devel
  • jansson-devel
  • openssl-devel
  • autoconf
  • automake

rpmでインストールするもの
  • cjose-0.4.1-1.el7.centos.x86_64.rpm
    • mod_auth_openidcと同じくここからダウンロードできます。
ソースからコンパイルするもの

  • hiredis
  • mod_auth_openidc


◆モジュールの導入手順

上記に記載したyumでインストールするものをyum installでまずはインストールします。
手順は書くまでもありませんが、以下の通りです。(だいぶ省略してます)
#yum install git
# yum install httpd-devel
# yum install curl-devel
# yum install jansson-devel
# yum install openssl-devel
# yum install autoconf
# yum install automake

同様にrpmでインストールするcjoseについても導入します。
# rpm -i cjose-0.4.1-1.el7.centos.x86_64.rpm


最後にコンパイルするモジュール群です。
まずはHiredisです。githubのレポジトリをクローンしてmakeします。
適当なディレクトリで以下のコマンドを実行します。
# git clone http://github.com/redis/hiredis
# cd hiredis
# make
# make install


そして、本命のmod_auth_openidcです。こちらもHiredisと同じくgit cloneして最新のソースを元にインストールしていきます。
git clone https://github.com/pingidentity/mod_auth_openidc/releases
cd mod_auth_openidc
./autogen.sh
./configure
make
make install

これで、/etc/httpd/modulesにmod_auth_openidc.soが出来上がります。


◆設定手順

設定は大きくは2つに分かれます。
 1つ目は、Apache自体にmod_auth_openidcを組み込む
 2つ目は、mod_auth_openidc自体の設定と対抗となるAzure ADへのクライアント登録
です。

順に解説していきます。

1.Apache自体にモジュールを組み込む

単純に出来上がったモジュールをロードします。
今回は認証関係のモジュールを読み込んでいる/etc/httpd/conf.modules.d/00-base.confへ以下を追記しました。
LoadModule auth_openidc_module modules/mod_auth_openidc.so



次に、保護対象とするコンテンツを決めていきます。
今回は単純にOpenID Connectを使ってAzure ADからアイデンティティ情報が取れていれば良いので、cgi-binディレクトリを保護対象として、環境変数にid_tokenの中身がちゃんと入ってきているかどうかを確認したいと思います。

/etc/httpd/conf/httpd.confに以下を追記します。
<Location /cgi-bin/>
   AuthType openid-connect
   Require valid-user
</Location>


もちろん、/var/www/cgi-binへテスト用のcgiファイルを置き、実行権限を付ける必要はあります。
今回は単純に環境変数を見たいだけなので、以下のスクリプトを置いています。
#!/bin/perl
print "Content-type: text/html\n\n";
print "<TABLE BORDER=\"1\">\n";

for $key (sort(keys(%ENV))) {
    print "<TR><TD><TT>$key</TT></TD><TD><TT>$ENV{$key}</TT></TD></TR>\n";
}

print "</TABLE>\n";
exit;


2.モジュールの設定(RPとしての設定)とAzure ADの設定(IdPとしての設定)

まず、Azure ADへクライアント登録を行います。

RPへ登録するために欲しい情報は、

  • client_id
  • client_secret

の2点で、これらはAzure ADへアプリケーション登録をすることにより取得が可能になります。

また、Azure ADへアプリケーション(つまりはOAuthクライアント)を登録する際に必要なのは、redirect_uri(アプリケーションのURL)です。

アプリケーションの追加をすると以下のパラメータを聞いてきますので、それぞれを設定します。

  • アプリケーション名: 任意の名前
  • アプリケーション・タイプ: Web app / APIを指定
  • サインオンURL: アプリケーションのURL(今回はhttp://oidc.eidentity.local/cgi-bin/にしています)
登録が終わると以下のダッシュボードが表示され、この中にあるアプリケーションIDがApache側へ設定するclient_idとなりますので、コピーしておきます。


次はclient_secretです。
ダッシュボードのAll settingsからキーを選択して新規にキーを生成し、保存をクリックすると表示されるのがclient_secretです。画面を遷移すると二度と表示できないので、ちゃんとコピーしておきます。


基本的にこれで情報はそろうのですが、最後にもう一つ。
mod_auth_openidcがリダイレクトしたり通信するIdPのエンドポイント情報を取得するためのメタデータURLが必要となりますので、これを確認しておきます。

以下のURLなので特に気にすることもありませんが、覚えておきます。
 https://login.windows.net/{ドメイン名}/.well-known/openid-configuration


では、最後となるhttpd.confへの設定追加をしていきます。
必要なのは以下のパラメータです。

  • OIDCProviderMetadataURL: Azure ADのメタデータURLを指定
  • OIDCClientID: Azure ADに登録したクライアントIDを指定
  • OIDCClientSecret: Azure ADに登録したクライアントシークレットを指定
  • OIDCRedirectURI: Azure ADに登録したアプリケーションのURLを指定
  • OIDCScope: スコープを指定。openid email profileあたりで問題なし
  • OIDCCryptoPassphrase: 必須なので適当にしてい


こんな感じになります。

OIDCProviderMetadataURL https://login.windows.net/pharaoh.onmicrosoft.com/.well-known/openid-configuration
OIDCClientID 0fa5bfc6-61da-47c1-9223-02f136594d09
OIDCClientSecret 6/2TYCeboBUgDB7rluxFmpLE8fYL45zgwhk38RTY5/E=
OIDCRedirectURI http://oidc.eidentity.local/cgi-bin/
OIDCScope "openid email profile"
OIDCCryptoPassphrase Password



これで設定は完了です。
早速テストしてみます。

◆動作確認

単純に先ほどAzure ADで保護したcgiにアクセスしてみます。

いきなりAzure ADのログイン画面へリダイレクトされますので、ログインします。

するとプロファイルへのサインインとアクセスに関する同意が求められるので同意します。


同意すると、cgiへリダイレクトされ、正しくアイデンティティ情報が取得できているのがわかります。
(OIDC_CLAIM_*という環境変数がid_tokenから取得された情報です)



かなり構成も簡単なので、レガシーなWebコンテンツやCGIなどが残っている場合は、今回紹介した方法でAzure ADとの連携を導入してみてはいかがでしょうか?


2017年1月4日水曜日

[Internet Weekフォローアップ]デモ環境の作り方⑥

こんにちは、富士榮です。

引き続きInternet Weekのフォローアップです。いよいよ最終回です。

利用部門で勝手に構築したOpenAMを完全に撤廃して、情シス管理のAzure Active Directory(Azure AD)にすべてをゆだねます。


すでに前回、G SuiteへのID管理(プロビジョニング)はAzure ADで実施する様に構成し、シングルサインオンについても経過期間ということでOpenAMと連携する様に設定を行いました。

今回はG SuiteとOpenAMの連携を解除し、Azure ADと直接連携することでOpenAMを使わないようにします。

では、早速初めて行きます。

<Step 3>

◆G SuiteとAzure ADのシングルサインオン設定をSAMLベースへ変更する

前回は、既存のOpenAMを活用するためにAzure AD上に登録したG Suiteのシングルサインオン設定に「リンクされたサインオン」を選択しましたが、今回からはG SuiteとAzure ADを直接連携させるため、ここの設定を「SAMLベースのサインオン」へ変更します。


SAMLを使って連携する属性を編集します。
今回、メールアドレス属性にGoogleで使うログインIDが入っていますので、ユーザ識別子として「user.mail」を指定します。


また、デフォルトでgivenNameやsurNameなどがAttributeStatementに含まれるように構成されますが、日本語の値が入っているとGoogle側でエラーになるので、不要な属性は削除しておきます。

この辺りは以前紹介した注意事項を参照してください。




次にSAMLアサーションに署名するための証明書を作成します。


注意)ここで証明書をダウンロードしてG Suiteへアップロードするのですが、現在新ポータルでダウンロードした証明書をアップロードするとG Suiteがエラーを出しますので、ここだけクラシックポータルへアクセスして証明書をダウンロードしてください。

G Suiteの出すエラー

クラシックポータルでの証明書ダウンロード

後は、G Suiteへ設定するAzure AD側のエンドポイント情報を確認します。
Google Appsの構成メニューを選択すると右側に設定すべきエンドポイントの情報が出てきますので、これをコピーしておきます。



◆G Suite側の設定を更新する

ここまでくればあとは、G Suite側へ設定を入れるだけです。
先ほどメモしたログインページのURL、ログアウトページのURL、パスワード変更URLを入力し、証明書をアップロードします。



尚、この設定を行っている間(Azure ADで設定変更~保存、G Suite側の保存)はシングルサインオン設定がAzure ADとG Suite側でズレているので利用者へ影響が出ますので、事前にアナウンスをしてから実施する様にしましょう。


◆動作確認を行う

これで、設定は完了です。
後は動作確認をしてみます。

ドメイン参加したPCでアクセスパネル(https://myapps.microsoft.com)へアクセスします。
Azure ADと連携されたドメインに参加しているので、Desktop SSOが有効なのでAzure ADのログイン画面が表示されることなくパネルへアクセスできます。


ここでGoogle Appsをクリックし開くとシングルサインオンされます。この際、前回までの構成だと一旦OpenAMへアクセスしていましたが、今回からは直接Azure ADと連携しているのでOpenAMを経由することなくG Suiteへアクセスしていることがわかります。

※もちろん、アクセスパネルを経由せずに直接G SuiteへアクセスしてもDesktop SSOが実行されるので、ユーザは何も意識することはありません。



後は、OpenAMを停止するだけです。
ようやく利用部門が抱えていた認証基盤およびアプリケーションの管理がすべて情報システム部門へ移管されました。

めでたし、めでたし。

◆最後に

今回、Internet Week向けのデモということであまり情シス目線だけに閉じたものはやめておこうというコンセプトで今回のコンテンツを作成しました。
また、オーディエンスが技術者の方が中心ということもあり、家に帰ってすぐに試せるもの、というのも大きなテーマでしたので、あえてOpenAMを引っ張り出してきました。


なかなか実世界では考えにくいシナリオだったかもしれませんが、技術要素としてのSAMLやKerberosを使ったDesktop SSOなどは覚えておいても損はありませんので、少しでもエッセンスが伝われば幸いです。






2017年1月2日月曜日

MVP Renewal 8th!!

こんにちは、富士榮です。

長いもので、8年目です。
引き続きEnterprise Mobilityという分野での受賞となります。



昨年は「日本におけるIDaaS元年」を目指し、書籍の監訳や各種カンファレンスやコミュニティ・イベントへ参加・登壇など様々な活動をさせていただき、かなり忙しい一年となりました。

今年はもう少し範囲を広げてグローバルに活動できるといいなぁ、と思っていますので皆様引き続きよろしくお願いいたします。

手始めに、英語版のBlogも始めてみます。コンテンツはこれから充実させていきたいと思います。

IdM Laboratory
http://idmlab-e.eidentity.jp/