[ AWSセキュリティ担当者必見] Config Rules 、Lambda、SNSによる中央集権型の管理統制について

#前置き
　私が勤めている会社では、約3年前からAWSの利用を積極的に検討してから、毎月のAWS利用費はもちろん、アカウントの数も急に増えてきました。自分が所属している部署もAWSの利用を推進しています。そして、AWSの社内利用において、セキュリテイ管理統制も行っています。今は(色々事情があっての)野良アカウントを除き、数十個のAWSアカウントを管理・セキュリティ統制をしています。
　AWSアカウントを作成した時に、管理統制用の設定を入れてから、AWSアカウントを渡すようにしています。しかし、管理するAWSアカウントを増えるほど、管理統制が難しくなります。チームメンバーの人数も多くないので、（各アカウントに分散されている設定やコードの運用管理など）社内AWS利用の管理統制を行うには大変な一面もあります。

#概要
　二三日前に、[【How to Centrally Manage AWS Config Rules across Multiple AWS Accounts】](http://blogs.aws.amazon.com/application-management/post/Tx23LIUFRTWOHNB/How-to-Centrally-Manage-AWS-Config-Rules-across-Multiple-AWS-Accounts)というAWSの方の記事を見ました、タイトルを見ただけで、きっと面白い内容だと思いました。その記事を一通り読みまして、こんなやり方もあるんだなと感心しました。(個人的)すごいソリューションだと思っています。そして、DeepDiveしてみました。
　その記事に書かれている内容を簡単にまとめてみますと、
　管理されるアカウントにあるConfig Rulesが
　　管理を行うアカウントにあるLambdaを呼び出し、
　　　管理されるアカウントの設定をチェックし、
　　　　その結果をConfig Rulesに表示するようにしています。

　自分の頭に浮かんできたイメージは以下の図に示す通りです。
<img width="771" alt="スクリーンショット 0028-07-09 22.30.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/117156/114e3144-8905-10d8-9614-5520d2aa2b89.png">
　これって、凄くないですか？！　統制用のコード（Lambda）は admin-account(管理を行うアカウント)にしか置かず、managed-accout(管理されるアカウント)がただそれを呼び出すだけです。コードが１つのアカウントに集約され、運用管理も楽ですね。
　また、自分なりに機能増強を拡張してみて、SNSを使って、Config Rulesの評価レポートを管理者に通知するようにしました。
　全体のイメージはこんな感じです。
<img width="565" alt="スクリーンショット 0028-07-09 23.27.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/117156/3b010ca3-606c-eee2-215d-320ec4ed16fe.png">

　今回は、【How to Centrally Manage AWS Config Rules across Multiple AWS Accounts】に紹介した例 (**CloudTrailのlog fileのvalidationが可能かどうかのチェック**) を沿って、一通り検証してみました。

#検証の流れ
　設定の手順は後ほど紹介しますが、まず、上記の図を使って、全体の流れを説明します。

- ① : ( managed-account ) Config Rulesが ( admin-account ) Lambdaをinvokeします。
  - Config RulesがAssumeRoleのARNとevent情報をLambdaに渡しています

- ② : ( admin-account ) LambdaがConfig Rulesから渡された情報を評価します、そして、managed-accountに対してAssumeRoleします。

- ③ : ( admin-account ) LambdaがAssumeRoleで得られたアクセス権限(putEvaluations)を使って、評価結果を( managed-account ) Config Rulesに送ります。

- ④ : ( managed-account ) Config Rulesが評価結果を受け取り、SNSに通知します。

- ⑤ : ( managed-account ) SNSがConfig Rulesからの通知を受け取り、予め設定されている通知先(今回はメールアドレス)に送信します。

#設定手順
##( admin-account ) Lambdaの設定

1. Servicesタブ → Lambda → Lambdaを新しく作成します。
<img width="998" alt="4.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/42bc2f17-3c44-200e-599f-debf100b5f03.jpeg">

1. 今回はblueprintのconfig-rule-change-triggeredを使います。
<img width="1386" alt="5.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/01176efc-0ba5-eeb3-b86d-ef4dceaafbe6.jpeg">

1. このまま「Next」をクリックします。
<img width="1820" alt="7.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/c304b74d-2801-0e30-2185-ea6f61e267a2.jpeg">

1. Nameは適宜で良いです(例では、Check-LogValidation-Enabledにします)、Runtimeを「Node.js 4.3」にします。
 - blueprintのコードを変更する必要がありません。
<img width="1820" alt="8.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/694f1302-243e-f7eb-7aea-7622c71818fb.jpeg">

1. Lambda用のロールを新たに作成しますので、Role欄に「Create a custom role」を選択します。
 - 既存のロールを利用して良いです。
<img width="1414" alt="9.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/57911c2c-9773-2e46-2746-de70728b66c0.jpeg">

1. Lambda用のロール名は適宜で良いです、(例では、lambda_basic_executionにします)
<img width="1092" alt="10.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/7fcc8af9-6bbc-f330-1894-a7971b149f36.jpeg">

1. ロールlambda_basic_executionを作成されたことを確認し、「Next」をクリックします。
 - ロールlambda_basic_executionはあとで、managed-accountに対してAssumeRoleできるように設定します。
     -  今回権限まわりをまだ確認できていないので、**ロールlambda_basic_executionにはデフォルトで設定されている権限以外に、検証用に<Font color="red">PowerUserAccess</font>を付けました**。
     <img width="1560" alt="28.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/962ea462-dc7e-4816-efea-80150af0caba.jpeg">
 - 必要に応じて、Memoryなどのconfigurationsを変更してください。
<img width="1392" alt="11.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/f9c47168-0d8f-4c4c-4f33-5639fb48b379.jpeg">

1. Lambdaの情報を一度確認し、作成します。
<img width="1840" alt="12.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/617b2ba4-820b-5ec5-da82-86b16cacc42c.jpeg">

1. Lambda(Check-LogValidation-Enabled)を作成されたことを確認します。
<img width="1852" alt="13.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/3e14d6e8-84ad-0eb0-381b-68cedd27c34c.jpeg">

1. managed-accountのConfig RulesがCheck-LogValidation-EnabledをInvokeできるように、下記のコマンドを実行します。
 - 例では、managed-account(AccountId:2847※※※※1948)がCheck-LogValidation-EnabledをInvokeできるように設定しています。( **AWSマネコンからは設定できません** )
<img width="1306" alt="14.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/68a8d1b3-45ff-2e38-9418-42d0ec5e3962.jpeg">

1. Lambdaの準備が終了

##( managed-account ) AssumeRole用のroleの設定

1. Servicesタブ → IAM → ロール → 「新しいロール作成」をクリックします。
 - ロール名は適宜替えてください 
<img width="666" alt="スクリーンショット 0028-07-10 9.02.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/117156/2d160054-34d3-5613-e09d-adb51dfd0ec1.png">

1. クロースアカウントアクセスのロール → 「所有しているAWSアカウント間のアクセスを提供します」を選択します。
![IMG_0427.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/fc58b495-f30d-1044-bbf7-181c815ce1ee.jpeg)

1. アカウントID欄に信頼する別のAWSアカウントを入力します。(自分の場合は8918****5875)
 - 「MFAが必要」のチェックを入れいないでください(入れてしまうと、クロスアカウントでコマンドを実行するたびに、MFAで２段階認証をしないといけなくなります)
![IMG_0428.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/6dc2f796-6df0-f92d-f167-cfba89646e68.jpeg)

1. ポリシーについては、後で設定しますので、今はこのまま「次のステップ」へ進みましょう。
![IMG_0429.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/1800dc93-3369-19c4-c2e0-b6856fb064b1.jpeg)

1. 一度確認します、問題がなければ、「ロールの作成」をクリックします。
![IMG_0430.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/ce0071ee-e7ad-bf46-9072-aadedbe6901b.jpeg)

1. AssumeRole用のロール(config-rules-admin)が作成されましたね。
![IMG_0431.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/4722e08b-7e17-87c8-f05c-592428d4040f.jpeg)

1. config-rules-adminをクリックして、「アクセス許可」の「インラインポリシー」で( admin-account ) Lambda用のポリシーを作成します。
![IMG_0432.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/124e117f-9441-5c4b-44cf-54e126a302e4.jpeg)

1. カスタムポリシーを選択します。
![IMG_0433.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/77d73543-bf8f-3c90-dc3c-d85542e5b150.jpeg)

1. 作成したいポリシーは以下になります。
![IMG_0434.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/678cd0c8-9bf0-5161-9d21-42bfb7c88cb9.jpeg)

1. ロールポリシーPutEvaluationsが作成されたことを確認します。
![IMG_0435.JPG](https://qiita-image-store.s3.amazonaws.com/0/117156/9c750a90-c67b-a150-04cc-2e04b6c70ce4.jpeg)

1. セキュリティを強化するために、信頼関係を修正しますので、「信頼関係の編集」をクリックします。
<img width="1516" alt="1.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/d307eccd-b08c-00a5-faf9-a825b49c33f2.jpeg">

1. 信頼するのを( admin-account ) Lambda用のロール(例では、lambda_basic_execution)に限定しますので、以下のように修正します。
<img width="1252" alt="2.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/6b69f1cf-3b4b-455b-4b2b-7736c4c3e79f.jpeg">

1. 信頼関係を修正されたことを確認します。
<img width="1400" alt="3.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/27ce47d8-4151-dc5f-19ee-adafb2701ef5.jpeg">

1. AssumeRole用のロールの準備が終了

##( managed-account ) SNSの設定
1. AWS ConfigのSettings → Amazon SNS topicの部分を以下のように設定します。
 - Topic nameは任意の名前で良いです。(今回はEvaluations-reportとします)
<img width="465" alt="スクリーンショット 0028-07-10 0.04.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/117156/86aaa52a-76aa-b890-0eee-6d6fac8da55c.png">

1. ServicesのSNS → Topic 、Evaluations-reportを選択します。
 - 新しいTopic(Evaluations-report)が作成されていますね
<img width="1470" alt="1.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/0aa31cb6-dde8-4d9c-0841-db211860aa26.jpeg">

1. Create subscriptionをクリックしますと、新しい欄が表示されます。
<img width="1354" alt="3.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/dd8438c4-f55b-51e0-3de1-840ea9c7d2d3.jpeg">
　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　↓　
Protocolを**Email**に選択し、Endpointに通知先のメールアドレスを入力して、Create subscriptionをクリックします。
<img width="1330" alt="4.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/1c7aa586-16e0-7d38-de65-7d1c9a8c111b.jpeg">

1. Create subscriptionをクリックすると、確認用のMessageがAWSから入力されたメールアドレスに送付されます。確認を取れるまで、Subscription IDのところには**PendingConfirmation**となっています。
<img width="1502" alt="5.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/cbf8008e-49dc-536d-6d37-1757ab245349.jpeg">

1. 送信されたメールを確認し、Confirm subscriptionをクリックします
<img width="1296" alt="6.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/27c6b510-92d6-324e-6d98-1535f7c9a4d1.jpeg">


1. AWSが確認を取れれると、Subscription IDのところにはSubscription IDの情報が表示されるようになります。
<img width="1846" alt="7.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/97e53f13-8c94-a61a-fdad-b1f78626fcea.jpeg">

1. SNSの設定が完了





##( managed-account ) Config Rulesの設定

1. Servicesタブ → Config → Rules → Add ruleにて、custom ruleを作成します。
<img width="1770" alt="16.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/0a2666fc-61aa-b78e-b3a1-34876966c2e2.jpeg">

1. custom ruleのconfigを設定します。
 - Nameは適宜で良いです。(例では、CloudTrail-LogValidation-Enabled)
 - AWS Lambda function ARN欄に、( admin-account ) Lambda **Check-LogValidation-Enabled**のARNを記入します。
 - Triggerについては、図に示す通りに設定します。
 - Rule parametersはKeyを**executionRole**に、ValueをAssumeRole用のロール**config-rules-adminのARN**に設定します。
<img width="1442" alt="17.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/fa253b1a-45bd-7281-93bb-edf15d21dd17.jpeg">
<img width="1122" alt="18.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/14b77eba-11bf-d778-6adb-88ca1892bbd4.jpeg">
<img width="1420" alt="19.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/0c6e3bb2-2f7c-8e07-880d-4b714b722f27.jpeg">

1. config ruleを作成されましたら、 準備が終了
<img width="1812" alt="20.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/0f30c57f-f93d-7e1e-ab87-bdeae10d4292.jpeg">

#検証の前提条件
　managed-accountに既にCloudTrailが設定されていることが必要です。当然のことなんですが、CloudTrailを設定されないと、（評価対象がないから）Config Rulesが評価できません。
　ちなみに、こんな検証用のCloudTrailを作りました。「Enable log file validation」は「**No**」になっています。

<img width="1218" alt="24.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/43a8f64e-1388-2fa7-88b2-7fbe318d78ab.jpeg">

#検証結果
##Enable log file validationがNoの場合
###Config Rules
　リソースCloud-Trailに対する評価はNoncompliantになっていますね。
<img width="1526" alt="21.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/efa44217-e66d-01ef-9cb8-de1f6f7877ed.jpeg">
↓　↓　↓　↓　↓　↓　↓　↓　
<img width="1496" alt="22.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/dcf938f4-3604-0c75-4580-c192e9c93c78.jpeg">

###E-mail通知
　管理者のE-mailにConfigの評価レポートが送信されます。これで、どのリソースがNoncompliantになっているかも分かりますね！

<img width="1442" alt="23.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/f589b0e9-c8c7-a8d9-0b74-11a92bddfbe2.jpeg">



##Enable log file validationがYesに設定した場合
###Config Rules
　リソースCloud-Trailに対する評価はちゃんとCompliantになりました。
<img width="1514" alt="25.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/46c8e033-37af-6b81-198f-3ca9a35fd5cb.jpeg">
↓　↓　↓　↓　↓　↓　↓　↓　
<img width="1516" alt="26.pic.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/a61786d4-0165-46da-9f55-e20397b3bb8d.jpeg">

###E-mail通知
　管理者のE-mailにConfigの評価レポートが送信されます。ちゃんとlogfileのvalidationをenableにしましたので、Compliantになったことを管理者に通知します。
<img width="1260" alt="27.pic_hd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/117156/b6a55a2d-1748-f4ae-fe84-4eaacdd5e027.jpeg">

#まとめ
　今回は、LambdaとConfig Rulesを使って、CloudTrailのlogfileのvalidationをチェックし、評価結果を管理者に通知することを検証しました。意外と簡単にできます。
　Config RulesはAWSのリソースをちゃんとルールに沿っているかの確認できますので、AWSセキュリティ担当者もしくは内部統制者にとって、非常に強力な"武器"だと思っています。コンプライアンス違反になったリソースを即座に検知・通知ができますので、個人的にもさらにConfig RulesをDeepDiveして、業務にも活用したいと思います。
　現在Config Ruleに使えるマネージドルールが９つあって、GitHubにも便利そうなカスタムルール([awslabs/aws-config-rules](https://github.com/awslabs/aws-config-rules))があります。興味がある方は一度やってみてください！

#最後
　余談になりますが、少し前に、IAMユーザ・AccessKeysの運用管理に使うものを作ってみました、（トライアル運用中ですが）興味がある方は下記２つの投稿を見てください。

- [Lambda & CloudWatchEvents & Slackで 長期的にログインしていないIAMユーザを検知・通知する](http://qiita.com/jobbin/items/21737cc258cf4268b176)
- [Lambda & CloudWatchEvents & Slackで 長期的に利用されていないAccessKeyを検知・通知する](http://qiita.com/jobbin/items/986225f0536697685e13)