【Security Hub入門】フルオープンされたセキュリティグループをカスタムアクションで削除する

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。

2019年6月24日に AWS Security Hub の一般提供を開始 というアナウンスされました。
私も非常に注目しているサービスです。

Security Hub の検出結果から AWS セキュリティサービスや
3rd-party のプロダクトが検出した問題や失敗してコンプライアンスチェックを確認可能です。

今回は、検出結果からカスタムアクションを呼び出し
コンプライアンスチェック失敗に対するリカバリーを試してみます。

セキュリティグループルールを削除

CIS AWS Foundation 4.2 どのセキュリティグループも 0.0.0.0/0 からポート 3389 への侵入を許可していないことを確認する を検出して
ポート 3389 (RDP) をフルオープンしているセキュリティグループルールを削除する手順を構築します。

この手順の良いところは以下だと考えています。

  1. 不穏な設定変更を検知可能
  2. オペレーターにセキュリティグループを変更する権限を与えなくて済む

特に2点目は効果が大きいと思います。
オペレーターに Security Hub のカスタムアクションを許可する権限を付けておけば
不穏なセキュリティグループルールを削除することが可能になります。

セキュリティグループに対する権限を与えなくて済みますし
そもそも Security Hub が検出したセキュリティグループルールしか変更できません。

実装

さっそく実装していきます。

SNS トピック作成

マネジメントコンソールで トピック を開きます。

トピックの作成 をクリックします。

任意の名前でトピックを作成します。
例として「cis42-rdp-opend」という名前を付けています。

IAM ポリシーの作成

セキュリティグループルールを削除するためのポリシーを作成します。
ポリシー を開きます。

ポリシーの作成 をクリックします。

以下の json をコピペしてポリシーを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "*"
        }
    ]
}

Lambda 関数作成

関数 を開きます。

関数の作成 をクリックします。

設計図の使用 を選択します。
sns-message-python を検索して選択してから 設定をクリックします。

次の画面では以下の情報を入力し関数の作成をクリックします。

項目
関数名 任意
実行ロール 基本的な Lambda アクセス権限で新しいロールを作成
SNS トピック 前の手順で作成したトピックを指定
トリガーの有効化 チェックを入れる

関数コード

関数コードは以下をコピペしてください。
ランタイムは Python 3.6 を指定します。

import json
import boto3
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    #print(message)

    sgId = message['detail']['findings'][0]['Resources'][0]['Details']['Other']['groupId']

    ec2 = boto3.client('ec2')

    try:
        response = ec2.revoke_security_group_ingress(
            CidrIp = '0.0.0.0/0',
            GroupId = sgId,
            FromPort = 3389,
            ToPort = 3389,
            IpProtocol = 'tcp'
        )

    except ClientError as e:
        print(e)

実行ロールにポリシーをアタッチ

実行ロールという項目に IAM コンソールへのリンクが表示されています。
そちらをクリックします。

IAM ロールが表示されたら ポリシーをアタッチします をクリックします。

前の手順で作成した IAM ポリシーをアタッチします。

カスタムアクション作成

Security Hub のカスタムアクションを作成します。
カスタムアクション を開きます。

カスタムアクションを作成する をクリックします。

設定情報を入力して カスタムアクションを作成する をクリックします。

項目
アクション名 任意
説明 わかりやすい説明を入力
カスタムアクション ID 後ほど CloudWatch Event で指定する ARN になります。

作成した カスタムアクション ARN をメモしておきます。

CloudWatch Events ルールの作成

もう少しで終わります。
CloudWatch Events を開きます。

ルールの作成 をクリックします。

イベントソース

カスタムイベントパターンの構築 を選択し、以下の json をコピペします。
"your-customaction-arn" の部分は前の手順でメモしたカスタムアクション ARN を入力します。

{
  "source": [
    "aws.securityhub"
  ],
  "detail-type": [
    "Security Hub Findings - Custom Action"
  ],
  "resources": [
    "your-customaction-arn"
  ]
}

ターゲット

前の手順で作成した SNS トピックを指定します。

テスト

テスト用セキュリティグループの作成

テスト用にポート 3389を 0.0.0.0/0 に公開したセキュリティグループを作成します。

※※※※※※※※※※※※※※※※※※※※※※※※※
※テスト用アカウントでお試しください
※本番用アカウントでは絶対に試さないでください
※このセキュリティグループを EC2 に紐付けないでください
※※※※※※※※※※※※※※※※※※※※※※※※※

カスタムアクション実行

しばらくすると Security Hub でルール違反が検出されます。

上図にあるようにリソースタイプが AwsEc2SecurityGroup である列にチェックを入れ
アクション から 前の手順で作成したカスタムアクション をクリックします。

確認

テスト用のセキュリティグループを表示します。
すでに表示している場合はブラウザを更新(F5)します。

ポート 3389を 0.0.0.0/0 に公開したセキュリティグループルールが消えています。

まとめ

セキュリティオートメーションとまでは実現出来ませんが
オペレーターに作業移管をして運用負荷を下げることは実現出来そうです。

原則としてセキュリティグループを変更可能な権限を与えないこと、
AWS 設定変更はコード化する、などの方針がまずは必要ですが、
Security Hub を活用することでより強固なシステム運用が可能になるのではないでしょうか。

Security Hub のこれからに期待です。

参考

Standards Supported in AWS Security Hub: CIS AWS Foundations
Automating AWS Security Hub with CloudWatch Events

以上、吉井 亮 がお届けしました。