うぇっしゃっしゃーす。
クラウドアーキテクチャチームの齋藤です。
AWSをご利用の方の中で、マルチアカウント運用されている方ってどれくらいいらっしゃるでしょうか。
アカウント一つならまだしも、いくつもAWSアカウントがあって個別にIAMユーザー発行とかしてると退職者アカウントの削除忘れとかあったり、色々面倒ですよね。
え?わからないって?
ほんじゃぁ、ソースコードのいろんなところに同じような処理をコピペしたせいで、修正加えるときに全部手作業で直さないといけないめんどくささを思い出してください。
めんどいでしょ?
同じような処理は一か所にまとめて使いまわせるほうがメンテナンス楽でしょ?
いやオブジェクト指向的な話したいわけじゃないんですけどね。
そんなわけで、いろんなところで独自に管理してたアカウント情報を一か所にまとめて、管理の手間やリスクを減らしてやろうじゃん。
っていう話です。
別にマルチアカウントじゃなくても、社内のいろんなアカウント管理が必要なものは全部一つのIdPにまとめたいみたいな話もあると思うので、参考になると思います。
それじゃぁいってみよう。
概要
以下を実現します。
- AzureADでアカウント管理したうえで、その情報を利用してAWSSSOでAWSOrganizations配下のアカウントにアクセスできるようにする。
- 各種アカウントごとに設定されたアカウント管理者側で、そのユーザーに与える権限を設定できるようにする。
これを行えば、様々なメリットがあります。
- 今まではアカウント管理の煩雑さの問題でSREとか限られた人しか使えなかったAWSコンソールを、環境に触るすべての関係者に使ってもらうことができるようになります。
- AWSコンソールを配布できるため、それらの機能をコンソールをつかえない人に提供するために行っていたビューワーなどの開発コスト、管理コストを排除できます。
- AWSの機能実装強化の恩恵をそのままダイレクトに得られるようになり、継続的に業務が便利になり続けます。
- 複数アカウントすべてにIAMユーザーを作成するなどしていて発生していた管理コストも、IdPで一括管理されることで大幅に楽になります。
- IdPさえ正しく管理されれば、アカウント管理者側の対応漏れがあってもアカウントを危険にさらしません。
- etc...
AWS SSOとは
「複数の AWS アカウントへのアクセスの一元的な管理を容易にし、 割り当てられたアカウントすべてに対する 1 か所からのシングルサインオンアクセスをユーザーに提供できるようにする AWS のサービスです。」
AWSSSO を使用すると、AWSOrganizations にあるすべてのアカウントに対するアクセスとユーザーアクセス許可を簡単に一元管理できます。
AWS SSO では、個々のアカウントにおける追加のセットアップを必要とすることなく、アカウントに必要なアクセス許可のすべてが自動的に設定および維持されます。
ユーザーのアクセス許可は一般的な職務に基づいて割り当てることができ、特定のセキュリティ要件を満たすためにこれらのアクセス許可をカスタマイズすることも可能です。
AWSSSOがない場合の課題
AWSSSOが無くても、誰にでもAWSコンソールを提供することは可能です。
それには対象者一人一人にIAMユーザーを作成してもらうことになるでしょう。
(もしくはこんな実装をしなきゃいけないかもしれません...)
もし社員が3000人いて、いくつもAWSアカウントがあるとしたら、そのすべてのアカウントにいちいちIAMユーザーを作成しますか?
MFAを入れるなら一つ一つのアカウントに別々のMFAもひつようになります。
ユーザー側は全部アカウントに別に管理できますか?
IAMユーザーを作成したとして、退職者が出た時の管理はどうでしょうか?
なかなかに面倒でしょう?
そんなわけで、複数のアカウントに1つの認証でアクセスできる機能としてAWSSSOが用意されているわけです。
ちなみに、SSO用のWebページはパブリックに公開されるんですが、特定ネットワークからじゃないと認証が通らないような設定も可能です。
ページも見せたくないって場合だとどうなんだろうなぁ。
IdP(Identify Provider)とは
ユーザーの認証情報を保存・管理するサービスです。
つまり、社内で使っている様々なサービスへの認証にIdPにある認証情報を使うことで、個別に認証情報を管理する必要がなくなるわけです。
もしAWSSSOを有効化してAWSSSOで認証情報を一括管理できたとしても、それはAWSSSO以外のサービスとは独立して管理されるだけです。
つまり、社内にいくつも認証情報を必要とするサービスがあれば、結局複数の認証情報を管理しなければならないという問題からは逃れられません。
そこでこのIdPを導入しAWSSSOと紐づけることで、その他のサービスとも認証情報を共有して管理できるようにし、管理者はIdPだけみればいいような状況を作れるわけです。
ちなみにMFAも設定できるから安心してくれよな。
もし違うIdPをすでに使っているよという場合、AWSSSOがサポートしてるIdPかどうかは確認しておいてくださいね。
認証と認可の分離
まず認証と認可の違いですが、簡単に言えば以下です。
- 認証はサービスへのアクセスに必要な物。
- 認可はサービスの機能を使用する権限。
ここまで説明してきた、AWSSSO+AzureADとはあくまで認証の部分の話です。
AWSSSOでは当然認可も設定できますが、業務上AWSアカウントを管理する者がアカウントごとに存在していて、それぞれで認可するアクセスレベルも別々に存在することのほうが多いと思います。
そこで、AWSSSO+AzureADでアカウントのコンソールを開けるところまでは実現しつつ、その中で何ができるかはAWSアカウント側で管理したいという需要があるわけです。
これには、AWSIAMのロールを使用して管理します。
- AWSSSO+AzureADにて各種アカウントに直接サインオン
- サインオン直後の状態では各種リソースへの認可を持たない状態(SSO用のロールにはスイッチできる権限をもたせる)
- アカウント内でSSOユーザー用ロールにスイッチロールさせることで、アカウント側に用意されたIAMロールに認可の管理を移譲できる
これで認証と認可を分離することができました。
ただし、これだけだと例えばチームメンバーと他社員で権限を分けたいというときに困りますよね。
IdPで管理することもできますが、誰がどんな権限を持っているかのロールとのマッピングをIdP側で持たなければなりません。
高頻度のチーム編成変更が想定される成長企業などでは、その運用は耐え切れなくなるなるでしょう。
そうすると、IdPでどの認証情報がどのロールを持つかのマッピングを管理せず、純粋にAWSアカウント管理側で認可を行いたいとおもいませんか?
じつはちゃんとAWSはそれも対応できるような機能があります。
それがAttributes-Based Access Controlです。
以前につかってみた記事を書いてあるので、興味があればこちらもご覧ください。
ここまでのまとめ
雑に図にするとこんな感じです。
マスターアカウントというのは、AWSOrganizationsで複数のAWSアカウントを統括しているアカウントのことですね。
まとめて利用料金とか払ってるアカウントです。
トレーサビリティ観点の話とか、他にもいろいろたくさんの検証や検討があったけど、まぁそういう色々幅広そうな話は自社のコンプラとかとお話していただくとして、さっそく設定手順やっていきましょう。
設定手順
ずらっと一覧と、AzureAD,AWSSSOのどっち側の操作が必要かをぱっと並べてます。
一杯あるけどまぁなんとかなるでしょ。
「※」は必須ではありませんが、知ってると役に立つと思います。
AzureAD自体は導入済みという前提で進めさせてください。
なお、AzureADのライセンスは複数ありますが、今回は AzureAD PREMIUM 2 を前提に進めさせていただきます。
1.アプリケーションの有効化
【AWS AWSSSOの有効化】
【AzureAD エンタープライズアプリケーションの作成】
2.AzureADとAWSの連携
【AzureAD フェデレーションメタデータ XML ファイルをダウンロード】
【AWS AzureADメタデータのアップロードとAWSメタデータのダウンロード】
【AzureAD AWSのメタデータを登録】
3.ユーザー情報管理設定
【AzureAD エンタープライズアプリケーションへのユーザー追加】
【AWS ユーザーの自動プロビジョニング】
【AzureAD ユーザーの自動プロビジョニング】
※【AzureAD MFAを強制する】
※【AzureAD メールアドレスをAWS側で読み込めるようにSAMLアサーションに含める】
4.SSO設定
※【AWS SSOでABACを有効化する】
【AWS アクセス権限を作成する】
【AWS アクセス権限・ユーザーを紐づける】
5.動作確認
【AWS シングルサインオンを検証する】
6.設定変更監視
【AWS SSOの設定変更監視を設定】
7.問い合わせ対応のナレッジ
【AzureAD MFAの再登録】
8.設定削除
【AWS SSO設定の削除】
【AWS 監視設定の削除】
【AzureAD アプリケーションの削除】
1.アプリケーションの有効化
まずAWSSSOとAzureAD、それぞれで機能を有効化する必要があります。
【AWS AWSSSOの有効化】
AWS Organizations サービスを設定し、[すべての機能] を有効化します。
この設定の詳細につい ては、『AWS Organizations ユーザーガイド』の「組織内のすべての機能の有効化」を参照してください。
https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/sso-ug.pdf
今回は東京リージョンで有効化します。
SSOはマスターアカウント(オーガナイゼーションのアドミンアカウント)の一つのリージョンでのみ有効化可能です。
###【AzureAD エンタープライズアプリケーションの作成】
名前の設定は自由に決めて問題ありませんが、わかりやすい名前にしましょう。
ギャラリーの選択肢にAWSがありますが、ノンギャラリーにしないと後述する手順の自動プロビジョニングがうまく動きませんので注意してください。
これでアプリケーションが生成されます。
2.AzureADとAWSの連携
AWSSSOとAzureADでお互いのメタデータを交換して登録することで連携することができます。
【AzureAD フェデレーションメタデータ XML ファイルをダウンロード】
AWSのSSOとAzureADのSSOを連携するために、メタデータを交換する必要があります。
まず、今回設定したAzureADのエンタープライズアプリケーションからメタデータをダウンロードします。
シングルサインオンの方式はSAMLを使用します。
【AWS AzureADメタデータのアップロードとAWSメタデータのダウンロード】
Azureのメタデータを登録し、AWS側のメタデータをダウンロードしましょう。
IDソースを外部のプロバイダーにして、メタファイルのダウンロードと、AzureADのメタデータアップロードをします。
【AzureAD AWSのメタデータを登録】
この時点で、Azure AD のユーザーと一致するユーザー名である AWS Single Sign-On のユーザーアカウントを既に持っている場合、Testボタンをクリックして設定を確認することができますが、現在は特に作っていないのでtestは通りません。
3.ユーザー情報管理設定
AzureADに認証情報が追加された場合などに、自動でAWSSSOにもプロビジョニングする設定を行います。
また、サインオンにはMFAを強要するように設定できます。
また、Attributes-Based Access Control(ABAC)を行うために、AzureADに登録されたユーザー個別の情報をSAMLアサーションに含める設定を行います。
【AzureAD エンタープライズアプリケーションへのユーザー追加】
AWSとの連携設定をする前に、SSO対象のユーザーをAzureAD上でアプリに連携しておきます。
ユーザーは個別に指定するのではなくグループにしておいてまとめて連携してしまいましょう。
今回は使用しませんが、AWS SSOではユーザーをグループで管理している前提でグループ別に異なるアクセス権限を付けることができます。
その機能を使用する場合、エンタープライズアプリケーションにユーザーを連携するときにユーザーをグループで仕訳する必要があります。
ユーザーをグループで管理するためには、AzureAD PREMIUM 1,2のどちらかのライセンスが必要になります。
こちらは有償オプションになります。
アクティブ化した後キャッシュが残ってると反映されないので、キャッシュクリアするかシークレットウィンドウで開きなおすと反映されます。
グループを作成していない場合、グループ単位で連携することができません。(ここで選択できるのが、ユーザー単位だけになっていると思います)
グループがない場合はグループを作成してください。
これにより、ユーザーごとにアクセス権限を管理する必要がなくなり、グループ単位でアクセス権限を管理できるようになります。
AzureAD ユーザーグループの作成手順
グループの種類はセキュリティ、名前は任意です。
【AWS ユーザーの自動プロビジョニング】
AWS SSOを行う場合、AWS側でもユーザーを管理する必要があります。
そこで、自動プロビジョニングを有効化します。
トークンとエンドポイントアクセストークンIDをコピーしておいてください。
【AzureAD ユーザーの自動プロビジョニング】
AWS SSOを行う場合、AWS側でもユーザーを管理する必要があります。
そのため、AzureADからユーザー情報をAWS側に送れるように設定しておく必要があります。
ここで自動プロビジョニングの設定を行うわけですが、ノンギャラリーアプリケーションで作成している場合は、テナントURLとトークンで設定を行うことができます。
この情報は【AWS ユーザーの自動プロビジョニング】にて確認できます。
テナントのURL = SCIMエンドポイント
シークレットトークン = トークン
プロビジョニングエラーがあった場合のメールの送信先は設定者・管理者のものを指定しておいてください。
40分に1度同期が実行されるので、初期サイクルの完了後に同期が終わるのを待ちましょう。
増分実行のため最初の同期は約40分ごとに発生する後続の同期よりも時間がかかることに注意してください。
進行状況を確認するには、Azure AD で同期の詳細または監査ログを表示するか、AWS Single Sign-On コンソールのナビゲーションパネルで [Users] を選択します。
【AzureAD MFAを強制する】
統制上、AWSアカウントへのログインにはMFAが必要ということもあると思います。
こちらを設定します。
AWS側では現状グループに対してMFAを強要する手段がないので、AzureAD側で設定する必要があります。
これで選択したアプリケーションではMFAが強要されます。
【AzureAD メールアドレスをAWS側で読み込めるようにSAMLアサーションに含める】
こちらは認可と認証の分離のための設定ですね。
今回はAWS側でAzureADの認証情報からメールアドレスを受け取ります。
ABACでメールアドレスを参照して個人を特定して権限の強さを変更したり、アシュームロール可能なロールをコントロールできるようになります。
これでAWSアカウント管理者が認可について責任を持てるようになるわけですね。
AWS側でAzureADで持つ情報にアクセスする場合、それをAWSが読み取れる形式でアサーションに含める必要があります。
アサーションはSAMLでの認証に使われるデータで、中にユーザー情報などをもっているものです。
認証レスポンスの SAML アサーションを設定する
AzureAD の SAML設定手順(オプション)
AccessControl:Email
https://aws.amazon.com/SAML/Attributes
user.mail
AccessControl:Emailでどんな名前でSAMLアサーションに登録されるか決まります。
名前空間はAWS側が提示しているもので、固定です。
user.mailのところでAzureADのどこの情報を引き継ぐが決まります。
今回はユーザー情報のmail情報をEmailという名前でSAMLアサーションに含めました。
ここらへんはお手元の環境で好きなように連携していただくといいと思います。
4.SSO設定
【AWS SSOでABACを有効化する】
これでAWS側でSAMLアサーションに渡されたAccessControl:Emailを読み取れるようになりました。
【AWS アクセス権限を作成する】
まずユーザー、グループが同期されていることを確認してください。
アクセス権限セット(権限)を作成し、ユーザーもしくはグループにアタッチします。
これはAWSアカウントにAWSSSOでサインオンした直後に渡される権限になります。
全社員に共通で持たせる権限になるので、アシュームロール以外の権限を渡さないようにしましょう。
以下のような内容にすると、IAMロール名の末尾がForAwsSsoRoleで終わるロールにのみアシュームロールを許可できます。
また、ABACで引っ張ってきたメールアドレスを参照して@xxxx.co.jp以外がアクセスした場合はすべての権限を無効化してます。
SSOを活用したいアカウント管理者は、アカウント毎に*ForAwsSsoRoleロールを作成しSSOユーザへの認可を設定します。
これによりSSOユーザーがそのロールにアシュームすることでアカウント内での操作権限を得るという状態を実現できます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAssumeRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/*ForAwsSsoRole"
},
{
"Sid": "BlockUsersOther",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalTag/Email": "*@xxxx.co.jp"
},
"Bool": {
"aws:ViaAWSService": "false"
}
}
}
]
}
これでAzureADの特定のグループに所属するユーザーで、@xxxx.co.jpのメールアドレスを持つユーザーにだけ、*ForAwsSsoRoleへのアシュームロールを許可できました。
Ipの制御もしたいならCondition、NotIpAddressを追加しましょう。
IPの制限についてはアカウント管理者側で行いたいということであれば不要です。
【AWS アクセス権限・ユーザーを紐づける】
ここで先ほど作成したアクセス権限セットとユーザー(グループ)、そして対象アカウントを紐づけます。
これにより、どのユーザーがどのアカウントに対してどんな権限を持つかということが明示されます。
ここまでの作業で、同期されたユーザーはSSOを行うことができるようになります。
やったね!
5.動作確認
【AWS シングルサインオンを検証する】
以下URLにアクセスすることでSSOを行うことができます。
URLについてはカスタマイズから変更することができるため、どのペイアーアカウントに対応するかわかりやすいものに変更するのもよいでしょう。
この画面が表示されたら、手元のデバイスで認証を行ってください
※MFAがない場合は登録画面が表示されます。
なおこの時点では何も権限が無いので、SSO後にアカウント管理者が用意したロールへアシュームロールしてもらう想定です。
※トラブルメモ
うまく行かない場合があったらしく、AWS SSOの「SAML 2.0 証明書」の管理で、Azure AD側の証明書を手動でインポートするとうまくいくようになったようです。
6.設定変更監視
【AWS SSOの設定変更監視を設定】
この俺がSSO設定するだけの単純な話で終わらせるわけないぜ。
というわけでAWS SSOの設定変更を検知し、アラートを飛ばす設定を行います。
あらかじめ組織の証跡が作成されていることを確認してください
ログを記録している証跡を確認し、ロググループを確認してください。
フィルターパターン
{ ($.eventName = AssociateDirectory) || ($.eventName = AssociateProfile) || ($.eventName = CreatePermissionSet) || ($.eventName = CreateProfile) || ($.eventName = DeleteProfile) || ($.eventName = DeletePermissionsPolicy) || ($.eventName = DeletePermissionSet) || ($.eventName = DisassociateDirectory) || ($.eventName = DisassociateProfile) || ($.eventName = PutPermissionsPolicy) || ($.eventName = UpdateProfile) || ($.eventName = UpdateDirectoryAssociation) }
フィルター名
AwsSsoChangeAudit
メトリクス名前空間
AwsSso
メトリクス名
AwsSsoChanges
メトリクス値
1
通知先(アラートを飛ばしたい対象)のトピックが既に存在するならそれを選んでください。
無い場合は新しいトピックの作成からアラートを送信したいユーザー、メーリングリストを指定してください。
アラーム名
AwsSsoChangesAlert
アラートが登録されると、ログ不足の場合はデータ不足で、しばらく待っていればアラームもしくはOKに移動します。
アラームに移動したときにメールが飛べばOKです
設定が終わったらOKになることを確認し、その後AWS SSOの設定を変更してみてアラーム状態に推移しメールが送信されることを確認しましょう
これでAWS SSOの設定は完了です。
7.設定削除
【AWS SSO設定の削除】
以下の操作を行うことで、AWS側のSSO設定をすべてきり戻すことが可能です。
【AWS 監視設定の削除】
以下の操作を行うことで、AWS側のSSO変更監視設定をすべてきり戻すことが可能です。
【AzureAD アプリケーションの削除】
以下の操作を行うことで、AzureAD側の設定をすべてきり戻すことが可能です。
8.おまけ
【AzureAD MFAの再登録】
本手順はSSOの設定では必要ありません。
MFAを変更したいなどの問い合わせがあったときに使用する手順です。
これが行えない場合、以下手順でも対応できます。
QRコードを読み取って次へ あとは1回承認を通せばOK
【AWSアカウント側のロール作成例】
以下はあくまで例ですので、実際にPrincipalで指定するフェデレーションロールはアカウント内のロール一覧から「AWSReservedSSO_BasicAccessRights_*」を探し、リソースネームを確認してください。(AWS SSOによって自動生成されているはずです)
厳密なコントロールが不要であればアカウント単位の指定でも問題ありません。
このロールであれば、指定したメールアドレスとフェデレーション(サインオン)ユーザー名が一致するユーザーのみがアシュームロール可能であり、"0.0.0.1/32","0.0.0.2/32"以外からのアクセスをうけつけないというようなものになります。
一部のユーザーにだけ使用許可するロールはこれでいいですし、全体に許可したいならPrincipalだけで絞ればOKです。
なお、ロールの信頼ポリシーの文字数制限は、デフォルトで 2048 文字ですが、拡張可能なパラメータとなっています。
ユーザーが増えてもロールを拡張すればいいし、最悪ロール分けても良いですね。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::*****:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_BasicAccessRights_*****"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"saml:sub": [
"saito_ry@xxxxx.co.jp",
"saito_ry2@xxxxx.co.jp",
"saito_ry3@xxxxx.co.jp",
"saito_ry4@xxxxx.co.jp"
]
}
}
},
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::*****:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_BasicAccessRights_*****"
},
"Action": "sts:AssumeRole",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"0.0.0.1/32",
"0.0.0.2/32"
]
}
}
}
]
}
おわりに
おぎゃーーーーつかれたーーーーー。
長すぎる膨大すぎるめんどくさすぎる。
まぁでもきっとこの世のだれかの役に立つと信じて、社会貢献のために頑張りました。
というのは冗談です。
僕はちやほやされるためにこういう記事を書いてるので、この記事が良いと思った方はちゃんとGoodボタン、高評価、チャンネル登録よろしくお願いします。
褒めてください。
以上、齋藤っした。