【AWS Security Hub】セキュリティグループの自動修復

# 目的
**AWS セキュリティグループでRDP/SSHの無制限公開のルールを検出し、自動削除する**
- **`AWS Security Hub`** で非準拠のセキュリティグループのルールを検出する
    - RDP/SSHポートのインバウンド通信の無制限許可を検出 (リスクの高いTCPポート)
- **`EventBrigde`** ＋ **`Systems Manager(SSM) オートメーション`** でルールを自動削除する
    - 修復は `SSM ドキュメント`で設定

:::note info
**`Security Hub`** を有効にすると`AWS Config`にルールが作成されるが、Configの修復アクションでは自動化アクションを設定できないため **`EventBridge`** を使う
:::

参考）AWS Configによる非準拠の検出と自動修復、カスタマイズ方法の詳細は下記を参照

https://qiita.com/maru3ka9/items/a7044543092770be7057

# 概要
## Security Hubを使った非準拠ルールの検出と自動修復
* 非準拠ルールの検出は、`Security Hub`を有効化することで自動的に設定される
* <font color="green">非準拠ルールを自動修復したい場合、個別対応が必要</font> (本記事で説明)

### 仕組み
* `EventBridge`ルールで `Security Hub` のイベントを検出し、`SSMオートメーション` を実行することで、セキュリティグループのルールを自動修復する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/50aabd5c-7a0d-e071-8d84-3afea9822160.png)

### 実装の特徴
  - **コーディング不要**
  - `EventBridge`でイベントを検出して実行するパターン（応用しやすい）
  - `SSMオートメーション ドキュメント`で修復（AWS標準ベース、カスタマイズも対応）
  - ついでに通知やロギングも対応（非準拠検出時の通知、原因調査でも使える）
  - リージョン単位で設定が必要（単一AWSアカウント / 単一リージョンのみ対応）
  
### 留意事項
:::note warn
**<font color="red">必ず `リソースが設定されていない未使用状態`のセキュリティグループで検証すること</font>**
本記事の正確性や安全性、発生した不都合や損害等について、著者や所属組織は一切の責任を負いません
:::

## 前提条件 (事前準備)
- **Security Hub** を有効化
- **AWS基礎セキュリティのベストプラクティス v1.0.0** を有効化
  - リスクの高いTCPポートの無制限許可を検出できる
    - **EC2.19** Security groups should not allow unrestricted access to ports with high risk
    <font color="gray">(20,21,**`22`**,23,25,110,135,143,445,1433,1434,3000,3306,**`3389`**,4333,5000,5432,5500,5601,8080,8088,8888)</font>
- **SSMドキュメント** 
    - AWS標準のSSMドキュメント `AWS-DisablePublicAccessForSecurityGroup`[^1]を活用
      - カスタマイズ版を使う場合: `Custom-AWS-DisablePublicAccessForSecurityGroup`[^2] を用意しておく (リージョン単位で作成が必要)

:::note warn
AWS標準のSSMドキュメントでは、`すべてのTCP`／`すべてのトラフィック`のルールは削除できない。→ [修復のカスタマイズ方法（SSMドキュメント）](https://qiita.com/maru3ka9/items/a7044543092770be7057#5-%E4%BF%AE%E5%BE%A9%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E6%96%B9%E6%B3%95ssm%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88)で対応可能。
自動削除される条件は、SSMドキュメントの対応範囲のみ。検出と修復で条件が異なるため、検出しても該当のルールが削除されるとは限らないので注意。
:::

# 設定手順
EventBridgeのルール名: `SecurityHub-AutoRemediate-EC2.19` の設定例です。
（AWSアカウントID: `123456789012`、リージョン: `ap-northeast-1 / 東京`）

- [1. IAMポリシーとロールの設定](#1-iamポリシーとロールの設定)
- [2. EventBridgeの設定](#2-eventbridgeの設定)
- [3. 動作確認](#3-動作確認)

## 1. IAMポリシーとロールの設定
セキュリティグループのインバウンドルール削除とSSMオートメーションの実行を許可するポリシーとロールを作成する。

例) IAMポリシー: `Amazon_EventBridge_SecurityHub-AutoRemediate-EC2.19`
- SSMオートメーションの実行許可: `AWS-DisablePublicAccessForSecurityGroup`[^1], `Custom-AWS-DisablePublicAccessForSecurityGroup` [^2]
- セキュリティグループのインバンドルールの削除許可 `ec2:RevokeSecurityGroupIngress` [^4]
```json:IAMポリシー: Amazon_EventBridge_SecurityHub-AutoRemediate-EC2.19
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowStartAutomationExecution",
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:*:automation-definition/AWS-DisablePublicAccessForSecurityGroup:*",
                "arn:aws:ssm:*:*:automation-definition/Custom-AWS-DisablePublicAccessForSecurityGroup:*"
            ]
        },
        {
            "Sid": "AllowRevokeSecurityGroupIngress",
            "Effect": "Allow",
            "Action": "ec2:RevokeSecurityGroupIngress",
            "Resource": "*"
        }
    ]
}
```
例) IAMロール: `Amazon_EventBridge_SecurityHub-AutoRemediate-EC2.19`
   -  信頼されたエンティティ: カスタム信頼ポリシー (JSON)
```json:IAMロールのカスタム信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "TrustEventBridgeService",
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```
- 許可ポリシー: `Amazon_EventBridge_SecurityHub-AutoRemediate-EC2.19` を設定

## 2. EventBridgeの設定
- **Amazon EventBridge > ルール > ルールを作成:**
   - 名前(例): `SecurityHub-AutoRemediate-EC2.19`
   - イベントバス: `default`
   - ルールタイプ: `イベントパターンを持つルール`
   - イベントソース: `AWS イベントまたは EventBridge パートナーイベント`
- **イベントパターン**: (JSON)
   - `ProductArn`: 東京リージョンに限定する場合、`arn:aws:securityhub:ap-northeast-1::product/aws/securityhub` を指定 (本手順では東京リージョンの検知/修復に限定)
   - `GeneratorId`に検出対象のIDを指定する。`EC2.19`の場合、`security-control/EC2.19`, `aws-foundational-security-best-practices/v/1.0.0/EC2.19` を指定
    ```json:イベントパターンの設定例 (Security Hub / EC2.19)
    {
      "source": ["aws.securityhub"],
      "detail-type": ["Security Hub Findings - Imported"],
      "detail": {
        "findings": {
          "Compliance": {
            "Status": ["FAILED"]
          },
          "ProductArn": ["arn:aws:securityhub:ap-northeast-1::product/aws/securityhub"],
          "RecordState": ["ACTIVE"],
          "Workflow": {
            "Status": ["NEW"]
          },
          "GeneratorId": [
            "security-control/EC2.19",
            "aws-foundational-security-best-practices/v/1.0.0/EC2.19"
          ]
        }
      }
    }
    ```

- **ターゲットの設定**: 自動修復する場合、SSMオートメーションを実行する
  - **ターゲットタイプ**: `AWS のサービス`
  - **ターゲットを選択**: `Systems Manager オートメーション`
  - **ドキュメントを選択**: `AWS-DisablePublicAccessForSecurityGroup` [^1] または `Custom-AWS-DisablePublicAccessForSecurityGroup` [^2]
  - **自動化パラメータを設定**: `入力トランスフォーマー` [^3]
  - **入力パス**: 非準拠ルールで検出された `セキュリティグループID` を `GroupId` の値にセットしてテンプレートに渡す
    ```text:入力パス
     {"GroupId": "$.detail.findings[0].Resources[0].Details.AwsEc2SecurityGroup.GroupId"}
    ```
  - **テンプレート**: SSMドキュメントのパラメータをJSON形式で設定
    ```text:テンプレート
    {"GroupId": [<GroupId>]}
    ```
    
    - GroupId: セキュリティグループのID (必須): **`[<GroupId>]`** で指定
  - **EventBridgeのロール**: [`Amazon_EventBridge_SecurityHub-AutoRemediate-EC2.19`](#1-iamポリシーとロールの設定) を選択

## 3. 動作確認
- **<font color="red">必ず `リソースが設定されていない未使用状態`のセキュリティグループで検証すること</font>**
- セキュリティグループのインバウンドルールに タイプ:`RDP`、`SSH`、ソース: `0.0.0.0/0` のルールを追加し、数分後にルールが自動削除されることを確認する

- EventBridgeのルールのモニタリングで実行されたか確認
  - ターゲットを追加し `CloudWatch Logs`へ出力したり、`SNS`で通知するとよい (非準拠の検出の履歴を残す、原因調査などで必要）
- オートメーションが実行されているかは `AWS Systems Manager > Automation` の `Executions` や`CloudTrail` で実行履歴を確認する

# 補足情報
### 参考1. 代替手段：AWSでの自動化されたセキュリティ対応 (CloudFormation)

https://aws.amazon.com/jp/solutions/implementations/automated-security-response-on-aws/

https://aws.amazon.com/jp/builders-flash/202409/automated-security-response-on-aws/

- 多くの自動修復が用意されている＋CloudFormationで導入できる
- <font color="green">**マルチアカウント・マルチリージョン環境に対応**</font>
- セキュリティグループの非準拠ルールの自動修復について：
  - `すべてのTCP`、`すべてのトラフィック`の条件には対応していない
  - カスタマイズで対応する場合、CDK利用など難易度が高いかも

### 参考2. Security Hub：セキュリティグループ関連のコントロール
CIS AWS Foundations Benchmark でも RDP/SSH の無制限許可を検出ができる
ただし、バージョンによって検出や設定方法が異なるため注意

- **CIS AWS Foundations Benchmark v1.2.0**
  - `SSH`と`RDP`の無制限許可を検出 ([restricted-ssh](https://docs.aws.amazon.com/config/latest/developerguide/restricted-ssh.html)、[restricted-common-ports](https://docs.aws.amazon.com/config/latest/developerguide/restricted-common-ports.html))
    - **[EC2.13]** Security groups should not allow ingress from 0.0.0.0/0 to port 22 [[修復]](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-13)
    - **[EC2.14]** Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 [[修復]](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-14)

- **CIS AWS Foundations Benchmark v3.0.0**
  - `SSH`と`RDP`の無制限許可を検出 ([vpc-sg-port-restriction-check](https://docs.aws.amazon.com/config/latest/developerguide/vpc-sg-port-restriction-check.html))
    - **[EC2.53]** EC2 security groups should not allow ingress from 0.0.0.0/0 to remote server administration ports [[修復]](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-53)
    
- 参考）`CIS AWS Foundations Benchmark v1.4.0` では、セキュリティグループのRDP/SSHの検出は未対応

[^1]:AWS Systems Manager Automation runbook reference > ユーザーガイド > [AWS-DisablePublicAccessForSecurityGroup](https://docs.aws.amazon.com/ja_jp/systems-manager-automation-runbooks/latest/userguide/automation-aws-disablepublicaccessforsecuritygroup.html)

[^2]:SSMドキュメントをカスタマイズする場合： [修復のカスタマイズ方法（SSMドキュメント）](https://qiita.com/maru3ka9/items/a7044543092770be7057#5-%E4%BF%AE%E5%BE%A9%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E6%96%B9%E6%B3%95ssm%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88)を参照

[^3]:入力トランスフォーマー EventBridgeからオートメーションを実行するときのパラメータの受け渡し方法: [入力トランスフォーマーを使用したオートメーションへのデータの受け渡し](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-tutorial-eventbridge-input-transformers.html)

[^4]:セキュリティグループのインバウンドルールを削除する権限を付与する [3-2-1. 事前準備：IAMポリシーとロールの作成](https://qiita.com/maru3ka9/items/a7044543092770be7057#3-2-1-%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99iam%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%A8%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90)