(初心者向け) AWSのアカウントを守るために最低限やっておきたいことまとめ ( IAMメイン )


## はじめに
これまで業務でAWSを触る機会もあったのですが、1からアカウントを運用するなどは経験がなく基本的な部分が抜けているなと感じたので、自身の知識の確認も含めて、AWSアカウントを安全に利用するためのセキュリティの基礎中の基礎をまとめてみました。
 
## 対象読者
* AWSアカウントを開設してばかりの方
* AWS IAMの設定内容に自信がない方
* IAM ベストプラクティスで推奨されている内容をさくっと確認したい方
 
## AWSにおけるセキュリティの考え方
AWSはさまざまな便利なサービスをクラウドサービスとして提供してくれていますが、クラウドサービスだからといってセキュリティのあらゆる部分をAWSが担保してくれるわけではありません。

セキュリティに関してAWSがどの範囲は責任を持ってくれるのか、また利用者側がどの範囲のセキュリティを検討しなくてはいけないのかは[「責任共有モデル」](https://aws.amazon.com/jp/compliance/shared-responsibility-model/)という形で明示されています。

https://aws.amazon.com/jp/compliance/shared-responsibility-model/
 
####[責任範囲で分類したAWSサービスのカテゴリ]
 
責任共有モデルでの責任の分担は大きく下記の3つのカテゴリに分類され、それぞれでAWSと利用者側の責任範囲が異なります。

* インフラストラクチャサービス(例：Amazon EC2、Amazon EBS、Amazon VPC)
* コンテナサービス(例： Amazon RDS、Amazon EMR、Amazon ECS)
* 抽象化されたサービス(例：Amazon S3、Amazon DynamoDB)

大まかには、インフラストラクチャサービス > コンテナサービス > 抽象化されたサービスの順で柔軟に運用できる分だけ利用者の責任範囲が増えていきます。

これらの各カテゴリごとのセキュリティの責任範囲については、[AWS セキュリティのベストプラクティス](https://d1.awsstatic.com/International/ja_JP/Whitepapers/AWS_Security_Best_Practices.pdf)を参照することで確認ができます。

####[AWSサービス別のセキュリティ / 責任範囲について調べたい場合]
AWSの各サービス別のドキュメントにはそのサービスのセキュリティ / 責任範囲が明示されています。
それぞれのサービスのセキュリティの責任範囲について確認したい時は [AWS Security Documentation](https://docs.aws.amazon.com/security/?secd_intro2) からたどると便利です。

## AWSのアカウントを守るために最低限やっておきたいこと
AWSのどのサービスを利用するにしても、Identity and Access Management（IAM）を利用した権限の管理は必須となります。

### (AWS IAMの主な機能)
* AWSリソースを利用する ユーザーやグループの作成/管理
* 各ユーザーやグループのAWSリソースへのアクセスの権限管理
* ロールを用いたAWSサービスが他のAWSリソースへアクセスする際の権限管理

これらの機能を利用して、AWSのアカウントを安全に利用できるように設定をしていきます。

参考:
[Identity and Access Management: The First Step in AWS Security](https://www.slideshare.net/AmazonWebServices/identity-and-access-management-the-first-step-in-aws-security-84032590)

https://www.slideshare.net/AmazonWebServices/identity-and-access-management-the-first-step-in-aws-security-84032590

## アカウント保護するために最初にやっておきたいIAMの設定
ここでは、[IAM でのセキュリティのベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html) と [AWS Well- Architected フレームワークのセキュリティの章](https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.question.SEC_2.ja.html) を参考にAWSを安全に利用するために最初にやっておきたいIAMの設定をまとめます。 

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html

https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.question.SEC_2.ja.html

###(最初にやっておきたいIAMの設定)
* ルートユーザーのMFAを有効化して、アクセスキーを削除する
* 各個人別のIAMユーザーを作成する
* 各ユーザーにMFAを強制するようなポリシーを作成する
* 組織上の役割や権限ごとのグループ/ロールを作成する
* 役割や権限ごとに利用するサービスのみにアクセスできる最小限のポリシーを作成する

### ルートユーザーのMFAを有効化して、アクセスキーを削除する
ルートユーザーは全てのAWSリソースにアクセスができるので、不正ログインがされた場合に甚大な被害を及ぼします。
少しでも、セキュリティのレベルを上げるためにアカウントを受け取ったら下記の手順ですみやかにルートユーザーのMFA(多要素認証)を有効にしましょう。

![computer_crime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/0dd15cda-09c4-cfda-2ae3-adfa67174f08.png)

**(ルートユーザーのMFAを有効化)**
公式のMFA設定手順: [AWS アカウントの root ユーザーの仮想 MFA デバイスを有効にする (コンソール)]
(https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root)
QiitaでわかりやすかったMFA設定手順: [AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)
 
**(ルートユーザーのアクセスキーを削除)**
AWSのユーザーはコンソールからだけではなくアクセスキーを発行することで、CLIなどからでもアクセスが可能です。
このアクセスキーが流出した場合にも不正にAWSアカウントの操作がされてしまうので、ルートアカウントのアクセスキーは発行しないようにします。
 
**(AWS ユーザーのアクセスキーの管理の手順)**

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey


アクセスキーが流出した怖い事例だとこんなのもあります。

https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694

#### 各個人別のIAMユーザーを作成する
ルートユーザーの認証情報が流出した場合、インシデントの被害が大きくなってしまうため、普段の運用には利用せず新規でIAMユーザーを発行するということが原則となります。

参考までに [ルートユーザー認証情報が必要なタスク](https://docs.aws.amazon.com/ja_jp/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root) は下記のリンクで確認できます。
ほとんどの作業をルートユーザー以外のIAMユーザーでできることが確認できるかと思います。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root


IAMユーザーを新規発行する場合には、利用する人間に対して関連づけられるように個別に発行します。
IAMユーザーの使い回しは誰がどのような操作をしたのか後から追跡するのが不可能になるのでNGです。

詳細はこちらに記載しませんが、AWS IAMは OpenID Connect または SAML 2.0 (Security Assertion Markup Language 2.0) と互換性のある IdP をサポートしているため、既存のID管理 システムと関連づけて管理することも可能です。
参考: [ID プロバイダーとフェデレーション](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers.html)

**(IAM ユーザーの作成手順)**
1 AWSアカウントにログイン
2 画面上部のツールバーに[IAM]と入力して、IAMのサービス画面に遷移
3 画面左のメニューから[ユーザー]を選択
![user.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/150a9807-32df-64a1-fa10-428eb167cce8.png)

4 [ユーザーを追加]を選択
5 必要な内容を入力します。意図せずアクセスキーを発行しないようにするため、[アクセスの種類]はAWSマネジメントコンソールにのみチェックをつけるようにしてください。
![add_user2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/7e2b42f9-a57a-cce1-3f67-431567c8de2b.png)

6 最初は特に何の権限も付けずにユーザーの作成を行います。(後ほど、必要な操作の権限を付与します。) 
7 最後のステップまで、完了するとユーザーの作成ができます。

これでユーザーの作成はできましたが、まだ何の権限も付与していないので、このユーザーでログインしても何もできません。
そのため、以降の作業でこれから必要な権限を付与していきます。
 
### 各ユーザーにMFAを強制するようなポリシーを作成する
AWSでユーザーやアプリケーションにどのAWSリソースに対してどのような操作を許可/拒否するのかをまとめた設定を``IAM ポリシー``と呼びます。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html

まず、やりたい操作の権限を各ユーザーに与える前にMFA(多段階認証)の認証をユーザーに強制するようなポリシーを作成して、ユーザーに付与できるようにしましょう。

**(MFA(多段階認証)の認証をユーザーに強制するポリシーの作成)**
ポリシーの作成が初めての場合はどうやってポリシーを作成すればいいか悩ましいかと思います。
しかし、ありがたいことにAWS公式で``「MFAが未認証の場合は、MFAデバイスの設定しかできないポリシー」``を公開してくれているのでこちらを参考に設定することで簡単に設定が可能です。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-mfa-only.html

**(ポリシーの作成手順)**
1 AWSアカウントにログイン
2 画面上部のツールバーに[IAM]と入力して、IAMのサービス画面に遷移
3 画面左のメニューから[ポリシー]を選択

![policy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/da7c9848-3f40-2e13-11f1-9b3cbb2fbb43.png)

4 [ポリシーの作成]をクリック
5 今回は[JSON]のタブをクリックして、JSONで権限管理を行います

![policy2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/f35d0e5a-d762-4189-35b5-8934d7927beb.png)

6 [MFAが未認証の場合は、MFAデバイスの設定しかできないポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-mfa-only.html)を参考に下記のようなポリシーを作成します

```json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": "iam:ListVirtualMFADevices",
            "Resource": "*"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            //ログインユーザーのIAMのみ操作可能
            "Resource": "arn:aws:iam::*:mfa/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
            }
        }
    ]
}

```

7 最後のステップまで進めて、保存します

こちらの権限を付与することで、IAMユーザーはMFA設定をするまでは他の操作ができなくなります。


### 組織上の役割や権限ごとのグループ/ロールを作成する 
 
**(権限をIAMユーザーに与える際の方針)**
各ユーザーにきちんと割り当てられていることを確認しやすくするために、各IAMユーザーに権限を割り当てるのではなく、``IAM ユーザーにアクセス許可を割り当てるためには、ユーザーグループを使用``します。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#use-groups-for-permissions

``グループにポリシーを設定``して、``IAMユーザーをグループに追加``することで、IAMユーザーに権限を割り当てます。

ただし、管理者権限など強すぎる権限の場合には永続的に特定のユーザーに権限を与えるのではなく一時的にAWSアクセス権限を与えるロールを利用することも検討します。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_terms-and-concepts.html


**(職務機能とグループ/ポリシーの関係)**
個人開発だとあまり意識しなくてもいいかもしれませんが、グループを定義する前に **「誰がどのような役割でどのようなタスクを実行できる権限を持つかを整理したルール」(=職務機能)** を定義し、その職務内容にそったグループ/ポリシーを作成します。

**[職務機能の例]**
- 管理者: AWSアカウントの管理者。強い権限なので1-2人程度にする
- データベース管理者: AWS クラウドのデータベースのセットアップ、設定、メンテナンスを行う
- 閲覧者: リソースやログ内容を確認するだけで、更新は行わない 
- アプリケーション開発者: アプリケーションの開発に関わるタスクを行う
- リリース承認者: アプリの本番環境へのデプロイ/リリースの承認を行う
- コストの責任者: 請求情報の確認、支払いの設定、支払いの承認を行う

個人開発の場合でも、管理者 / 開発 / インフラ作業は分けて管理して、行う作業内容に合わせて、ユーザー/グループ/ロールを管理するといいと思います。

**(グループの作成手順)**
ここでは上記で作成したMFAを強制するポリシーを例にグループ/ IAMユーザーの設定を行います。

1 画面左の[ユーザーグループ]のメニューを選択します
2 [グループを作成]をクリック
3 [ユーザーグループ名]を入力します
4 グループに追加したいユーザーを選択して、グループに追加します(MFAを強制するポリシーは全員に適用したいグループなので、全てのユーザーを選択します)
5 [アクセス許可ポリシーをアタッチ]で、必要な権限(ここではMFAを強制するポリシー)を追加します

![groups.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/eb38a508-d6af-75b6-c230-3e47460d58ea.png)
 
組織上の役割や権限に沿って、決めた職務機能に沿って、同様の手順でグループを作成します。
``役割や権限ごとに利用するサービスのみにアクセスできる最小限のポリシーを作成する`` を参考にアタッチするポリシーを作成します。
 
### 役割や権限ごとに利用するサービスのみにアクセスできる最小限のポリシーを作成する
 
各職務機能に応じて、必要なポリシーを作成します。

どのような役割を担うかにもよって必要なポリシーは異なるのですが、AWSが公開してくれている [職務機能の AWS 管理ポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html)を参考にして、最初は少しずつ必要な権限を足していくのが良いかと思います。(慣れてきたら、このようなホワイトリスト方式ではなく、最低限防ぎたいサービスのみをブロックするブラックリスト方式を併用すると管理コストを減らせます。)

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html

ポリシーにはAWS側で、あらかじめ必要そうな権限を定義してくれている [AWS 管理ポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies)と``「MFAが未認証の場合は、MFAデバイスの設定しかできないポリシー」``のように自由に作成ができる[カスタマー管理ポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies)があるのでこの2つをうまく組み合わせて、必要な権限を設定します。

#### (ポリシーを作成する際に知っておきたいこと)
* 最小限のアクセス権を付与する
* 複数のポリシーを組み合わせた場合の評価ルールを考慮する

#### 最小限のアクセス権を付与する
[IAMでのセキュリティのベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)にもあるように必要最小限のアクセス権を付与することが原則となります。
ポリシーを複数設計するのは大変だとは思うのですが、アプリケーションやインフラの運用方針を決めることにもつながるのでここはできるだけサボらずにやりましょう。

#### 複数のポリシーを組み合わせた場合の評価ルールを考慮する
[カスタマー管理ポリシーは最大6,144文字](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entity-length)で定義しなければならないため、1つのポリシーで全ての権限管理をすることは難しく、複数のポリシーを組み合わせて権限の管理を行うことになります。

公式ページに記載されている[複数のポリシーを組み合わせた場合の評価ルール](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)を見ると、複雑そうな印象を受けますが最初のうちは下記の3点だけ意識するとわかりやすいかと思います。

* 明示的に許可するポリシーがない場合には暗黙的な拒否がされる(= 対象のAWSリソースにアクセスできない)
* 明示的な拒否と明示的な許可を組み合わせた場合は``拒否``が優先する(= 対象のAWSリソースにアクセスできない)
* IAMによるポリシーとリソースベースのポリシー(S3のようなアクセスされる側に設定できるポリシー)を組み合わせた場合、明示的な許可と暗黙的な拒否を組み合わせた場合は``明示的な許可``が優先される
 
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow

これら点に注意すると安全性を保ちつつ、管理コストを押さえたIAMポリシーの設計ができると思います。

## セキュリティインシデントを検知できるようにするためにやっておきたいこと
セキュリティインシデントを防ぐだけではなく、もし発生しまった時にきちんと気づける体制を整えておくことも大切です。
最初の一歩として、[AWS CloudTrailのBlack Beltでも紹介されている](https://aws.amazon.com/jp/blogs/news/webinar-bb-awscloudtrail-2021/)最低限これだけはやっておこうという設定を記載します。
 
* 全てのAWSリージョンで AWS CloudTrailの証跡の有効化
* AWS GuardDutyの利用

(注意)これらのサービスは有料サービス(AWS GuardDutyは30日間は無料)なので、導入には多少のコストがかかることをご了承ください。

* [AWS Cloud Trailの料金](https://aws.amazon.com/jp/cloudtrail/pricing/)
* [Amazon GuardDuty の料金](https://aws.amazon.com/jp/guardduty/pricing/)

### 全てのAWSリージョンで AWS CloudTrailの証跡の有効化
AWS CloudTrailは、AWSアカウントでの操作イベント(管理イベント)、S3などのAWSのリソースに対する操作(データイベント)、管理イベントが異常な操作をされたことを検知するイベント(インサイトイベント)を記録できます。

[イベント履歴]という機能では90日間の管理イベントの履歴は無料で見れるのですが、多くのケースでは90日間だけでは不都合があるので、S3に証跡を保存する設定をまずしておきましょう。

**(設定手順)**
1 AWSアカウントにログイン
2 画面上部のツールバーに[Cloud Trail]と入力して、AWS CloudTrailのサービス画面に遷移
3 画面上の[証跡の作成]をクリック
4 証跡名を入力して、ログファイルの SSE-KMS 暗号化のチェックを外し、[次へ]をクリック
(これはログファイルをAWS KMSというサービスを利用して暗号化できるオプションなのですが、有料なのと設定が少し複雑になるので外します。このチェックを外してもS3上のログファイルはSSE-S3という方式で暗号化されるので、必要になったら後からSSE-KMS 暗号化を利用するということでいいと思います。)

![cloudtrail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/1dc059d4-6102-db43-7a34-afacbb99bb52.png)

５ イベントタイプで[管理イベント]、[Insight イベント]にチェックをつけて、[次へ]をクリック
![cloudtrail2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/af5d3139-12ea-4af2-d254-f49594dfd604.png)

6 内容を確認して、[証跡の作成]をクリックして完了です

保存された証跡は、[証跡の作成]の際に作成されたS3バケットに保存されます。
もしバケットがわからない場合はCloudTrailの[証跡]のメニューからログの場所へ遷移できます。
 
### AWS GuardDutyの利用
AWS GuardDutyはAWSのいくつかのログ(VPC Flow logs / CloudTrail / DNS logs)を用いて、AWS リソース(EC2 / IAM/ S3)に対しての不審な動作/アクセスの検知を行えるサービスです。

利用方法は簡単で、[サービス開始]のボタンを開始するだけで、開始できます。

サービス開始後は、AWS GuardDuty内から不審な動作が発生していないかを確認できるので、定期的に確認するようにしてください。
どのくらいのコストがかかっているかも確認できるので、無料期間中に継続利用するかどうかの参考材料にできます。

### AWS アカウントの不正なアクティビティに気付いた場合の対応
もし何らかの不正なアクティビティに気づいた場合は、被害状況の確認/証跡の保存をしたのち、不正なAWSリソースの削除 / パスワードの変更などの復旧作業を行うようにしましょう。

AWS公式側での対応のQAもありましたので、参考にしてみてください。

参考: [AWS アカウントの不正なアクティビティに気付いた場合、どうすればよいですか?]
(https://aws.amazon.com/jp/premiumsupport/knowledge-center/potential-account-compromise/)

## 最後に
AWSは多くの個人/企業で利用されているので、書籍/ネットの記事で多くの情報が手に入るのですが、部分的なサービスについて詳しい記事やサービスの構築に使ってみたという記事が多く、どういう点を最低限気をつけようとか詳細情報を確認するためのリンクがまとまった記事が少なかったため、自分の知識の確認も含めてまとめてみました。

この記事を参考に1人でも何やったらいいかわからないとかAWSアカウント使ってみたら不正請求されたという方がいなく慣れば幸いです。

また、ロールを用いてアプリケーションに権限を渡す際の設計や監視などについても実践しつつ、まとめていきたいと思います。 

## 参考資料
* [AWS セキュリティのベストプラクティス](https://d1.awsstatic.com/International/ja_JP/Whitepapers/AWS_Security_Best_Practices.pdf)
* [IAM でのセキュリティのベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html)
* [AWS CloudTrail におけるセキュリティのベストプラクティス](https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/best-practices-security.html)
* [AWS Well- Architected フレームワーク / セキュリティ](https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.question.SEC_2.ja.html) 
* [AWS Security Documentation](https://docs.aws.amazon.com/security/?secd_intro2)
* [AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)
* [社外の開発メンバーをAWSアカウントに入れるときのIAM設定を考えている](https://kmiya-bbm.hatenablog.com/entry/2019/09/07/221740)
* [IAM ポリシーの要素: 変数とタグ](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_variables.html)
* [AWS: MFA認証されていない場合、MFA認証の設定に必要なアクションを除いて、すべてのAWS アクションへのアクセスを拒否するポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-mfa-only.html)