はじめに
AWSが提供しているAWS Security Hubの一括設定ツールを試したのでそのメモです。
なんでこのツールを利用したかと言うと、AWS Security Hubはリージョン単位のサービスのためリージョンごとの設定が必要で、かつマルチアカウント構成の場合アカウント毎の設定になるので、作業量が「対象AWSアカウント数 x 対象リージョン数」となり手動でのセットアップは骨が折れるので、楽をしたいと言うのが発端です。
ツール
AWS Security Hubのマルチアカウント一括設定ツール
github.com
上記ツールですが、下記のマネコンAWS Security Hubの「設定」で出る「GitHubでスクリプトを実行します」のリンク先のスクリプトになります。
構成環境
作成するAWS Security Hub構成
マルチアカウントのベストプラクティスである Landing Zoneにならい、下記アカウントがあるマルチアカウント構成を前提とします。
- 支払いアカウント(OrganizationsのMaster Account)
- メンバーアカウント
- 監査アカウント
- ログアカウント(CloudTrailのログなどを集中的に保管管理するアカウント)
- 複数のリソースアカウント(VPCやEC2をデプロイする環境)
AWS Security Hubは、監査アカウントをMasterアカウントとして、他のアカウントはメンバーアカウントとして招待し作成したHubに所属させます。
準備: IAMロールの作成
全アカウントにツールを実行するためのIAMロールを作成します。
Gitに含まれるCloudFormation(EnableSecurityHub.yaml)で、IAMロールを作成することもできますが、ここではCLIで作成しています。
事前準備
PROFILE=<auditアカウントのIAM管理可能なプロファイル>
監査アカウントのインスタンスIAMロール
スクリプトを実行するEC2にアタッチするインスタンスロールを作成します。
ASSUMEROLE_POLICY='{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' ROLE_POLICY='{ "Version": "2012-10-17", "Statement": [ { "Sid": "AssumeToManageSecurityHubRoleOfMemberAccounts", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::*:role/ManageSecurityHubRole" } ] }' #IAMロールの作成 aws --profile ${PROFILE} \ iam create-role \ --role-name "ManageSecurityHubInstanceRole" \ --assume-role-policy-document "${ASSUMEROLE_POLICY}" \ --max-session-duration 3600 #インラインポリシーのアタッチ aws --profile ${PROFILE} \ iam put-role-policy \ --role-name "ManageSecurityHubInstanceRole" \ --policy-name "ManageSecurityHubPolicy" \ --policy-document "${ROLE_POLICY}" #インスタンスプロファイルの作成 aws --profile ${PROFILE} \ iam create-instance-profile \ --instance-profile-name "ManageSecurityHubInstanceRole"; aws --profile ${PROFILE} \ iam add-role-to-instance-profile \ --instance-profile-name "ManageSecurityHubInstanceRole" \ --role-name "ManageSecurityHubInstanceRole" ; #IAMロールのARN取得 ARN_ManageSecurityHubInstanceRole=$( aws --profile ${PROFILE} --output text \ iam get-role --role-name "ManageSecurityHubInstanceRole" \ --query 'Role.Arn' ) echo ${ARN_ManageSecurityHubInstanceRole}
Security Hub管理用のIAMロール
各アカウントに、Security Hub管理用のIAMロールを作成します。
このIAMロールは、先に作成した「監査アカウントのインスタンスIAMロール」と信頼関係を結びます。
#一連の設定をSecurity Hubを利用する全AWSアカウントに設定します。 PROFILE=<対象のAWSアカウントのIAM管理者のプロファイル> ASSUMEROLE_POLICY='{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": [ "'"${ARN_ManageSecurityHubInstanceRole}"'" ] }, "Action": "sts:AssumeRole" } ] }' ROLE_POLICY='{ "Version": "2012-10-17", "Statement": [ { "Condition": { "StringLike": { "iam:AWSServiceName": [ "securityhub.amazonaws.com", "config.amazonaws.com" ] } }, "Action": "iam:CreateServiceLinkedRole", "Resource": "*", "Effect": "Allow" }, { "Action": "securityhub:*", "Resource": "*", "Effect": "Allow" }, { "Action": [ "config:DescribeConfigurationRecorders", "config:DescribeDeliveryChannels", "config:DescribeConfigurationRecorderStatus", "config:DeleteConfigurationRecorder", "config:DeleteDeliveryChannel", "config:PutConfigurationRecorder", "config:PutDeliveryChannel", "config:StartConfigurationRecorder" ], "Resource": "*", "Effect": "Allow" }, { "Action": "iam:PassRole", "Resource": "arn:aws:iam::*:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", "Effect": "Allow" }, { "Action": [ "s3:CreateBucket", "s3:PutBucketPolicy", "s3:ListBucket" ], "Resource": "arn:aws:s3:::config-bucket-*", "Effect": "Allow" } ] }' #IAMロールの作成 aws --profile ${PROFILE} \ iam create-role \ --role-name "ManageSecurityHubRole" \ --assume-role-policy-document "${ASSUMEROLE_POLICY}" \ --max-session-duration 3600 #インラインポリシーのアタッチ aws --profile ${PROFILE} \ iam put-role-policy \ --role-name "ManageSecurityHubRole" \ --policy-name "ManageSecurityHubPolicy" \ --policy-document "${ROLE_POLICY}"
スクリプト実行環境作成
auditアカウントに、スクリプト実行用のEC2環境を準備します。
プロファイル準備
PROFILE=<auditアカウントのEC2管理可能なプロファイル>
インスタンスの起動
#起動パラメータ設定(環境に合わせて変更するもの) KEYNAME="CHANGE_KEY_PAIR_NAME" #環境に合わせてキーペア名を設定してください。 SUBNETID=subnet-f59858bd #"パブリックサブネットのIDを設定" SG_ID=sg-071417e793b795090 #"SSHログインできるセキュリティーグループのIDを設定" #起動パラメータ設定(固定設定) INSTANCE_TYPE="t2.micro" AL2_AMIID=$(aws --profile ${PROFILE} --output text \ ec2 describe-images \ --owners amazon \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2' \ 'Name=state,Values=available' \ --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ; #タグ設定 TAGJSON=' [ { "ResourceType": "instance", "Tags": [ { "Key": "Name", "Value": "SecurityHubMgr" } ] } ]' #ユーザデータ設定 USER_DATA=' #!/bin/bash -xe #RPM最新化&ホスト名設定 yum -y update hostnamectl set-hostname SecurityHubMgr #パッケージインストール yum -y install python2-pip python2 git #boto3インストール sudo pip install boto3 #AWS CLIアップデート curl -o "get-pip.py" "https://bootstrap.pypa.io/get-pip.py" python get-pip.py pip install --upgrade # ec2-userのAWS CLI初期設定 Region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//') sudo -u ec2-user aws configure set region ${Region} sudo -u ec2-user aws configure set output json #スクリプトのセットアップ cd /home/ec2-user sudo -u ec2-user git clone https://github.com/awslabs/aws-securityhub-multiaccount-scripts.git ' #インスタンスの起動 aws --profile ${PROFILE} \ ec2 run-instances \ --image-id ${AL2_AMIID} \ --instance-type ${INSTANCE_TYPE} \ --key-name ${KEYNAME} \ --subnet-id ${SUBNETID} \ --security-group-ids ${SG_ID} \ --associate-public-ip-address \ --iam-instance-profile "Name=ManageSecurityHubInstanceRole" \ --tag-specifications "${TAGJSON}" \ --user-data "${USER_DATA}" \ --monitoring Enabled=true ;
スクリプトによるSecurityHubの有効化
Security Hub管理インスタンスへのログイン
MgrIP=$(aws --profile ${PROFILE} --output text \ ec2 describe-instances \ --filters "Name=tag:Name,Values=SecurityHubMgr" "Name=instance-state-name,Values=running" \ --query 'Reservations[*].Instances[*].PublicIpAddress' ) ssh ec2-user@${MgrIP}
SecurityHubのメンバーアカウント一覧(CSV)作成
Security Hubの有効化し、SecurityHubのMasterAccount(ここではauditアカウント)の配下のメンバーとなるAWSアカウントの一覧をCSV形式で作成します。1行1アカウントで、"AccountId,EmailAddress"形式で作成します。
CSVファイルの作成例(securityhub_account_list.csv)
111111111111,master@mail_address 222222222222,logging@mail_address 333333333333,resource1@mail_address 444444444444,resource2@mail_address
有効化対象リージョンの設定
スクリプトのデフォルトではSecurityHubが利用可能な全てのリージョンで有効化をしようとします。しかし、最近開設されたリージョンは、デフォルトではリージョン自身が無効化されており、そのまま実行するとスクリプトがエラーとなります。そのため、SecurityHubを有効化するリージョンを明示的に指定する必要があります。
Security Hubが利用可能なリージョン一覧の確認
CLIではコマンドがないので、boto3を利用しpythonのワンライナーでSecurityHubが利用可能なリージョン一覧を取得します。
python -c "import boto3,json; print('{}'.format( json.dumps( boto3.session.Session().get_available_regions('securityhub') ) ) );"
有効化対象リージョン一覧作成
上記で取得した一覧情報から、有効化対象のリージョンを抽出し、カンマ区切りの文字列にします。
- 変更点
- デフォルトで無効化されているリージョンを削除。
- ap-east-1(香港リージョン)
- me-south-1(中東バーレーン)
- カンマカンマ
- デフォルトで無効化されているリージョンを削除。
ENABLE_REGIONS="ap-northeast-1,ap-northeast-2,ap-south-1,ap-southeast-1,ap-southeast-2,ca-central-1,eu-central-1,eu-north-1,eu-west-1,eu-west-2,eu-west-3,sa-east-1,us-east-1,us-east-2,us-west-1,us-west-2"
Security Hubの有効化
enablesecurityhub.pyスクリプトを利用し、対象アカウントの対象リージョンのSecurity Hub有効化を行います。
# Security Hubのマスターアカウントとして監査アカウントを指定 MASTER_ACCOUNT=$(aws sts get-caller-identity --output text --query 'Account') #その他設定 ASSUME_ROLE="ManageSecurityHubRole" CSV_FILE_NAME="securityhub_account_list.csv" #実行 python2 ./aws-securityhub-multiaccount-scripts/enablesecurityhub.py \ --master_account ${MASTER_ACCOUNT} \ --assume_role ${ASSUME_ROLE} \ --enabled_regions ${ENABLE_REGIONS} \ ${CSV_FILE_NAME} ;
下記のようにスクリプトでのAWS Config有効化に失敗したAWSアカウント/リージョンがある場合、マネージメントコンソールのAWS Configで手動でConfigの有効化をしてから、enablesecurityhub.pyを再実行してください。
スクリプトによるSecurityHubの無効化
SecurityHubの無効化です。
MASTER_ACCOUNT=$(aws sts get-caller-identity --output text --query 'Account') ENABLE_REGIONS="ap-northeast-1,ap-northeast-2,ap-south-1,ap-southeast-1,ap-southeast-2,ca-central-1,eu-central-1,eu-north-1,eu-west-1,eu-west-2,eu-west-3,sa-east-1,us-east-1,us-east-2,us-west-1,us-west-2" #無効化実行 python2 ./aws-securityhub-multiaccount-scripts/disablesecurityhub.py \ --master_account ${MASTER_ACCOUNT} \ --assume_role ${ASSUME_ROLE} \ --enabled_regions ${ENABLE_REGIONS} \ ${CSV_FILE_NAME} ;