Amazon Web Services ブログ

AWS Security Hubによる自動対応と修復

AWS Security Hub は、複数の AWS アカウントにわたるセキュリティとコンプライアンスの状態を可視化するサービスです。AWS のサービスおよび APN パートナーソリューションからの検出結果を処理することに加えて、Security Hub にはカスタムアクションを作成するオプションがあり、お客様は特定の検出結果に対して特定の対応と修復アクションを手動で呼び出すことができます。カスタムアクションは特定のイベントパターンとして Amazon CloudWatch Events に送信されます。CloudWatch Events ルールは、Lambda 関数Amazon SQS キューなどのターゲットサービスをトリガーできます。

特定の検出結果タイプにマッピングされたカスタムアクションを作成し、そのカスタムアクションに対応する Lambda 関数を作成することにより、これらの検出結果のターゲットを絞った自動修復を実現できます。これにより、お客様は特定の検出結果に対して何の修復アクションを呼び出すかどうかを明確にできます。お客様は、これらの Lambda 関数を、人が介在しない完全に自動化された修復アクションとして使用することもできます。

本ブログでは、カスタムアクション、CloudWatch Events ルール、および Lambda 関数を作成する方法を紹介します。これらによって、CIS AWS Foundations ベンチマークの十数個のコンプライアンス検出結果を修復できます。また、検出結果を課題管理システムに送信し、セキュリティパッチを自動化するユースケースについても説明します。このソリューションをお客様がすぐにご利用できるように、AWS CloudFormation から必要なコンポーネントの大部分をデプロイします。

:本ブログで紹介する対応と修復テンプレートの完全なリポジトリは GitHub にホストしています。このブログで提供するソリューションを拡張するための追加の技術ガイダンスも含まれています。

全体のアーキテクチャ

Figure 1 - Solution Architecture Overview

図1 – 全体のアーキテクチャ

図1は、検出結果が連携サービスからカスタムアクションにどのように移動するかを示しています

  1. 連携サービスは、検出結果を Security Hub に送信します
  2. Security Hub コンソールから、検出結果のカスタムアクションを選択します。その後、各カスタムアクションは CloudWatch Events として発行されます
  3. CloudWatch Events ルールは Lambda 関数をトリガーします。 この関数は、カスタムアクションの ARN に基づいてカスタムアクションにマップされます
  4. 特定のルールに応じて、呼び出される Lambda 関数は、ユーザーに代わって修復アクションを実行します

本ブログでは、カスタムアクション、CloudWatch Events ルール、Lambda 関数、および特定のアクションを「プレイブック」として実行するために必要なサポートサービスを一つずつ説明します。修復ソリューションがエンドツーエンドでどのように機能するかを説明するために、最初にプレイブックを手動で作成する方法を紹介します。残りのプレイブックは CloudFormation を使ってデプロイします。

また、4つのプレイブックを修正する方法も説明します。 AWS Lambda 環境変数を使用してアクションを実行するので、これらは後ほど説明します。

Security Hub のお客様からのフィードバックに基づいて、CIS AWS Foundations ベンチマークの次のコントロールをこのブログでデプロイします。

  • 1.3 – 90 日間以上使用されていない認証情報は無効にします
  • 1.4 – アクセスキーは 90 日ごとに更新します
  • 1.5 – IAM パスワードポリシーには少なくとも 1 つの大文字が必要です
  • 1.6 – IAM パスワードポリシーには少なくとも 1 つの小文字が必要です
  • 1.7 – IAM パスワードポリシーには少なくとも 1 つの記号が必要です
  • 1.8 – IAM パスワードポリシーには少なくとも 1 つの数字が必要です
  • 1.9 – IAM パスワードポリシーは 14 文字以上の長さが必要です
  • 1.10 – IAM パスワードポリシーはパスワードの再使用を禁止しています
  • 1.11 – Ensure IAM パスワードポリシーにより、パスワードは 90 日以内に有効期限が切れます
  • 2.2 – CloudTrail ログファイルの検証は有効なっています
  • 2.3 – CloudTrail が記録する S3 バケットはパブリックアクセスできません
  • 2.4 – CloudTrail 証跡は Amazon CloudWatch Logs によって統合されています
  • 2.6 – S3 バケットアクセスログ記録が CloudTrail S3 バケットで有効になっていることを確認します
  • 2.7 – CloudTrail ログは保管時に AWS KMS CMK を使用して暗号化されていることを確認します
  • 2.8 – カスタマー作成の CMK のローテーションが有効になっていることを確認します
  • 2.9 – すべての VPC で VPC フローログ記録が有効になっていることを確認します
  • 4.1 – どのセキュリティグループでも 0.0.0.0/0 からポート 22 への入力を許可しないようにします
  • 4.2 – どのセキュリティグループでも 0.0.0.0/0 からポート 3389 への入力を許可しないようにします
  • 4.3 – すべての VPC のデフォルトセキュリティグループがすべてのトラフィックを制限するようにします

また、追加でプレイブック「検出結果をJIRAに送信する」をデプロイおよび修正します。CloudFormation リソースの説明だけでなく、各カスタムアクションの作成では、それぞれのプレイブックの概要も説明をします。

: Security Hub の検出結果を Amazon Elasticsearch Service やサードパーティソリューションなどの SIEM (Security Information and Event Management) に送信する場合は、CloudWatch Events ルールを変更する必要があります。例えば、ターゲットを修正することで、Amazon Kinesis Data Streams から Kinesis Data Firehose に送信して、SIEM に読み込ませられます。この方法は、本ブログでは説明いたしません。

前提条件

リージョンで Security Hub と AWS Config が有効になっていることを確認します。また、このブログのソリューションは、単一のアカウントの場合の説明で、クロスアカウントの修復は説明いたしません。Lambda のクロスアカウントロールの基本情報については、Knowledge Centerの 記事 「別の AWS アカウントからロールを引き受けるように Lambda 関数を設定するにはどうすれば良いですか?」を参照してください。

プレイブック「セキュリティパッチの適用」では、EC2 インスタンスを Systems Manager で管理します。マネージドインスタンスの詳細については、AWS Systems Manager ユーザーガイドの 「AWS Systems Manager のマネージドインスタンス」を参照してください。

修復プレイブックを手動で作成する

プレイブックを作成するプロセスを説明すために、まず手動で作成する方法を紹介して、残りのプレイブックはCloudFormation でデプロイします。手動で CIS AWS Foundations ベンチマーク の コントロール 2.7 「CloudTrail ログは保管時に AWS KMS CMK を使用して暗号化されていることを確認します」を修復するためのプレイブックを作成します。SSE-KMSによる暗号化を使用するように CloudTrail を設定すると、ログデータに機密性の統制が追加できます。CloudTrail ログにアクセスするには、ユーザーは対応するログバケットの S3 読み取り権限を持っているだけでなく、KMS キーポリシーで復号する権限を付与されている必要があります。

重要な注: この修復および他のすべての修復コードは、カスタムアクションメニューから一度に1つの検出結果のみをターゲットにできます。

Lambda 関数で自動修復を実現するために、コンプライアンス非準拠の CloudTrail 証跡情報を暗号化するための新しい KMS CMK とエイリアスを作成します。次に、KMS キーポリシーをアタッチします。これによって、証跡情報を所有するAWSアカウントで IAMの Condition に StringEquals: kms:CallerAccoun が付与されたアカウントのみが証跡情報を復号できます。このプレイブックは、非準拠の CloudTrail 証跡情報ごとに1回だけ実行されます。

このプレイブックは次の手順で開始できます。

  1. Security Hubコンソールに移動し、ナビゲーションペインから設定を選択して、カスタムアクションタブを選択します。
  2. カスタムアクションを作成するを選択し、図2に示すように、アクション名、説明、およびカスタムアクション ID の値を入力してから、カスタムアクションを作成するを再度選択します
    本ブログでは、アクション名を「CIS 2.7 RR」、カスタムアクション ID を「cis27rr」とします。「RR」は「Response and Remediation」の略です。

    Figure 2 - Create custom action

    図2 – カスタムアクションの作成

  3. 手順12で必要になるため、Amazon リソースネーム(ARN)をコピーします
  4. Lambda コンソールに移動し、関数の作成を選択します
  5. 関数名を入力し、ランタイムに「Python 3.7」を選択し、アクセス権限には基本的な Lambda アクセス権限で新しいロールを作成を選択します。次に、関数の作成を選択します
  6. 「実行ロール」までスクロールダウンし、「既存のロール」の下のハイパーリンクを選択します。これにより、IAM コンソールに新しいタブが開きます
  7. IAM コンソールから、インラインポリシーの追加を選択し、JSON タブを選択して、以下の JSON 形式の IAM ポリシーを貼り付け、ポリシーの確認を選択します
    
    {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "kmssid",
            "Action": [
              "kms:CreateAlias",
              "kms:CreateKey",
              "kms:PutKeyPolicy"
            ],
            "Effect": "Allow",
            "Resource": "*"
          },
          {
            "Sid": "cloudtrailsid",
            "Action": [
              "cloudtrail:UpdateTrail"
            ],
            "Effect": "Allow",
            "Resource": "*"
          }
        ]
      }
    
  8. インラインポリシーに名前を付けて、ポリシーの作成を選択します
  9. Lambda コンソールに戻り、タイムアウトを1分に、メモリを256MBに増やします。「関数コード」まで上にスクロールし、以下のコードを貼り付けて、保存を選択します
    
     # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
     # SPDX-License-Identifier: MIT-0
     #
     # Permission is hereby granted, free of charge, to any person obtaining a copy of this
     # software and associated documentation files (the "Software"), to deal in the Software
     # without restriction, including without limitation the rights to use, copy, modify,
     # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
     # permit persons to whom the Software is furnished to do so.
     #
     # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
     # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    import boto3
    import json
    import time
    
    def lambda_handler(event, context):
        # parse non-compliant trail from Security Hub finding
        noncompliantTrail = str(event['detail']['findings'][0]['Resources'][0]['Details']['Other']['name'])
        # parse account ID from Security Hub finding, will be needed for Key Policy
        accountID = str(event['detail']['findings'][0]['AwsAccountId'])
        
        # import boto3 clients for KMS and CloudTrail
        kms = boto3.client('kms')
        cloudtrail = boto3.client('cloudtrail')
    
        # create a new KMS CMK to encrypt the non-compliant trail
        try:
            createKey = kms.create_key(
            Description='Generated by Security Hub to remediate CIS 2.7 Ensure CloudTrail logs are encrypted at rest using KMS CMKs',
            KeyUsage='ENCRYPT_DECRYPT',
            Origin='AWS_KMS'
            )
            # save key id as a variable
            cloudtrailKey = str(createKey['KeyMetadata']['KeyId'])
            print("Created Key" + " " + cloudtrailKey)
        except Exception as e:
            print(e)
            print("KMS CMK creation failed")
            raise
            
        # wait 2 seconds for key creation to propogate
        time.sleep(2)
    
        # attach an alias for easy identification to the key - must always begin with "alias/"
        try:
            createAlias = kms.create_alias(
            AliasName='alias/' + noncompliantTrail + '-CMK',
            TargetKeyId=cloudtrailKey
            )
            print(createAlias)
        except Exception as e:
            print(e)
            print("Failed to create KMS Alias")
            raise
        
        # wait 1 second
        time.sleep(1)
    
        # policy name for PutKeyPolicy is always "default"
        policyName = 'default'
        # set Key Policy as JSON object
        keyPolicy={
            "Version": "2012-10-17",
            "Id": "Key policy created by CloudTrail",
            "Statement": [
                {
                    "Sid": "Enable IAM User Permissions",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": [ "arn:aws:iam::" + accountID + ":root" ]
                    },
                    "Action": "kms:*",
                    "Resource": "*"
                },
                {
                    "Sid": "Allow CloudTrail to encrypt logs",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "cloudtrail.amazonaws.com"
                    },
                    "Action": "kms:GenerateDataKey*",
                    "Resource": "*",
                    "Condition": {
                        "StringLike": {
                            "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:" + accountID + ":trail/" + noncompliantTrail
                        }
                    }
                },
                {
                    "Sid": "Allow CloudTrail to describe key",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "cloudtrail.amazonaws.com"
                    },
                    "Action": "kms:DescribeKey",
                    "Resource": "*"
                },
                {
                    "Sid": "Allow principals in the account to decrypt log files",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "*"
                    },
                    "Action": [
                        "kms:Decrypt",
                        "kms:ReEncryptFrom"
                    ],
                    "Resource": "*",
                    "Condition": {
                        "StringEquals": {
                            "kms:CallerAccount": accountID
                        },
                        "StringLike": {
                            "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:" + accountID + ":trail/" + noncompliantTrail
                        }
                    }
                },
                {
                    "Sid": "Allow alias creation during setup",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "*"
                    },
                    "Action": "kms:CreateAlias",
                    "Resource": "*",
                    "Condition": {
                        "StringEquals": {
                            "kms:CallerAccount": accountID
                        }
                    }
                }
            ]
        }
        # attaches above key policy to key
        try:
            attachKeyPolicy = kms.put_key_policy(
                KeyId=cloudtrailKey,
                Policy=json.dumps(keyPolicy),
                PolicyName=policyName
            )
            print(attachKeyPolicy)
        except Exception as e:
            print(e)
            print("Failed to attach key policy to Key:" + " " + cloudtrailKey)
    
        # update CloudTrail with the new CMK
        try:
            encryptTrail = cloudtrail.update_trail(
            Name=noncompliantTrail,
            KmsKeyId=cloudtrailKey
            )
            print(encryptTrail)
            print("CloudTrail trail" + " " + noncompliantTrail + " " + "has been successfully encrypted!")
        except Exception as e:
            print(e)
            print("Failed to attach KMS CMK to CloudTrail")
    
  10. CloudWatch コンソールに移動し、イベントの下のルールルールの作成の順に選択します
  11. イベントパターンを選択して、下にあるプルダウンメニューからカスタムイベントパターンを選択します
  12. カスタムイベントパターンの構築のテキストボックスに、下の JSON を貼り付けます。”resources”の下の ARN は、手順3で作成したカスタムアクションの ARN に置き換えます
    
    {
      "source": [
        "aws.securityhub"
      ],
      "detail-type": [
        "Security Hub Findings - Custom Action"
      ],
      "resources": [
        "arn:aws:securityhub:us-west-2:123456789012:action/custom/test-action1"
      ]
    }
    
  13. 同じ画面の右側のターゲットで、ターゲットの追加を選択し、手順4で作成した Lambda 関数を選択して、設定の詳細を選択します
  14. 次の画面で、名前と説明の値を入力し、ルールの作成を選択します
  15. Security Hub コンソールに戻り、左側のメニューからコンプライアンス標準を選択し、「結果を表示する」を選択して CIS AWS Foundations ベンチマークを表示します。
  16. ルール CIS 2.7「KMS CMK を使用して CloudTrail ログが保存時に暗号化されていることを確認する」を検索し、ハイパーリンクを選択して、そのコントロールに関連するすべての結果を確認します
  17. リソースタイプが「AwsCloudTrailTrail」ステータスが「FAILED」の検出結果を選択します
  18. 図3に示すように、右上からアクションドロップダウンメニューを選択し、CIS 2.7 RR (または手順2でこのアクションにつけた名前)を選択します。このアクションを選択すると、手順13で作成した Cloudwatch Events ルールが実行され、手順9で作成した Lambda 関数が呼び出されます

    Figure 3 - Security Hub Custom Actions

    図3 – Security Hub カスタムアクション

  19. CloudTrail コンソールに移動して、CloudTrail 証跡情報が SSE-KMS を使用するよう更新されていることを確認します

コンソールから作成したこのフローは、Security Hub を使用したすべてのプレイブック開発に共通です。このチュートリアルの次のセクションでは、同じ方法でアクションメニューから、CloudFormation からデプロイしたプレイブックを実行させます。

: プレイブックの Lambda 関数によって実行されるアクションを監視するには、Lambda 関数のログを参照してください。成功メッセージとエラーメッセージの両方が表示され、必要に応じて調査できます。

CloudFormation から修復プレイブックをデプロイする

GitHub から CloudFormation テンプレートをダウンロードし、CloudFormation スタックを作成します。CloudFormation スタックの作成方法の詳細については、AWS CloudFormation ユーザーガイドの「AWS CloudFormation の使用開始」を参照してください。

スタックのデプロイが完了したら、リソースタブに移動し、各リソースのハイパーリンクを選択して、それぞれのコンソールに移動します。各リソースの論理 ID は、リソースが対応するアクションの前に追加されます。たとえば、図4の CIS13RRCWEPermissions は、AWS CIS ベンチマーク コントロール 1.3 の CloudWatch Events のアクセス許可を示しています。この論理 ID 構造は、テンプレート全体で使用されます。

Figure 4 - CloudFormation Resources

図4 – CloudFormation リソース

次に、それぞれの「検出結果をJIRAに送信」「CIS 2.4」「CIS 2.6」「CIS 2.9」のプレイブックに関連する Lambda 関数を修正する方法を説明します。

プレイブックの修正: 検出結果をJIRAに送信

: 現在アカウントでJIRA Software Data Centerを使われていない場合は、このクイックスタートで評価版を無料で試用できます。JIRA の使用に興味がない場合、または別の課題管理システムを使用する場合は、このセクションはスキップしてください。

このプレイブックは、Lambda 関数を使用して、AWS-CreateJiraIssue という Systems Manager オートメーション ドキュメントを実行することで機能します。

この Systems Manager ドキュメントは、CloudFormation スタックをデプロイし、カスタム Lambda 関数を作成して、Lambadaに設定された環境変数の値を JIRA にマッピングします。

完了すると、CloudFormation スタックは自動で削除され、オートメーションが完了します。このフローを確認するには、次の図5を参照してくだい。

Figure 5 - Send to JIRA Architecture Diagram

図5 – JIRAに送信するアーキテクチャ

  1. 検出結果が選択され、カスタムアクション「Create JIRA Issue」が呼び出され、CloudWatch Events がトリガーされます
  2. CloudWatch Events は Lambda 関数をトリガーします
  3. Lambda は、Systems Manager オートメーション から AWS-CreateJiraIssue ドキュメントを呼び出します
  4. Systems Manager オートメーション は、Lambda 環境変数と Security Hub の検出結果をドキュメントパラメーターとして渡します
  5. ドキュメントは、課題を作成するために JIRA API を呼び出す別のカスタム Lambda を含む CloudFormation スタックを作成します
  6. ドキュメントの Lambda 関数はパラメーターを使用して JIRA で課題を作成します
  7. JIRA は、失敗または成功を示す応答を送り返し、CloudFormation スタックは自動で削除されます

開始するには、Lambda コンソールに移動し、SendToJIRA という名前の関数を見つけて、環境変数まで下にスクロールします。各テキストの横に「placeholder」というテキストが表示されます。次の手順に従って、データを設定する方法を説明します。

  1. JIRA_API_PARAMETER フィールドに入力します
    1. JIRA API トークンを生成するには、 アトラシアンのガイドを参照してください
    2. Systems Manager パラメーターストアのチュートリアルに従って、 パラメーターを作成します。
      1. リンク先のチュートリアル手順6で、安全な文字列を選択し、デフォルトの KMS キーを選択します
      2. リンク先のチュートリアル手順7で、新しく生成された JIRA API トークンを貼り付けます
    3. パラメーターの名前をコピーし、JIRA_API_PARAMETER フィールドの値として貼り付けます
  2. JIRA_PROJECT フィールドに JIRA Software の Project Key を貼り付けます
  3. JIRA_SECURITY_ISSUE_USER フィールドに入力します
    1. この値は JIRA Software のユーザーにマッピングされます。ユーザーを作成する方法については、アトラシアンのガイドを参照してください。このユーザーのパスワードとして、手順1.Aで生成した API キーを使用します。
    2. ユーザー名を JIRA_SECURITY_ISSUE_USER フィールドに貼り付けます
  4. JIRA_URL フィールドに入力します
    1. JIRA Software から JIRA Administration のサブメニュー System に移動し、Settings – General Settings の下にある Base URL フィールドを探します(図6を参照)
    2. Base URL 値をコピーして、 JIRA_URL フィールドに貼り付けます

      Figure 6 - Base URL in JIRA

      図6 – JIRA の Base URL

  5. 完了したら、Lambda コンソールの上部にある保存を選択し、Security Hub コンソールに移動して、左側のメニューから検出結果を選択します
  6. 検出結果のどれかのチェックボックスを選択し、右上のアクションドロップダウンから 「Create JIRA Issue」 を選択します
  7. 図7に示すように、JIRA インスタンスに移動し、新しい課題が表示されるまで数分待ちます

    Figure 7 - Security Hub Finding in JIRA

    図7 – JIRA インスタンス の Security Hub 検出結果

    : 数分経っても JIRA で課題が表示されない場合は、Systems Manager オートメーション コンソールまたは CloudFormation コンソールを参照して Systems Manager によって作成されたスタックを見つけ、失敗メッセージを参照してトラブルシューティングを行なってください

プレイブックの修正: CIS 2.4 の対応と修復

CIS コントロール 2.4は、「CloudTrail 証跡は Amazon CloudWatch Logs によって統合されています」です。この推奨事項の目的は、CloudTrail によって記録された API アクティビティを、CloudWatch でのトラブルシューティングまたはセキュリティインシデント調査の目的で、ほぼリアルタイムでクエリできるようにすることです。

CloudTrail ログを CloudWatch に送信するために、このプレイブックの Lambda 関数は、簡単に識別できるように非準拠 CloudTrail 証跡の名前を持つ新しい CloudWatch Logs グループを作成し、非準拠の CloudTrail 証跡を更新して送信し、新しく作成されたロググループにログを記録します。

これを実現するには、CloudTrail に IAM ロールと CloudWatch へのログの発行を許可するアクセス権限が必要です。  Lambda から複数の新しい IAM ロールとポリシーを作成しないようにするには、このプレイブックの Lambda 環境変数にこの IAM ロールの ARN を入力します。

: 現在、CloudTrail の IAM ロールを持っていない場合は、CloudTrail ユーザーガイドの次の手順に従って作成してください。

このプレイブックを修正する方法:

  1. Lambda コンソールに移動し、「CIS_2-4_RR」という名前の関数を選択して、環境変数まで下にスクロールします
  2. Key が「CLOUDTRAIL_CW_LOGGING_ROLE_ARN」、Value が「placeholder」となっている環境変数見つける
  3. IAM ロールの ARN を Value フィールドに貼り付け、保存を選択します

プレイブックの修正: CIS 2.6 の対応と修復

CIS コントロール 2.6 は、「S3 バケットアクセスログ記録が CloudTrail S3 バケットで有効になっていることを確認します」です。アクセスログには、リクエストタイプ、リクエストで指定されたリソース、リクエストが処理された日時など、リクエストに関する詳細が含まれます。AWS は、CloudTrail 証跡情報を保存している S3 バケットで バケットアクセスのログ記録を有効にすることをお勧めします。対象の S3 バケットで S3 バケットロギングを有効にすることで、バケット内のオブジェクトに影響を与える可能性のあるすべてのイベントを捕捉できます。ログを専用のバケットに配置するように構成し、アクセスログ情報の集中収集をすると、セキュリティのインシデント対応で役立ちます。

: Security Hub が CIS AWS Foundations のコントールをサポートするのは、リソースが、有効化された Security Hub と同じリージョンで同じアカウントに所有されている場合のみです。例えば、us-east-2 リージョンで Security Hub を使っていて、us-west-2 リージョンで CloudTail のログを S3 バケットに保存している場合、Security Hub はus-west-2 リージョンのバケットを見つけることはできません。コントロールは、リソースが見つからないという警告を返します。同様に、複数のアカウントからのログを単一のバケットに集約する場合、バケットを所有するアカウントを除くすべてのアカウントの CIS コントロールは失敗します。

CloudTrail ログを含む S3 バケットでアクセスログが有効になっていることを確認するために、このプレイブックの Lambda 関数は Systems Manager ドキュメントの「AWS-ConfigureS3BucketLogging」を呼び出します。このドキュメントは、このバケットのアクセスロギングを有効にします。Lambda 関数のコードに 静的に S3 アクセスログのバケット名を記述するのを避けるには、環境変数を利用して値を渡します。

: 現在、アクセスログを受信するように設定されたS3バケットがない場合は、S3 開発ガイドの手順に従って作成してください。

このプレイブックの修正方法:

  1. Lambda コンソールに移動し、「CIS_2-6_RR」という名前の関数を選択して、環境変数まで下にスクロールします
  2. Key が「ACCESS_LOGGING_BUCKET」、Value が「placeholder」となっている環境変数見つける
  3. アクセスログを受信する S3 バケットの名前をValue フィールドに貼り付け、保存を選択します

プレイブックの修正: CIS 2.9 の対応と修復

CIS コントロール 2.9は、「すべての VPC で VPC フローログ記録が有効になっていることを確認します」です。 Amazon Virtual Private Cloud (VPC)フローログ機能を使用すると、VPC のネットワークインターフェイスを行き来する IP トラフィック情報を捕捉できます。フローログを作成したら、CloudWatch Logs でデータを表示および取得できます。AWS では、VPC のパケット拒否のフローログ記録を有効にすることをお勧めします。フローログは、VPC を通過するネットワークトラフィックの可視性を提供し、異常なトラフィックを検出したり、セキュリティワークフローのインサイトを提供したりできます。

拒否されたパケットの VPC フローログ記録を有効にすると、このプレイブックの Lambda 関数は新しい CloudWatch Logsグループを作成します。簡単に識別できるように、グループの名前には非準拠の VPC 名が含まれます。Lambda 関数はプログラムで VPC を更新し、新しく作成されたロググループにフローログを送信できるようにします。

CloudTrail ログ記録と同様に、VPC フローログには、ログを CloudWatch Logs に発行することを許可する IAM ロールとアクセス許可が必要です。Lambda が複数の新しい IAM ロールとポリシーを作成しないようにするには、このプレイブック の Lambda 環境変数にこの IAM ロールの ARN を入力します。

: 現在、VPC フローログが CloudWatch Logs にログを配信するために使用できる IAM ロールがない場合は、VPC ユーザーガイドの手順に従ってロールを作成してください。

このプレイブックの修正方法:

  1. Lambda コンソールに移動し、「CIS_2-9_RR」という名前の関数を選択して、環境変数まで下にスクロールします
  2. Key が「flowLogRoleARN」、Value が「placeholder」となっている環境変数見つける
  3. VPC フローログ の IAM ロールの ARN を Value フィールドに貼り付け、保存を選択します

まとめ

本ブログでは、Security Hub の対応と修復のプレイブックを作成、デプロイ、実行する方法を示しました。カスタムアクション、CloudWatch Events ルール、および Lambda 関数を組み合わせることで、非準拠リソースをすばやく修復できます。また、検出結果を JIRA に送信するなど、事前に定義されたアクションを実行する方法、および CloudFormation プレイブックをデプロイする方法も紹介しました。

他のアクションを実行するプレイブックを作成することもできるでしょう。例えば、GuardDuty がUnauthorizedAccess:EC2/TorIPCaller を検出した時に、TOR の EXIT ノード からの悪意のあるトラフィックをブロックするために、ネットワークアクセスコントロールリストを更新するプレイブックです。Security Hub でプレイブックを使用することは、AWS リソースのセキュリティとコンプライアンスを構築する1つの方法です。

最後にクリーナップをします。AWS リソースから追加料金が発生しないように、デプロイした CloudFormation スタックと、手動で作成した「CIS 2.7 対応と修復プレイブック」のリソースを削除してください。

本ブログについての質問は、Security Hub フォーラムで新しいスレッドを開始するか、AWSサポートにお問い合わせください 。

AWS Securityのハウツーコンテンツ、ニュース、新機能の発表は Twitter をフォローしてください。

Jonathon Rau

Jonathan Rau

Jonathan は AWS Security Hub のシニア TPM です。彼は AWS 認定セキュリティ – 専門知識を取得しており、サイバーセキュリティ、データプライバシー、ブロックチェーンなどの新しいテクノロジーに多くの情熱を注いでいます。彼は個人的な時間も同じテーマに関する研究と支援活動に費やしています。

ブログの原文はこちらです。
翻訳は SA 中島 が担当しました。