0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IAM Identity Center の一時的な認証情報を使って複数 AWS アカウントのセキュリティサービス有効化状況をチェックするスクリプトを作ってみた

Last updated at Posted at 2025-07-11

こんにちは、CSC の平木です!

複数の AWS アカウントを管理している環境では、セキュリティサービスの設定状況を一括で確認したいことがありますよね。
今回は、IAM Identity Centerの一時的な認証情報を使用して、複数の AWS アカウントにスイッチロールし、AWS Security HubAWS GuardDutyIAM Access Analyzer の有効化状況をチェックするスクリプトを作成してみました。

背景

  • とある制約からスイッチロール元では CloudShell が使用できない
  • Organizations 外の AWS アカウントのセキュリティサービスの有効化状況をスイッチロール経由で確認したい

上記のため、今回は、IAM Identity Centerの一時的な認証情報から各 AWS アカウントへスイッチロールしチェックしてみました。

aws_iic_switch.png

やってみた

前提条件

必要な設定

  • IAM Identity Center のプロファイル設定済み
  • 各対象アカウントでのスイッチロール権限
  • Security Hub の読み取り権限

必要なツール

  • AWS CLI(v2 推奨)
  • jq(JSON パーサー)
  • bash(スクリプト実行環境)

スクリプトの構成

ファイル構成

コードは下記 GitHub リポジトリにも配置済みです。

aws-security-audit-checker-scripts/
├── check_security_hub_status.sh  # Security Hub チェックスクリプト
├── check_guardduty_status.sh     # GuardDuty チェックスクリプト
├── check_analyzer_status.sh      # Access Analyzer チェックスクリプト
├── accounts.list                 # チェック対象アカウント一覧
└── regions.list                  # チェック対象リージョン一覧

アカウントリスト

accounts.list
123456789012
234567890123
345678901234
456789012345

リージョンリスト

regions.list
us-east-1
us-east-2
us-west-1
us-west-2
ap-south-1
ap-northeast-1
ap-northeast-2
ap-northeast-3
ap-southeast-1
ap-southeast-2
ca-central-1
eu-central-1
eu-west-1
eu-west-2
eu-west-3
eu-north-1
sa-east-1

注意事項
ファイルの改行コードは必ず LF(Unix 形式)にしてください。
Windows 環境で作成する場合、改行コードが CRLF になってしまうと、スクリプトが正常に動作しない可能性があります。

Security Hub チェックスクリプト

check_security_hub_status.sh
#!/bin/bash

# --- 設定項目 ---
PROFILE_NAME="your-profile-name"
ASSUME_ROLE_NAME="YourAssumeRoleName"
ACCOUNT_FILE="./accounts.list"
REGION_FILE="./regions.list"

# 設定ファイルの存在チェック
if [[ ! -f "$ACCOUNT_FILE" ]]; then
    echo "エラー: アカウントリストファイル '$ACCOUNT_FILE' が見つかりません。" >&2
    exit 1
fi
if [[ ! -f "$REGION_FILE" ]]; then
    echo "エラー: リージョンリストファイル '$REGION_FILE' が見つかりません。" >&2
    exit 1
fi

# ファイルからアカウント ID とリージョンを配列に読み込む
mapfile -t TARGET_ACCOUNTS < "$ACCOUNT_FILE"
mapfile -t REGIONS < "$REGION_FILE"

# SSO ログインセッションを開始/更新
echo "IAM Identity Center のログインセッションを更新します..." >&2
aws sso login --profile ${PROFILE_NAME} >&2

# CSV ヘッダーを出力
echo "AccountId,Region,SecurityHubStatus"

# 各アカウントに対してループ処理
for ACCOUNT_ID in "${TARGET_ACCOUNTS[@]}"; do
  # 空行はスキップ
  [[ -z "$ACCOUNT_ID" ]] && continue

  echo "--- Checking Account: ${ACCOUNT_ID} ---" >&2
  ROLE_ARN="arn:aws:iam::${ACCOUNT_ID}:role/${ASSUME_ROLE_NAME}"

  # IAM Identity Center のプロファイルを使って AssumeRole を実行
  TEMP_CREDS=$(aws sts assume-role \
    --role-arn ${ROLE_ARN} \
    --role-session-name "SecurityHubCheck-$(date +%s)" \
    --profile ${PROFILE_NAME} \
    --output json)

  # assume-role に失敗した場合はスキップ
  if [ $? -ne 0 ]; then
    echo "${ACCOUNT_ID},ALL,FailedToAssumeRole"
    continue
  fi

  # 一時的な認証情報を環境変数にエクスポート
  export AWS_ACCESS_KEY_ID=$(echo $TEMP_CREDS | jq -r .Credentials.AccessKeyId)
  export AWS_SECRET_ACCESS_KEY=$(echo $TEMP_CREDS | jq -r .Credentials.SecretAccessKey)
  export AWS_SESSION_TOKEN=$(echo $TEMP_CREDS | jq -r .Credentials.SessionToken)

  # 各リージョンに対してループ処理
  for REGION in "${REGIONS[@]}"; do
    # 空行はスキップ
    [[ -z "$REGION" ]] && continue

    # Security Hub のステータスを確認
    if aws securityhub describe-hub --region ${REGION} > /dev/null 2>&1; then
      STATUS="ENABLED"
    else
      STATUS="DISABLED_OR_NOT_AVAILABLE"
    fi
    echo "${ACCOUNT_ID},${REGION},${STATUS}"
  done

  # 環境変数をクリア
  unset AWS_ACCESS_KEY_ID
  unset AWS_SECRET_ACCESS_KEY
  unset AWS_SESSION_TOKEN
done

echo "--- All checks completed. ---" >&2

GuardDuty チェックスクリプト

check_guardduty_status.sh
#!/bin/bash

# --- 設定項目 ---
PROFILE_NAME="your-profile-name"
ASSUME_ROLE_NAME="YourAssumeRoleName"
ACCOUNT_FILE="./accounts.list"
REGION_FILE="./regions.list"

# --- スクリプト本体 ---
if [[ ! -f "$ACCOUNT_FILE" ]]; then
    echo "エラー: アカウントリストファイル '$ACCOUNT_FILE' が見つかりません。" >&2
    exit 1
fi
if [[ ! -f "$REGION_FILE" ]]; then
    echo "エラー: リージョンリストファイル '$REGION_FILE' が見つかりません。" >&2
    exit 1
fi

mapfile -t TARGET_ACCOUNTS < "$ACCOUNT_FILE"
mapfile -t REGIONS < "$REGION_FILE"

echo "IAM Identity Center のログインセッションを更新します..." >&2
aws sso login --profile ${PROFILE_NAME} >&2

echo "AccountId,Region,GuardDutyStatus"

for ACCOUNT_ID in "${TARGET_ACCOUNTS[@]}"; do
  [[ -z "$ACCOUNT_ID" ]] && continue
  echo "--- Checking GuardDuty on Account: ${ACCOUNT_ID} ---" >&2
  ROLE_ARN="arn:aws:iam::${ACCOUNT_ID}:role/${ASSUME_ROLE_NAME}"

  TEMP_CREDS=$(aws sts assume-role --role-arn ${ROLE_ARN} --role-session-name "GuardDutyCheck" --profile ${PROFILE_NAME} --output json)
  if [ $? -ne 0 ]; then
    echo "${ACCOUNT_ID},ALL,FailedToAssumeRole"
    continue
  fi

  export AWS_ACCESS_KEY_ID=$(echo $TEMP_CREDS | jq -r .Credentials.AccessKeyId)
  export AWS_SECRET_ACCESS_KEY=$(echo $TEMP_CREDS | jq -r .Credentials.SecretAccessKey)
  export AWS_SESSION_TOKEN=$(echo $TEMP_CREDS | jq -r .Credentials.SessionToken)

  for REGION in "${REGIONS[@]}"; do
    [[ -z "$REGION" ]] && continue
    
    # list-detectors で DetectorId のリストを取得し、その数が 0 より大きいか確認
    if aws guardduty list-detectors --region ${REGION} --output json | jq -e '.DetectorIds | length > 0' > /dev/null 2>&1; then
      STATUS="ENABLED"
    else
      STATUS="DISABLED"
    fi
    echo "${ACCOUNT_ID},${REGION},${STATUS}"
  done

  unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
done

echo "--- GuardDuty checks completed. ---" >&2

IAM Access Analyzer チェックスクリプト

check_analyzer_status.sh
#!/bin/bash

# --- 設定項目 ---
PROFILE_NAME="your-profile-name"
ASSUME_ROLE_NAME="YourAssumeRoleName"
ACCOUNT_FILE="./accounts.list"
REGION_FILE="./regions.list"

# --- スクリプト本体 ---
if [[ ! -f "$ACCOUNT_FILE" ]]; then
    echo "エラー: アカウントリストファイル '$ACCOUNT_FILE' が見つかりません。" >&2
    exit 1
fi
if [[ ! -f "$REGION_FILE" ]]; then
    echo "エラー: リージョンリストファイル '$REGION_FILE' が見つかりません。" >&2
    exit 1
fi

mapfile -t TARGET_ACCOUNTS < "$ACCOUNT_FILE"
mapfile -t REGIONS < "$REGION_FILE"

echo "IAM Identity Center のログインセッションを更新します..." >&2
aws sso login --profile ${PROFILE_NAME} >&2

echo "AccountId,Region,AccessAnalyzerStatus"

for ACCOUNT_ID in "${TARGET_ACCOUNTS[@]}"; do
  [[ -z "$ACCOUNT_ID" ]] && continue
  echo "--- Checking IAM Access Analyzer on Account: ${ACCOUNT_ID} ---" >&2
  ROLE_ARN="arn:aws:iam::${ACCOUNT_ID}:role/${ASSUME_ROLE_NAME}"

  TEMP_CREDS=$(aws sts assume-role --role-arn ${ROLE_ARN} --role-session-name "AnalyzerCheck" --profile ${PROFILE_NAME} --output json)
  if [ $? -ne 0 ]; then
    echo "${ACCOUNT_ID},ALL,FailedToAssumeRole"
    continue
  fi

  export AWS_ACCESS_KEY_ID=$(echo $TEMP_CREDS | jq -r .Credentials.AccessKeyId)
  export AWS_SECRET_ACCESS_KEY=$(echo $TEMP_CREDS | jq -r .Credentials.SecretAccessKey)
  export AWS_SESSION_TOKEN=$(echo $TEMP_CREDS | jq -r .Credentials.SessionToken)

  for REGION in "${REGIONS[@]}"; do
    [[ -z "$REGION" ]] && continue

    # list-analyzers で ACCOUNT タイプのアナライザーリストを取得し、その数が 0 より大きいか確認
    if aws accessanalyzer list-analyzers --type ACCOUNT --region ${REGION} --output json | jq -e '.analyzers | length > 0' > /dev/null 2>&1; then
      STATUS="ENABLED"
    else
      STATUS="DISABLED"
    fi
    echo "${ACCOUNT_ID},${REGION},${STATUS}"
  done

  unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
done

echo "--- IAM Access Analyzer checks completed. ---" >&2

共通変数の設定

各スクリプトでは以下の共通変数を使用しています。実行前に環境に合わせて変更してください:

# --- 設定項目 ---
PROFILE_NAME="your-profile-name"            # IAM Identity Center のプロファイル名
ASSUME_ROLE_NAME="YourAssumeRoleName"       # 各アカウントのスイッチロール名(共通のスイッチロール名を使用することを前提)
ACCOUNT_FILE="./accounts.list"              # チェック対象アカウント一覧ファイル
REGION_FILE="./regions.list"                # チェック対象リージョン一覧ファイル

変数の説明

  • PROFILE_NAME: aws configure sso で設定したプロファイル名
  • ASSUME_ROLE_NAME: 各アカウントに作成されたスイッチロール用の IAM ロール名
  • ACCOUNT_FILE: チェック対象の AWS アカウント ID を記載したファイルパス
  • REGION_FILE: チェック対象のリージョンを記載したファイルパス

実行方法

1. IAM Identity Center の設定

まず、IAM Identity Center のプロファイルを設定する必要があります:

# IAM Identity Center プロファイルの設定
aws configure sso

# 以下の情報を入力します:
 SSO session name (Recommended): my-sso
 SSO start URL [None]: https://your-domain.awsapps.com/start
 SSO region [None]: ap-northeast-1
 SSO registration scopes [sso:account:access]: [Enter]
 
# 次に、使用するアカウントとロールを選択:
# There are X AWS accounts available to you.
# Using the account ID 123456789012
# The only role available to you is: PowerUserAccess
# Using the role name "PowerUserAccess"
 CLI default client Region [None]: [Enter]
 CLI default output format [None]: [Enter]
 CLI profile name [PowerUserAccess-123456789012]: your-profile-name

# 設定確認
aws configure list-profiles

# プロファイルでのログインテスト
aws sso login --profile your-profile-name

必要な設定項目

  • SSO start URL: IAM Identity Center のアクセスポータル URL
  • SSO region: IAM Identity Center が有効化されているリージョン
  • プロファイル名: スクリプト内の PROFILE_NAME と一致させる(例:your-profile-name

2. スクリプトの準備

# 実行権限を付与
chmod +x check_security_hub_status.sh check_guardduty_status.sh check_analyzer_status.sh

# 設定ファイルの編集(必要に応じて)
vi accounts.list  # チェック対象アカウントを記載
vi regions.list   # チェック対象リージョンを記載

# 各スクリプトの変数の編集(必要に応じて)
vi check_security_hub_status.sh
vi check_guardduty_status.sh
vi check_analyzer_status.sh

3. スクリプトの実行

# Security Hub の状況確認
./check_security_hub_status.sh > security_hub_status.csv

# GuardDuty の状況確認
./check_guardduty_status.sh > guardduty_status.csv

# IAM Access Analyzer の状況確認
./check_analyzer_status.sh > analyzer_status.csv

出力例

各スクリプトを実行すると、以下のような CSV 形式で結果が出力されます:

Security Hub の出力例

AccountId,Region,SecurityHubStatus
123456789012,us-east-1,ENABLED
123456789012,us-east-2,DISABLED_OR_NOT_AVAILABLE
123456789012,ap-northeast-1,ENABLED
123456789012,ap-northeast-2,ENABLED

GuardDuty の出力例

AccountId,Region,GuardDutyStatus
123456789012,us-east-1,ENABLED
123456789012,us-east-2,ENABLED
123456789012,ap-northeast-1,ENABLED
123456789012,ap-northeast-2,DISABLED

IAM Access Analyzer の出力例

AccountId,Region,AccessAnalyzerStatus
123456789012,us-east-1,ENABLED
123456789012,us-east-2,DISABLED
123456789012,ap-northeast-1,ENABLED
123456789012,ap-northeast-2,DISABLED

出力結果の見方

  • AccountId: チェック対象の AWS アカウント ID
  • Region: チェック対象のリージョン
  • 各サービスの Status: 各セキュリティサービスの状態
    • ENABLED: サービスが有効化されている
    • DISABLED / DISABLED_OR_NOT_AVAILABLE: サービスが無効またはサポートされていない
    • FailedToAssumeRole: スイッチロールに失敗(権限不足など)

制約事項

IAM Identity Center の制約

  • セッション有効期限: IAM Identity Center のセッションには有効期限があるため、長時間の実行時は再認証が必要
  • プロファイル設定: 事前に aws configure sso でプロファイルの設定が必要

スイッチロール の制約

  • ロール権限: 各アカウントに適切なスイッチロール用のロールが作成されている必要がある
  • 信頼関係: IAM Identity Center のアカウントからのスイッチロールが許可されている必要がある

おわりに

今回は、IAM Identity Center を使用して複数 AWS アカウントの Security Hub 有効化状況をチェックするスクリプトを作成しました。

複数アカウント環境でのセキュリティサービスのチェックにぜひご活用ください。

この記事がどなたかの役に立つと嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?