Security Hubで不要なコントロールを無効化するとき、リージョンごとに無効化します。 手間だったので、Pythonでスクリプトを作ってみました。
おすすめの方
- Security Hubのコントロールを全リージョンで無効化したい方
Security Hubのコントロールを無効化する
無効化したいコントロールのARNを取得する
下記を参考にして、無効にしたいコントロールのStandardsControlArn
を取得します。
なお、有効にしている「セキュリティ基準」が複数ある場合は、それぞれのStandardsControlArn
を取得します。
見た目が同じコントロールであっても、セキュリティ基準ごとにStandardsControlArn
が異なります。
(検出結果.jsonを確認しました)
{
"StandardsControlArn": "arn:aws:securityhub:us-west-2:123456789012:control/aws-foundational-security-best-practices/v/1.0.0/IAM.6"
}
{
"StandardsControlArn": "arn:aws:securityhub:us-west-2:123456789012:control/cis-aws-foundations-benchmark/v/1.2.0/1.14"
}
コントロールを無効化するスクリプト(Python)
下記を最初に記載していますが、人間のわかり易さのために記載している項目もあります。
- StandardsControlArn
- ControlId
- Title
- Reason
- AfterStatus
最小限にするなら、StandardsControlArn
だけで十分です。
この場合は、Pythonスクリプトの内容を適宜変更してください。
また、StandardsControlArn
の「AWSアカウントID」や「リージョン」が異なっても、実行時に目的の値に置換するようにしています。
そのため、AWSアカウント毎やリージョン毎にARNを用意する必要はありません。使い回せます。
app.py
import copy
import re
import sys
import time
import boto3
import botocore
DEFAULT_FIX_REGION_NAME = 'ap-northeast-1'
DEFAULT_FIX_AWS_ACCOUNT_ID = '123456789012'
# ここに書く
# 下記の「AWSアカウントID」や「リージョン」が異なっても、実行時に上記の内容で検索して、目的の値に置換します
TARGET_CONTROLS = [
{
"StandardsControlArn": "arn:aws:securityhub:ap-northeast-1:123456789012:control/aws-foundational-security-best-practices/v/1.0.0/IAM.6",
"ControlId": "IAM.6",
"Title": "Hardware MFA should be enabled for the root user",
"Reason": "(理由の参考)rootアカウントは、ソフトウェアMFAで管理しています。",
"AfterStatus": "DISABLED",
},
{
"StandardsControlArn": "arn:aws:securityhub:ap-northeast-1:123456789012:control/cis-aws-foundations-benchmark/v/1.2.0/1.14",
"ControlId": "CIS.1.14",
"Title": "Ensure hardware MFA is enabled for the root user",
"Reason": "(理由の参考)rootアカウントは、ソフトウェアMFAで管理しています。",
"AfterStatus": "DISABLED",
},
]
ec2 = boto3.client('ec2')
def main(aws_account_id):
print('############################################')
print(f'AWS ACCOUNT ID: {aws_account_id}')
print('')
update_all_region(aws_account_id)
def update_all_region(aws_account_id: str):
print('====================')
regions = ec2.describe_regions()['Regions']
for region in regions:
region_name = region['RegionName']
print(region_name)
print('')
update(aws_account_id, region_name)
print('')
print('')
def update(aws_account_id: str, region_name: str):
securityhub = boto3.client('securityhub', region_name=region_name)
for target in TARGET_CONTROLS:
print('----------')
# AWSアカウントID と リージョン をすり替える
tmp = copy.deepcopy(target)
tmp['StandardsControlArn'] = re.sub(DEFAULT_FIX_REGION_NAME, region_name, tmp['StandardsControlArn'])
tmp['StandardsControlArn'] = re.sub(DEFAULT_FIX_AWS_ACCOUNT_ID, aws_account_id, tmp['StandardsControlArn'])
print(tmp)
update_control(
securityhub,
tmp['StandardsControlArn'],
tmp['AfterStatus'],
tmp['Reason'],
)
print('')
time.sleep(0.1)
def update_control(securityhub, standards_control_arn: str, status: str, reason: str):
try:
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/securityhub/client/update_standards_control.html
securityhub.update_standards_control(
StandardsControlArn=standards_control_arn,
ControlStatus=status,
DisabledReason=reason,
)
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == 'ResourceNotFoundException':
# データなしのコントロールは、存在しない扱いのため、本APIが失敗する。
# そのため、例外キャッチして無視する
print(e)
else:
raise
if __name__=='__main__':
if len(sys.argv) != 2:
print('[usage] python app.py 123456789012')
exit()
aws_account_id = sys.argv[1]
main(aws_account_id)
スクリプトを実行する
python app.py 123456789012
コントロールが無効になったことを確認する
見た目が反映されたり、既存の結果がアーカイブされるまで、数日の猶予があります。焦らないでください。
コントロールの確認画面を表示すれば、無効になったことを確認できます。
コントロール画面
セキュリティ基準画面
無効なコントロールを取得するコマンド
次のコマンドでも確認できます。
$ aws securityhub describe-standards-controls \
--standards-subscription-arn "arn:aws:securityhub:ap-northeast-1:123456789012:subscription/aws-foundational-security-best-practices/v/1.0.0" \
--query 'Controls[?ControlStatus==`DISABLED`]'
standards-subscription-arn
の値は、下記を参考に適宜変更してください。
さいごに
Security Hubのコントロールを無効化してみました。 AWSアカウント毎、リージョン毎に変更する手間が少しでも楽になれば幸いです。