IAM Access AnalyzerのIAM Roleをアーカイブするルールを複数リージョンで作成するスクリプト

2022.11.30

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

こんにちは。たかやまです。

こちらのブログで紹介したとおりIAM Access AnalyzerのIAM Role検知はすべてのリージョンで行われてしまうため通知する場合にノイズになります。ブログではEventBridgeを使い、IAM Roleの通知を抑制する方法をご紹介しました。

このブログを書いたあとアーカイブルールでIAM Roleを抑制すれば同様のことができるなと思い、今回はマルチリージョンにIAM Roleの検知を抑制するアーカイブルールの作成スクリプトをご紹介したいと思います。

後述しますが、こちらのほうがSecurity Hubの情報もすっきりするのでおすすめです。

1つのリージョンを除いてアーカイブルールを作成する

複数リージョンでIAM Role検知のアーカイブルールを作成するスクリプトはこちらになります。各変数には環境に合わせて以下の値を設定してCloudShellなどで実行してください。

  • analyzer_name : 作成済みIAM Access Analyzerの名前
  • rule_name : 作成するアーカイブルールの名前
  • exc_region : アーカイブルールを作成しないリージョン
analyzer_name="cm-access-analyzer"
rule_name="ArchiveRule-Iam-Role"
exc_region="ap-northeast-1"
aws ec2 describe-regions --query Regions[].[RegionName] --output text \
| while read region; do
    if [[ ${region} != ${exc_region} ]]; then
        aws accessanalyzer create-archive-rule --analyzer-name ${analyzer_name} \
        --rule-name ${rule_name} \
        --filter '{"resourceType":{"eq":["AWS::IAM::Role"]}}' \
        --region ${region}
        echo "Created in ${region}";
    fi
  done
実行結果

ap-northeast-1(東京リージョン)で作成しないパターン

[cloudshell-user@ip-10-1-94-139 ~]$ analyzer_name="cm-access-analyzer"
[cloudshell-user@ip-10-1-94-139 ~]$ rule_name="ArchiveRule-Iam-Role"
[cloudshell-user@ip-10-1-94-139 ~]$ exc_region="ap-northeast-1"
[cloudshell-user@ip-10-1-94-139 ~]$ aws ec2 describe-regions --query Regions[].[RegionName] --output text \
> | while read region; do
>     if [[ ${region} != ${exc_region} ]]; then
>         aws accessanalyzer create-archive-rule --analyzer-name ${analyzer_name} \
>         --rule-name ${rule_name} \
>         --filter '{"resourceType":{"eq":["AWS::IAM::Role"]}}' \
>         --region ${region}
>         echo "Created in ${region}";
>     fi
>   done
Created in ap-south-1
Created in eu-north-1
Created in eu-west-3
Created in eu-west-2
Created in eu-west-1
Created in ap-northeast-3
Created in ap-northeast-2
Created in ca-central-1
Created in sa-east-1
Created in ap-southeast-1
Created in ap-southeast-2
Created in eu-central-1
Created in us-east-1
Created in us-east-2
Created in us-west-1
Created in us-west-2

作成後の確認コマンドはこちらになります。

analyzer_name="cm-access-analyzer"
rule_name="ArchiveRule-Iam-Role"
aws ec2 describe-regions --query Regions[].[RegionName] --output text \
| while read region; do
    echo "### ${region} ###";
    aws accessanalyzer get-archive-rule --analyzer-name ${analyzer_name} \
    --rule-name ${rule_name} \
    --query archiveRule.[ruleName,createdAt] \
    --region ${region} \
    --output text ;
  done

作成しないap-northeasst-1(東京リージョン)ではArchive rule not foundのエラーメッセージが出ます。

[cloudshell-user@ip-10-0-8-183 ~]$ analyzer_name="cm-access-analyzer"
[cloudshell-user@ip-10-0-8-183 ~]$ rule_name="ArchiveRule-Iam-Role"
[cloudshell-user@ip-10-0-8-183 ~]$ aws ec2 describe-regions --query Regions[].[RegionName] --output text \
> | while read region; do
>     echo "### ${region} ###";
>     aws accessanalyzer get-archive-rule --analyzer-name ${analyzer_name} \
>     --rule-name ${rule_name} \
>     --query archiveRule.[ruleName,createdAt] \
>     --region ${region} \
>     --output text ;
>   done
### ap-south-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:43+00:00
### eu-north-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:44+00:00
### eu-west-3 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:45+00:00
### eu-west-2 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:46+00:00
### eu-west-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:47+00:00
### ap-northeast-3 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:49+00:00
### ap-northeast-2 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:50+00:00
### ap-northeast-1 ###

An error occurred (ResourceNotFoundException) when calling the GetArchiveRule operation: Archive rule not found
### ca-central-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:52+00:00
### sa-east-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:53+00:00
### ap-southeast-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:54+00:00
### ap-southeast-2 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:56+00:00
### eu-central-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:57+00:00
### us-east-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:58+00:00
### us-east-2 ###
ArchiveRule-Iam-Role    2022-11-29T15:27:59+00:00
### us-west-1 ###
ArchiveRule-Iam-Role    2022-11-29T15:28:00+00:00
### us-west-2 ###
ArchiveRule-Iam-Role    2022-11-29T15:28:01+00:00

アーカイブルールが不要になったときに削除する場合はこちら

analyzer_name="cm-access-analyzer"
rule_name="ArchiveRule-Iam-Role"
aws ec2 describe-regions --query Regions[].[RegionName] --output text \
| while read region; do
    echo "### ${region} ###";
    aws accessanalyzer delete-archive-rule --analyzer-name ${analyzer_name} \
    --rule-name ${rule_name} \
    --region ${region}
    echo "Deleted in ${region}"
  done
実行結果

ap-northeast-1(東京リージョン)で作成しないパターン

[cloudshell-user@ip-10-0-15-236 ~]$ analyzer_name="cm-access-analyzer"
[cloudshell-user@ip-10-0-15-236 ~]$ rule_name="ArchiveRule-Iam-Role"
[cloudshell-user@ip-10-0-15-236 ~]$ aws ec2 describe-regions --query Regions[].[RegionName] --output text \
> | while read region; do
>     echo "### ${region} ###";
>     aws accessanalyzer delete-archive-rule --analyzer-name ${analyzer_name} \
>     --rule-name ${rule_name} \
>     --region ${region}
>     echo "Deleted in ${region}"
>   done
### ap-south-1 ###
Deleted in ap-south-1
### eu-north-1 ###
Deleted in eu-north-1
### eu-west-3 ###
Deleted in eu-west-3
### eu-west-2 ###
Deleted in eu-west-2
### eu-west-1 ###
Deleted in eu-west-1
### ap-northeast-3 ###
Deleted in ap-northeast-3
### ap-northeast-2 ###
Deleted in ap-northeast-2
### ap-northeast-1 ###
Deleted in ap-northeast-1
### ca-central-1 ###
Deleted in ca-central-1
### sa-east-1 ###
Deleted in sa-east-1
### ap-southeast-1 ###
Deleted in ap-southeast-1
### ap-southeast-2 ###
Deleted in ap-southeast-2
### eu-central-1 ###
Deleted in eu-central-1
### us-east-1 ###
Deleted in us-east-1
### us-east-2 ###
Deleted in us-east-2
### us-west-1 ###
Deleted in us-west-1
### us-west-2 ###
Deleted in us-west-2

検証

SNS/Chatbotの設定はこちらのブログを参考にしてください。

EventBridgeの設定

EventBridgeでリージョンによるフィルタリングは行わず、すべてのIAM Access Analyzerのイベント検知するイベントパターンを用意します。

{
  "detail-type": ["Security Hub Findings - Imported"],
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "ProductName": ["IAM Access Analyzer"],
      "RecordState": ["ACTIVE"],
      "Severity": {
        "Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
      }
    }
  }
}

用意される構成はこんな感じ
ap-northeast-1(東京リージョン)以外はアーカイブされているため、IAM Roleのイベントはap-northeast-1のもののみ通知されます。

IAM Roleの作成

以下のAWS CLIでクロスアカウントなRoleを作成していきます。
YOUR_CROSSACCOUNTIDはご自身の対象のクロスアカウントIDを設定してください。

aws iam create-role --role-name accessanalyzer-test-role \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"sts:AssumeRole","Principal":{"AWS":"YOUR_CROSSACCOUNTID"},"Condition":{}}]}'

クロスアカウントなRoleが作成されるとIAM Access Analyzerで検知されます。
このとき、複数通知ではなく1つだけ通知が来ていればアーカイブがうまくできています。

このときSecurity Hubの情報も一つのみ記録され、すっきりします。

ちなみにアーカイブルールを作成しないですべてのリージョンでIAM Roleを検知したときのSecurity Hub上の画面こちらになります。

EventBridgeでフィルタリングする場合、通知は1つにできますがSecurity Hub上では複数イベントが記録される状態になるのでアーカイブルール側で制御するほうが管理上よいかと思います。

検証後のテストRoleの削除コマンドこちら

aws iam delete-role --role-name accessanalyzer-test-role

最後に

Security Hubでの管理を考慮したとき、アーカイブルールを使うことでSecurity Hubでの管理も楽にすることができます。

アーカイブルールの展開方法はAWS CLIを使った方法をご紹介しましたが、CloudFormationでも展開可能なのでお好きな方法で管理いただければと思います。

AWS::AccessAnalyzer::Analyzer - AWS CloudFormation

アーカイブルールを活用してIAM Access Analyzerを効率よく管理しましょう!

以上、たかやま(@nyan_kotaroo)でした。