新しい修復の追加 - AWS での自動化されたセキュリティ対応

新しい修復の追加

修復は、適切なプレイブックファイルを更新して手動で追加することも、特定のワークフローに応じて CDK コンストラクト経由でソリューションを拡張することでプログラムで追加することもできます。

注記

この後の説明では、このソリューションによってインストールされたリソースを開始点として活用します。慣例により、ほとんどのソリューションのリソース名には ASRSO0111 が含まれ、見つけやすく、特定しやすいようになっています。

手動ワークフローの概要

AWS での自動化されたセキュリティ対応のランブックは、次の標準的な命名規則に従う必要があります。

ASR-<standard>-<version>-<control>

Standard: セキュリティ標準の略称です。これは ASR がサポートする基準と一致する必要があります。CIS、AFSBP、PCI、NIST、または SC のいずれかでなければなりません。

Version: セキュリティ基準のバージョン。これも、ASR がサポートするバージョンおよび検出結果データのバージョンと一致する必要があります。

Control: 修復するコントロールのコントロール ID。これは検出結果データと一致する必要があります。

  1. メンバーアカウントでランブックを作成します。

  2. メンバーアカウントで IAM ロールを作成します。

  3. (オプション) 管理者アカウントで自動修復ルールを作成します。

ステップ 1. メンバーアカウントでランブックを作成する

  1. AWS Systems Manager コンソールにサインインし、検出結果の JSON の例を取得します。

  2. 検出結果を修復するオートメーションランブックを作成します。[自己所有] タブで、[ドキュメント] タブの下にある任意の ASR- ドキュメントを開始点として使用します。

  3. 管理者アカウントの AWS Step Functions がランブックを実行します。ランブックをコールしたときにロールを渡すために、ランブックで修復ロールを指定する必要があります。

ステップ 2. メンバーアカウントで IAM ロールを作成する

  1. AWS Identity and Access Management コンソールにサインインします。

  2. IAM SO0111 ロールから例を取得し、新しいロールを作成します。ロール名は SO0111-Remediate-<standard>-<version>-<control> で始まる必要があります。例えば、CIS v1.2.0 コントロール 5.6 を追加する場合、このロールは SO0111-Remediate-CIS-1.2.0-5.6 である必要があります。

  3. この例を使用して、修復を実行するために必要な API 呼び出しのみを許可する、適切な範囲が設定されたロールを作成します。

この時点で、修復はアクティブになり、AWS Security Hub の ASR カスタムアクションからの自動修復が可能になります。

ステップ 3: (オプション) 管理者アカウントで自動修復ルールを作成する

自動修復とは (「自動化修復」ではなく)、AWS Security Hub が検出結果を受け取ると、すぐに修復を実行することです。このオプションを使用する前に、慎重にリスクを検討するようにしてください。

  1. CloudWatch Events で同じセキュリティ標準のルール例を確認してください。ルールの命名規則は、standard_control_*AutoTrigger* になります。

  2. 使用する例からイベントパターンをコピーします。

  3. GeneratorId の値を、JSON の検出結果の GeneratorId と一致するように変更します。

  4. ルールを保存してアクティブにします。

CDK ワークフローの概要

要約すると、ASR リポジトリ内の以下のファイルは変更または追加されます。この例では、ElastiCache.2 の新しい修復が SC および AFSBP プレイブックに追加されています。

注記

すべての新しい修復は、SC プレイブックに追加する必要があります。このプレイブックは、ASR で利用可能なすべての修復を統合するためです。特定のプレイブックのセット (AFSBP など) のみをデプロイする場合は、(1) 目的のプレイブックのみに修復を追加するか、(2) SC プレイブックに加えて、対応する Security Hub の標準内に存在するすべてのプレイブックに修復を追加します。2 番目のオプションは柔軟性を確保するために推奨されます。

この例では、ElastiCache.2 を以下の Security Hub の標準に含めています。

  • AFSBP

  • NIST.800-53.r5 SI-2

  • NIST.800-53.r5 SI-2(2)

  • NIST.800-53.r5 SI-2(4)

  • NIST.800-53.r5 SI-2(5)

  • PCI DSS v4.0.1/6.3.3

デフォルトでは、ASR は AFSBP と NIST.800-53 のプレイブックのみを実装するため、SC に加えてこれらのプレイブックにこの新しい修復を追加します。

Modify

  • source/lib/remediation-runbook-stack.ts

  • source/playbooks/AFSBP/lib/[標準名]_remediations.ts

  • source/playbooks/NIST80053/lib/control_runbooks-construct.ts

  • source/playbooks/NIST80053/lib/[標準名]_remediations.ts

  • source/playbooks/SC/lib/control_runbooks-construct.ts

  • source/playbooks/SC/lib/sc_remediations.ts

  • source/test/regex_registry.ts

追加

  • source/playbooks/SC/ssmdocs/SC_ElastiCache.2.ts

  • source/playbooks/SC/ssmdocs/descriptions/ElastiCache.2.md

  • source/remediation_runbooks/EnableElastiCacheVersionUpgrades.yaml

注記

ランブックに選択する名前は、実施する残りの変更と一致する限り、任意の文字列にすることができます。

  • source/playbooks/NIST80053/ssmdocs/NIST80053_ElastiCache.2.ts

  • source/playbooks/AFSBP/ssmdocs/AFSBP_ElastiCache.2.yaml

開発ステップ

  1. 修復ランブックを作成します。

  2. コントロールランブックを作成します。

  3. 各コントロールランブックをプレイブックと統合します。

  4. 修復 IAM ロールを作成し、修復ランブックを統合します。

  5. ユニットテストを更新します。

ステップ 1: 修復ランブックを作成する

これは、リソースの修復に使用する SSM ドキュメントです。修復を実行するアクセス許可を持つ IAM ロールである AutomationAssumeRole パラメータを含める必要があります。新しい修復ランブックを作成するときに、既存のファイル source/remediation_runbooks/EnableElastiCacheVersionUpgrades.yaml をリファレンスとして参照します。

すべての新しいランブックを source/remediation_runbooks/ ディレクトリに追加する必要があります。

ステップ 2: コントロールランブックを作成する

コントロールランブックは、特定の標準の検出結果データを解析し、適切な修復ランブックを実行するプレイブック固有のランブックです。SC、AFSBP、NIST80053 の各プレイブックに ElastiCache.2 修復を追加するため、それぞれに新しいコントロールランブックを作成する必要があります。以下のファイルが作成されます。

  • source/playbooks/SC/ssmdocs/SC_ElastiCache.2.ts

  • source/playbooks/NIST80053/ssmdocs/NIST80053_ElastiCache.2.ts

  • source/playbooks/AFSBP/ssmdocs/AFSBP_ElastiCache.2.yaml

これらのファイルの命名は重要であり、<PLAYBOOK_NAME>_<CONTROL.ID>.ts/yaml の形式に従う必要があります。

ASR のプレイブックの中には、TypeScript の IaC コントロールランブックをサポートするものもあれば、raw YAML で記述する必要があるものもあります。それぞれのプレイブックの既存の修復を例として参照してください。この例では、IaC を使用する SC プレイブックについて説明します。

SC プレイブックでは、新しいコントロールランブックにより、ControlRunbookDocument を拡張して修復ランブック名と一致するクラスをエクスポートする必要があります。次の例を参照してください。

export class EnableElastiCacheVersionUpgrades extends ControlRunbookDocument {
  constructor(scope: Construct, id: string, props: ControlRunbookProps) {
    super(scope, id, {
      ...props,
      securityControlId: 'ElastiCache.2',
      remediationName: 'EnableElastiCacheVersionUpgrades',
      scope: RemediationScope.REGIONAL,
      resourceIdRegex: <Regex>,
      resourceIdName: 'ClusterId',
      updateDescription: new StringFormat('Automatic minor version upgrades enabled for cluster %s.', [
        StringVariable.of(`ParseInput.ClusterId`),
      ]),
    });
  }
}
  • securityControlId は、Security Hub の統合コントロールビューで定義しているように、追加する修復のコントロール ID です。

  • remediationName は、修復ランブックに選択した名前です。

  • scope は、修復範囲のリソースであり、グローバルに存在するか、特定のリージョンに存在するかを示します。

  • resourceIdRegex は、修復ランブックにパラメータとして渡すリソース ID をキャプチャするために使用する正規表現です。キャプチャ対象のグループは 1 つのみとし、他のすべてのグループはキャプチャ対象外とします。ARN 全体を渡す場合は、このフィールドを省略します。

  • resourceIdName は、resourceIdRegex を使用してキャプチャするリソース ID に設定する名前です。これは、修復ランブックのリソース ID パラメータ名と一致する必要があります。

  • updateDescription は、修復が成功したら、Security Hub の検出結果の [注意] セクションに割り当てる文字列です。

また、クラスの新しいインスタンスを返す createControlRunbook という関数をエクスポートする必要があります。ElastiCache.2 の場合は、次のようになります。

export function createControlRunbook(scope: Construct, id: string, props: PlaybookProps): ControlRunbookDocument {
  return new EnableElastiCacheVersionUpgrades(scope, id, { ...props, controlId: 'ElastiCache.2' });
}

ここで、controlId は、セキュリティ標準に定義されているコントロール ID であり、運用に使用しているプレイブックに関連しています。

修復ランブックに渡すパラメータが Security Hub コントロールにある場合は、オーバーライドを追加した getExtraSteps メソッドを渡すことができます。このメソッドは、Security Hub でコントロールに実装する各パラメータのデフォルト値を定義します。

注記

Security Hub の各パラメータにはデフォルト値を指定する必要があります。

  • getInputParamsStepOutput: コントロールランブックの GetInputParams ステップの出力を定義します。

  • 出力ごとに nameoutputTypeselector があります。selector は、getExtraSteps メソッドのオーバーライドで使用するのと同じセレクタである必要があります。

  • getRemediationParams: 修復ランブックに渡すパラメータを定義します。これらのパラメータは、GetInputParams ステップの出力から取得します。

例を表示するには、 source/playbooks/SC/ssmdocs/SC_DynamoDB.1.ts ファイルに移動します。

ステップ 3: 各コントロールランブックをプレイブックと統合する

前のステップで作成した各コントロールランブックを、関連するプレイブックのインフラストラクチャ定義と統合する必要があります。コントロールランブックごとに、以下の手順に従います。

重要

typescript IaC の代わりに raw YAML を使用してコントロールランブックを作成した場合は、次のセクションに進みます。

/<playbook_name>/control_runbooks-construct.ts で、新しく作成したコントロールランブックファイルを、次のようにインポートします。

import * as elasticache_2 from '../ssmdocs/SC_ElastiCache.2';

次に、以下の配列に移動します。

const controlRunbooksRecord: Record<string, any>

また、作成した createControlRunbook メソッドにコントロール ID (プレイブック固有) をマッピングする新しいエントリを追加します。

'ElastiCache.2': elasticache_2.createControlRunbook,

プレイブック固有のコントロール ID を <playbook_name>\_remediations.ts の修復のリストに、次のように追加します。

{ control: 'ElastiCache.2', versionAdded: '2.3.0' },

versionAdded フィールドは、ソリューションの最新バージョンである必要があります。修復を追加すると、テンプレートのサイズ制限を超える場合は、versionAdded を増やします。solution_env.sh の各プレイブックメンバースタックに含める修復の数は調整できます。

ステップ 4: 修復 IAM ロールを作成し、修復ランブックを統合する

修復ごとに、修復ランブックの実行に必要なカスタムアクセス許可を持つ独自の IAM ロールがあります。さらに、ステップ 1 で作成した修復ランブックをソリューションの CloudFormation テンプレートに追加するには、RunbookFactory.createRemediationRunbook メソッドを呼び出す必要があります。

remediation-runook-stack.ts には、修復ごとに独自のコードブロックが RemediationRunbookStack クラスにあります。次のコードブロックは、ElastiCache.2 修復用の新しい IAM ロールと修復ランブック統合の作成を示しています。

    //-----------------------
    // EnableElastiCacheVersionUpgrades
    //
    {
      const remediationName = 'EnableElastiCacheVersionUpgrades'; // should match the name of your remediation runbook
      const inlinePolicy = new Policy(props.roleStack, `ASR-Remediation-Policy-${remediationName}`);

      const remediationPolicy = new PolicyStatement();
      remediationPolicy.addActions('elasticache:ModifyCacheCluster');
      remediationPolicy.effect = Effect.ALLOW;
      remediationPolicy.addResources(`arn:${this.partition}:elasticache:*:${this.account}:cluster:*`);
      inlinePolicy.addStatements(remediationPolicy);

      new SsmRole(props.roleStack, 'RemediationRole ' + remediationName, { // creates the remediation IAM role
        solutionId: props.solutionId,
        ssmDocName: remediationName,
        remediationPolicy: inlinePolicy,
        remediationRoleName: `${remediationRoleNameBase}${remediationName}`,
      });

      RunbookFactory.createRemediationRunbook(this, 'ASR ' + remediationName, { // adds the remediation runbook to the solution's cloudformation templates
        ssmDocName: remediationName,
        ssmDocPath: ssmdocs,
        ssmDocFileName: `${remediationName}.yaml`,
        scriptPath: `${ssmdocs}/scripts`,
        solutionVersion: props.solutionVersion,
        solutionDistBucket: props.solutionDistBucket,
        solutionId: props.solutionId,
        namespace: namespace,
      });
    }

ステップ 5: ユニットテストを更新する

新しい修復の追加後に、ユニットテストを更新して実行することをお勧めします。

まず、新しい正規表現 (まだ追加していないもの) を source/test/regex_registry.ts ファイルに追加する必要があります。このファイルは、ソリューションのランブックに含まれる新しい正規表現ごとにテストを適用します。ElastiCache 修復で使用する正規表現をテストするための addElastiCacheClusterTestCases 関数を例として示します。

最後に、各スタックのスナップショットを更新する必要があります。スナップショットは、ASR のインフラストラクチャに加えられた変更を追跡するためのバージョン管理された CloudFormation テンプレート定義です。これらのスナップショットファイルを更新するには、deployment ディレクトリから次のコマンドを実行します。

./run-unit-tests.sh update

これで、新しい修復をデプロイする準備が整いました。次のビルドとデプロイに関するセクションに移動し、新しい変更を反映してソリューションをビルドおよびデプロイする手順を参照してください。