AWS公式資料で挑むSCS認定(42)-こんな時どうする(全分野その19)

##### [前回] [AWS公式資料で挑むSCS認定(41)-こんな時どうする(全分野その18)](https://qiita.com/mingchun_zhao/items/935141b158b168931d80)

## はじめに

今回も引き続き、「こんな時どうする」集の作成です。

## 分野1: インシデント対応

- アクセスキーの不正使用が報告された、アクセスキーを使用しアクセスされたAWSサービスを特定したい
    - AWSアカウントの認証情報レポートから確認できる
        - 認証情報レポートには、AWSアカウントのすべてのユーザーと各種認証情報(パスワード、アクセスキー、MFAデバイスなど)のステータスが含まれている
        - AWS Management Console、AWS SDK、コマンドラインツール、またはIAM APIから取得できる
    - ※ 認証情報レポートを使用し、監査やコンプライアンス作業を支援
        - パスワードやアクセスキーのローテーションなど、認証情報ライフサイクルの要件の結果を監査可能
        - 外部の監査人にレポート提供、または監査人にアクセス権限を付与し直接ダウンロード
            - 認証情報レポートは、4時間ごとに生成され、最新のレポートがダウンロードされる
    - ※ 認証情報レポートの作成/ダウンロードに必要なアクセス許可
        - 作成生成: `iam:GenerateCredentialReport`
        - ダウンロード: `iam:GetCredentialReport`

## 分野2: ログとモニタリング(監視)

- CloudTrailが一部リージョンのログを配信していない
    - S3バケットのポリシー設定が古く、個別リージョンのCloudTrailアカウントIDが指定された可能性あり
        - この場合、指定されたリージョンのみログを配信するようなアクセス権限がCloudTrailに与えられる
    - CloudTrailがリージョンのログを配信しない場合、CloudTrailサービスプリンシパルでアクセス権限を使用するようポリシーを更新
        - アカウントIDのARNをサービスプリンシパル名`cloudtrail.amazonaws.com`に置き換える
            - これにより、CloudTrailに現在および新リージョンのログを配信するアクセス権限が与えられる
    - ※ 証跡の作成/更新時に新しいバケットを作成すると、CloudTrailは必要なアクセス権限をバケットにアタッチ
        - バケットポリシーはサービスプリンシパル名`cloudtrail.amazonaws.com`を使用するため、CloudTrailがすべてのリージョンのログを配信できる
    - ※ ベストプラクティスとして、S3バケットポリシーに`aws:SourceArn`または`aws:SourceAccount`条件キーを追加
        - これでS3バケットへの不正なアカウントアクセスを防止
        - 既に証跡が存在する場合も忘れず、1つまたは複数の条件キーを追加
    - サービスプリンシパル名を使用したバケットポリシーの例
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {"Service": "cloudtrail.amazonaws.com"},
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::MyBucket"
        },
        {
            "Sid": "CloudTrailWrite",
            "Effect": "Allow",
            "Principal": {"Service": "cloudtrail.amazonaws.com"},
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::MyBucket/[Prefix]/AWSLogs/MyAccountID/*",
            "Condition": {"StringEquals": {
                "s3:x-amz-acl": "bucket-owner-full-control",
                "aws:SourceArn": "arn:aws:cloudtrail:region:MyAccountID:trail/MyTrail"
                }
            }
        }
    ]
}
```

## 分野3: インフラストラクチャのセキュリティ

- AWS Step Functionsのステートメントマシンを簡単に作成したい
    - AWS CloudFormationテンプレートの拡張であるAWS SAM(AWS Serverless Application Model)テンプレートを使用し、ステートマシンを定義する
        - AWS SAMとは、AWSでサーバーレスアプリケーションを構築するために使用できるオープンソースのフレームワーク
            - サーバーレスアプリケーションは、タスクを実行するために連動するLambda関数、イベントソース、およびその他リソースの組み合わせ
        - AWS SAMでは、ステートマシンをテンプレート内でインラインで定義するか、別ファイルに定義できる
        - AWS SAM CLIをAWS Toolkit for Visual Studio Codeと組み合わせ、ステートマシンをローカルに作成できる
            - AWS SAMを使用しサーバーレスアプリケーションを構築後、VS Code IDEでステートマシンを構築
    - ※ ステートマシンを使用し、リソースに対する検証/パッケージ化/デプロイを実施できる
        - オプションで、AWS Serverless Application Repositoryへ発行できる
    - ※ Step FunctionsをAWS SAMとともに使用する理由
        - AWS SAMサンプルテンプレートを使用し簡単にスタートできる
        - ステートマシンをサーバーレスアプリケーションにビルド可能
        - デプロイ時に変数置換を使用し、ARNをステートマシンに置換できる
        - AWS SAMポリシーテンプレートを使用し、ステートマシンロールを指定できる
        - API Gateway、EventBridgeイベント、AWS SAMテンプレート内のスケジュールを使用し、ステートマシンを開始できる
    - ※ Step FunctionsとAWS SAM仕様の統合
        - AWS SAMポリシーテンプレートを使用し、ステートマシンにアクセス許可を追加できる
        - これらの権限は、Lambda関数とAWSリソースのオーケストレーションに使用され、複雑で堅牢なワークフローを形成できる
    - ※ Step FunctionsとSAM CLIの統合
        - AWS SAM CLIをStep Functionsと統合し、サーバーレスアプリケーションですばやくステートマシンを開発できる

## 分野4: アイデンティティ(ID)及びアクセス管理

- AWS`アカウントA`が`アカウントB`のS3バケットにアップロードしたオブジェクトに対し、`アカウントB`がフルコントロールできるようにしたい
    - `bucket-owner-full-control`アクセスコントロールリスト(ACL)をS3内に存在するオブジェクトに追加
    - ※ 背景知識
        - デフォルトで、他のAWSアカウントがS3バケットにオブジェクトをアップロードしたら、オブジェクトの所有権はアップロードするアカウントとなる
        - オブジェクト作成者がオブジェクトACLレベルでターゲットアカウントのアクセス許可を指定しない場合、ターゲットアカウントにできるのはオブジェクト削除のみ
        - `bucket-owner-full-control`ACLを追加すると、バケット所有者`アカウントB`は他のアカウントによって書き込まれた新しいオブジェクトを完全制御できる
            - ACLで対象バケットのS3オブジェクト所有権が有効になっている場合、新しいオブジェクトの所有者が`アカウントB`に更新される
        - ※ 重要: バケットおよびオブジェクトACLによるクロスアカウントアクセス許可は、S3オブジェクトの所有権が`Bucket Owner Enforced`に設定されているバケットでは機能しない
            - ACLは、通常オブジェクトやバケットにアクセス権限付与に必要ない
            - 代わりに、IAMポリシーとS3バケットポリシーを使用し、オブジェクトとバケットにアクセス許可を付与
        - 既存のオブジェクトの場合、オブジェクト所有者はオブジェクトのACLを更新することで、バケット所有者にオブジェクトのフルコントロールを付与することができる
        - 新しいオブジェクトを書き込む場合、PUTまたはCOPYオペレーションで`bucket-owner-full-control`ACLを指定できる
    - `アカウントA`のユーザーが`アカウントB`のオブジェクトに`bucket-owner-full-control`既定ACLを付与するためアクセス許可付与方法
        - `アカウントA`でIAMロールを作成し、`アカウントB`のオブジェクトでPutObjectAclを実行するアクセス許可を付与
            - ※ 注: アップロード時にIAMユーザーまたはロールがオブジェクトのACLを更新する必要がある場合、IAMポリシーで`s3:PutObjectAcl`アクセス許可が必要
            - ポリシー例
                - `"Effect": "Allow"`
                - `"Action": ["s3:GetObject", "s3:PutObject", "s3:PutObjectAcl"]`
                - `"Resource": "arn:aws:s3:::AccountB-Bucket/*"`
        - `アカウントB`のバケットポリシーで、`アカウントA`のIAMユーザー/IAMロールにアクセス許可を付与する必要あり
            - ※ バケットポリシーは、オブジェクトのアップロード時の既定ACLの要件に応じて異なる
            - ポリシー1: S3 PUTオペレーションに`bucket-owner-full-control`既定ACLを含めず、`アカウントA`のIAMユーザーまたはロールにアクセスを許可
                - ACLなしで`アカウントA`のIAM ロールにアクセスを許可するには、`アカウントB`にバケットポリシーを作成
                - `アカウントB`のオブジェクトに対する以下アクションを`アカウントA`のロールに許可
                    - GetObject
                    - PutObject
                    - PutObjectACL
                - ポリシー例
                    - `"Effect": "Allow"`
                    - `"Principal": {"AWS": "arn:aws:iam::AccountA:role/AccountARole"}`
                    - `"Action": ["s3:GetObject", "s3:PutObject"]`
                    - `"Resource": ["arn:aws:s3:::AccountB-Bucket/*"]`
            - ポリシー2: すべてのS3 PUTオペレーションで`bucket-owner-full-control`既定ACLを強制
                - `アカウントA`のIAMユーザーまたはロールが`アカウントB`のバケットへのオブジェクトアップロードは、オブジェクトのACLが`bucket-owner-full-control`に設定されている場合にのみ実行できる
                    - ユーザーはPutObjectオペレーションで`bucket-owner-full-control`既定ACLを強制され、含めない場合オペレーションがアクセス拒否エラーで失敗
                - ポリシー例
                    - `"Effect": "Allow"`
                    - `"Principal": {"AWS": ["arn:aws:iam::AccountA:role/AccountARole"]}`
                    - `"Action": ["s3:PutObject"]`
                    - `"Resource": "arn:aws:s3:::AccountB-Bucket/*"`
                    - `"Condition":`
                    ```
                    {
                        "StringEquals": {
                            "s3:x-amz-acl": "bucket-owner-full-control"
                        }
                    }
                    ```
            - オブジェクトアップロード時、`bucket-owner-full-control`既定ACLを付与する方法
                - `アカウントA`(オブジェクト所有者のアカウント)から`put-object`コマンドを実行
                    - `aws s3api put-object --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control`
            - コピーオペレーションで`bucket-owner-full-control`既定ACLを付与する方法
                - `アカウントA`(オブジェクト所有者のアカウント)から`copy-object`コマンドを実行
                    - `aws s3api copy-object --copy-source accountA-bucket/example.txt --key example.txt --bucket accountB-bucket --acl bucket-owner-full-control`
                - `アカウントA`から`cp`コマンドで`bucket-owner-full-control`既定ACLを付与する方法
                    - `aws s3 cp s3://accountA-bucket/test.txt s3://accountB-bucket/test2.txt --acl bucket-owner-full-control`
                - 複数オブジェクトのコピーオペレーションの場合、オブジェクト所有者(`アカウントA`) から次のコマンドを実行
                    - `aws s3 cp s3://accountA-bucket/ s3://accountB-bucket/ --acl bucket-owner-full-control --recursive`
                - `アカウントB`のバケットにオブジェクトが既に存在する場合、オブジェクト所有者(`アカウントA`)から次のコマンドでバケット所有者へアクセス許可を付与
                    - `aws s3api put-object-acl --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control`
    - ※ 多くのS3オブジェクトに`bucket-owner-full-control`既定ACLを追加する場合
        - S3バッチ操作を使用し、指定したオブジェクトのリストに対して1つのオペレーションを実行できる
        - S3バッチ操作を使用して、多数のオブジェクトにACLを設定することもできる
        - S3バッチ操作は、事前定義されたアクセス許可セットと共にS3が提供するカスタムACLと既定 ACLをサポート
    - ※ VPCエンドポイントを経由してルーティングされるインスタンスを使用しS3にオブジェクトをアップロードする場合
        - VPCエンドポイントポリシーで`PutObjectAcl`アクションのアクセス許可を付与
        - ポリシー例
            - `"Principal": "*"`
            - `"Action": ["s3:PutObject", "s3:PutObjectAcl"]`
            - `"Effect": "Allow"`
            - `"Resource": "arn:aws:s3:::AccountB-Bucket/*"`

## 分野5: データ保護

- DynamoDBの保管データを保護したい
    - DynamoDBの保管データは、AWS KMSの暗号化キーを用いて完全に暗号化される
        - この機能により、機密データの保護における負担と複雑な作業を減らせる
        - セキュリティ重視のアプリケーションを構築でき、組織のポリシー/業界や政府の規制/コンプライアンス要件を満たせる
    - DynamoDBの保管時暗号化は、暗号化されたテーブル内にデータを配置し保護することで、以下の要素に追加のデータ保護レイヤーを提供
        - プライマリキー
        - ローカルおよびグローバルセカンダリインデックス
        - ストリーム
        - グローバルテーブル
        - バックアップ
        - DynamoDB Accelerator(DAX)
    - 保管時の暗号化には、テーブルの暗号化に使用される暗号化キーを管理するためのAWS KMSが統合されている
        - 新しいテーブルを作成する場合、下記いずれかのKMSキーを選択しテーブルを暗号化できる
            - AWS所有のキー
                - デフォルトの暗号化タイプで、キーはDynamoDB により所有される(追加料金なし)
            - AWS管理キー
                - キーはアカウントに保存され、AWS KMSによって管理される(AWS KMSの料金が適用される)
                - ※ 注: 保存時の暗号化を有効にし、新しいDAXクラスターを作成する場合、AWS管理キーを使用し、クラスター内の保管中データを暗号化
            - カスタマー管理キー
                - キーはアカウントに保存され、ユーザーによって作成、所有、管理され、ユーザーはKMSキーに対するフルコントロール権限を持つ(AWS KMSの料金が適用される)
        - AWS所有のキー、AWS管理キー、カスタマー管理キーはいつでも切り替えることができる
        - 暗号化されたテーブルにアクセスすると、DynamoDBはテーブルデータを透過的に復号
        - 暗号化されたテーブルの使用/管理時、コードやアプリケーションを変更する必要なし
            - DynamoDBは、1桁ミリ秒のレイテンシーを継続的に提供し、すべてのDynamoDBクエリは暗号化されたデータでシームレスに機能

## おわりに

「こんな時どうする」の追記でした。
次回も続きます、お楽しみに。

##### [次回] [AWS公式資料で挑むSCS認定(43)-こんな時どうする(全分野その20)](https://qiita.com/mingchun_zhao/items/f14591ba121837755f58)