AWS Security Hubのセキュリティ基準・コントロールをAWS CLIから有効・無効化してみた

2023.03.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS Security HubはAWS のセキュリティチェックの自動化とセキュリティアラートを一元化するサービスです。

いざ導入してみると、ありとあらゆるコントロールが失敗し、アクションの必要な検知に気づくのも一苦労です。

通知対象を絞るのも有力ですが、根本であるセキュリティ基準とコントロールをAWS CLIから有効・無効化して間引く方法を紹介します。

今回のAWS CLI方式は、各AWSアカウントで作業が必要です。 システム化まで手が回っていなかったり、管理対象のAWSアカウントが少数の場合に向いています。

セキュリティ基準の操作

セキュリティ基準の初期設定

Security Hubの有効化とセキュリティ基準の初期設定は一部独立しています。Security Hubの有効化方法により、有効化される基準は異なります。

マネジメントコンソールから操作する場合、Security Hub有効化のタイミングで、有効にする基準を設定できます。

APIでSecurity Hubを有効にすると、次の2つのセキュリティ基準が有効化されます。

  • AWS Foundational Security Best Practices(FSBP)
  • CIS v1.2.0

Security HubをOrganizationsと連携している場合、Security Hubの有効化とデフォルトのセキュリティ基準(上記2つ)の有効・無効を独立に設定できます。

AWS Security HubのOrganizations統合で自動有効化されるセキュリティ基準を無効化できるようになりました | DevelopersIO

AWS FSBP基準だけを利用したい場合

  • Security Hub : 有効化
  • デフォルトのセキュリティ基準 : 無効化

としておくと、アカウント開設直後から発生するCIS基準のコントロール失敗に悩まされなくて済みます。

利用するAWS FSBP基準は管理者が明示的に有効化します。

有効・無効化操作

基準の初期状態と理想とする状態によって、基準の有効・無効操作が必要です。

例1)

AWS FSBP基準だけを利用したいのに、基準が何も有効化されていない場合、AWS FSBP基準だけを有効化します。

有効化時には securityhub::batch-enable-standards で基準の StandardsArn を渡します。

$ aws securityhub batch-enable-standards \
  --standards-subscription-requests arn:aws:securityhub:ap-northeast-1::standards/aws-foundational-security-best-practices/v/1.0.0

例2)

AWS FSBP基準だけを利用したいのに、AWS FSBPとCIS 1.2の2つの基準が有効化されている場合、CIS 1.2基準を無効化します。

無効化時には securityhub::batch-disable-standards で基準の StandardsSubscriptionArn を渡します。

$ aws securityhub batch-disable-standards \
  --standards-subscription-arn arn:aws:securityhub:ap-northeast-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0

以上を踏まえ、全リージョンで

  • AWS FSBP基準を有効化
  • CIS v1.2基準を無効化

するのが次のスクリプトです。

要件に合わせてカスタマイズしてください。

#!/bin/bash

aws ec2 describe-regions --query "Regions[].[RegionName]" --output text \
| while read region; do
    echo ${region}

    # enable FSBP
    STANDARD_ARN=$(printf '{"StandardsArn\":\"arn:aws:securityhub:%s::standards/aws-foundational-security-best-practices/v/1.0.0\"}' $region)
    aws securityhub --region ${region} \
          batch-enable-standards --standards-subscription-requests $STANDARD_ARN

    # disable CIS 1.2
    aws securityhub --region ${region} \
      batch-disable-standards --standards-subscription-arn "arn:aws:securityhub:${region}:$(aws sts get-caller-identity --query Account --output text):subscription/cis-aws-foundations-benchmark/v/1.2.0"
    
    echo 調整後
    aws securityhub  get-enabled-standards --query 'StandardsSubscriptions[*]'.StandardsArn --region ${region} --output json
    echo
done

基準のARN

2023年3月時点では、以下の4種類の基準が提供されています。

Standards StandardsArn StandardsSubscriptionArn
AWS Foundational Security Best Practices (FSBP) 1.0.0 arn:aws:securityhub:ap-northeast-1::standards/aws-foundational-security-best-practices/v/1.0.0 arn:aws:securityhub:ap-northeast-1:123456789012:subscription/aws-foundational-security-best-practices/v/1.0.0
CIS 1.2 arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0 arn:aws:securityhub:ap-northeast-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0
CIS 1.4 arn:aws:securityhub:ap-northeast-1::standards/cis-aws-foundations-benchmark/v/1.4.0 arn:aws:securityhub:ap-northeast-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.4.0
PCI DSS 3.2.1 arn:aws:securityhub:ap-northeast-1::standards/pci-dss/v/3.2.1 arn:aws:securityhub:ap-northeast-1:123456789012:subscription/pci-dss/v/3.2.1

$ aws securityhub describe-standards で基準一覧とそのARNを確認できます。

  • 基準の有効化では StandardsArn
  • 基準の無効化では StandardsSubscriptionArn

と利用するARNが異なるので、ご注意ください。

基準によってはアカウントIDやリージョン情報が含まれているため、同じスクリプトを任意のアカウント・リージョンで実行する場合、ARNを動的に生成してください。

サンプルは次のアカウントID/リージョンを例にしています

  • アカウントID: 123456789012
  • リージョン:東京

コントロールの操作

対応が難しいコントロールを無効化したり、一度無効化したコントロールを有効化する場合の操作です。

securityhub::update-standards-control APIでコントロールの StandardsControlArn を渡し、--control-statusで 有効(ENABLED)/無効(DISABLED)を指定します。 無効化の場合は理由(--disabled-reason) も必要です。

コントロールのARNは securityhub::describe-standards-controls で確認できます。コントロールにはIDが振られており、同じ基準であればARNのID部分だけが異なります。

例1)

AWS FSBPのIAM.6を無効にします。

$ aws securityhub update-standards-control \
    --standards-control-arn arn:aws:securityhub:ap-northeast-1:123456789012:control/aws-foundational-security-best-practices/v/1.0.0/IAM.6 \
    --disabled-reason 不要 \
    --control-status DISABLED

例2)

AWS FSBPのIAM.6を有効にします。

$ aws securityhub update-standards-control \
    --standards-control-arn arn:aws:securityhub:ap-northeast-1:123456789012:control/aws-foundational-security-best-practices/v/1.0.0/IAM.6 \
    --control-status ENABLED

以上を踏まえ、全リージョンのAWS FSBP基準に対して

  • 変数 disabled_control で指定したコントロールを無効化
  • 変数 enabled_control で指定したコントロールを有効化

するのが次のスクリプトです。

API呼び出しの違いから、有効化はコントロールIDだけを管理し、無効化はコントロールIDと理由も管理しています。

要件に合わせてカスタマイズしてください。

#!/bin/bash

ACCOUNT_ID=`aws sts get-caller-identity --output text --query Account`

# 無効化ID一覧
declare -A disabled_control

## Critical

### IAM.6	: ハードウェア MFA はルートユーザーに対して有効にする必要があります
disabled_control[IAM.6]="不要"

## High

### EC2.8	: EC2 インスタンスでは、Instance Metadata Service Version 2 (IMDSv2) を使用する必要があります
disabled_control[EC2.8]="不要"

# 有効化ID一覧
declare -a enabled_control

## Critical
enabled_control+=(
IAM.4
EC2.1
)

## High
enabled_control+=(
CloudTrail.1
)

aws ec2 describe-regions --query "Regions[].[RegionName]" --output text \
| while read region; do
    echo ${region}

    echo "コントロール無効化"
    for id in "${!disabled_control[@]}"
    do
        STD_CONTROL_ARN="arn:aws:securityhub:${region}:$ACCOUNT_ID:control/aws-foundational-security-best-practices/v/1.0.0/$id"
        echo "id  : $id"
        aws securityhub update-standards-control \
          --standards-control-arn $STD_CONTROL_ARN \
          --disabled-reason ${disabled_control[$id]} \
          --control-status DISABLED \
          --region $region
    done

    echo "コントロール有効化"
    for id in "${enabled_control[@]}"
    do
        STD_CONTROL_ARN="arn:aws:securityhub:${region}:$ACCOUNT_ID:control/aws-foundational-security-best-practices/v/1.0.0/$id"
        echo "id  : $id"
        aws securityhub update-standards-control \
            --standards-control-arn $STD_CONTROL_ARN \
            --control-status ENABLED \
            --region $region
    done
done

最後に

AWS Security Hubのセキュリティ基準・コントロールの有効・無効化をAWS CLIから行う方法を紹介しました。

今回紹介したシェルスクリプトでは、見通しの良さを優先して、Security Hubの有効済み判定など、諸々の条件分岐を入れていません。無駄なAPIが走って時間が余計にかかり、仮にAPIが失敗しても実害のないエラーが発生するだけですので。

今回紹介したような操作がCloudFormationだけで行えると、StackSetsを使った複数アカウントへの展開が楽になります。

現状のSecurity HubのCloudFormation 対応は非常に貧弱なので、早く強化してほしいところです。

それでは。

参考