AWSセキュリティグループの自動修復とカスタマイズ対応 (AWS Config＋SSMドキュメント)

# はじめに
AWSのセキュリティグループの設定不備対策として、AWS Configを使って検出・自動修復する方法と、修復できない条件（すべてのトラフィック、すべてのTCP）について、SSMドキュメントのカスタマイズで対応する方法をご紹介します。

# 目次
1. [背景](#1-背景)
1. [概要: AWS Configを使った検出と自動修復](#2-概要-aws-configを使った検出と自動修復)
1. [AWSで用意されている検出と修復の設定方法](#3-awsで用意されている検出と修復の設定方法)
1. [標準の修復アクションでは対応できないケース](#4-標準の修復アクションでは対応できないケース)
1. [修復のカスタマイズ方法（SSMドキュメント）](#5-修復のカスタマイズ方法ssmドキュメント)
1. [まとめ](#6-まとめ)
1. [補足1. AWS Security Hub利用時](#補足1-aws-security-hub利用時)
1. [補足2. AWS Control Tower利用時](#補足2-aws-control-tower利用時)

# 1. 背景
インターネットから通信できるようなシステム構成で、セキュリティグループの設定をミスってしまい、第三者に乗っ取られるケースがあります。
社会問題になっており、クラウド設定不備防止のガイドラインも出てきました。

引用 [クラウドサービス利用・提供における適切な設定のためのガイドライン 総務省 2022/10](https://www.soumu.go.jp/main_content/000843318.pdf)

> Ⅲ. 3.1.2 【基本】設定項目の管理 【ベストプラクティス】 (p.49)
>  - i. 管理については、サードパーティやクラウドサービス事業者から提供される設定項目の可視化ツール等を利用する。
>  - ii. 初期の設定だけでなく、設定値の監視の仕組み等を構築する。（予防的措置）
>  - iii. 外部の設定値診断サービス等を活用して定期的に設定値の診断を行う。（予防的措置）
>  - iv. 設定が変更されたことが検知されたら、なるべく早く適正な設定値に戻す、又は自動で復元する仕組みを組み込んでおく。（発見的措置）

:::note info
ベストプラクティス：設定値の監視、自動で復元する仕組み
:::
人が設定する時点でミスを防ぐことは困難なため、設定ミスが発生することを前提に対策を考えることが重要です。お勧めの対策は、危険なルールが設定されたら検出して、自動的に該当のルールを削除する仕組みを導入することです。

AWSではどうすればよいでしょうか？簡単な方法として、AWS Configを使いましょう！

# 2. 概要: AWS Configを使った検出と自動修復
- AWS Configルールで非準拠を検出
  - AWSで用意されているルールを活用
- 修復アクションで設定不備に自動対応
  - AWS管理のSSMドキュメントを活用
  - SSMドキュメントのカスタマイズ方法

## 2-1. 特徴
AWSで用意されているものを使うため、汎用的で簡単に導入できる方法であると思います。
- 簡単に導入できて、仕組みを理解しやすい。
- マネジメントコンソールから設定。スクリプト(Lambda等)不要。

※AWS Security HubやAWS Control Towerを利用している場合は下記をご確認ください。
  - [補足1. AWS Security Hub利用時](#補足1-aws-security-hub利用時)
  - [補足2. AWS Control Tower利用時](#補足2-aws-control-tower利用時)

## 2-2. 検出／修復対象の条件
対象条件：セキュリティグループのインバウンドルール
- ルールタイプ ：RDP(3389/tcp)、SSH(22/tcp)、すべてのTCP(0-65535)、すべてのトラフィック
- ソース：0.0.0.0/0 (Anywhere-IPv4) 
  - ※本記事ではIPv4の無制限許可の条件を対象にしています。

## 2-3. 仕組み
- AWSセキュリティグループの設定不備の検出／自動修復の仕組みを以下に示します。
![diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/424aa3fb-7237-17a3-a415-05482f03ca48.png)
  - 主にAWS Config、Systems Manager(SSMドキュメント/オートメーション)を利用
    - 参考：[AWS Systems Managerオートメーションランブックを利用して非準拠ステータスのAWS Configルールを修復する](https://aws.amazon.com/jp/blogs/news/remediate-noncompliant-aws-config-rules-with-aws-systems-manager-automation-runbooks/)

# 3. AWSで用意されている検出と修復の設定方法

- AWSで用意されているConfigルールを設定することで無制限許可の検出に対応できます。RDPとSSHの両方の検出に対応する場合は下記の2つのConfigルールを設定する必要があります。

| AWS Configルール名 | 対応ポート (インバウンド通信) |
| --- | --- |
| [restricted-common-ports](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/restricted-common-ports.html) | RDP (3389/tcp), FTP (20/tcp, 21/tcp), MySQL (3306/tcp, 4333/tcp) |
| [restricted-ssh](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/restricted-ssh.html) | SSH (22/tcp) |

- 検出については、「すべてのTCP」、「すべてのトラフィック」の条件で設定した無制限許可(0.0.0.0/0)のルールも検出できます。
 
## 3-1. セキュリティグループのRDP/SSHの全開放を検出
- AWS Config ＞ ルール ＞ ルールを追加
  - ルールタイプ：AWSによって管理されるルールの追加 を選択
  - AWS マネージド型ルール から検索します。
    - RDPの検出：[restricted-common-ports](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/restricted-common-ports.html)
    
    - SSHの検出：[restricted-ssh](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/restricted-ssh.html)

![config-add-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/69efef9a-2728-fe2b-a891-30cdd3b2934f.png)

- あとはポチポチとクリックして進めていけば検出設定ができます。（詳細は省略）

- 設定後、セキュリティグループで非準拠の条件があると検出されます。
- 検出結果は、AWS Configルールの一覧から非準拠のセキュリティグループを確認可能
    - 別途設定：通知したい
      -  → EventBridge＋SNSでイベント通知（Emailなど / 詳細は省略）
***
- 参考：検出できるセキュリティグループのルール
    | タイプ | ソース | 検出可能なConfigルール | 検出結果 |
    | --- | --- | --- | --- |
    | RDP (3389/tcp) | 0.0.0.0/0| restricted-common-ports | <font color="red">非準拠</font> |
    | SSH (22/tcp) | 0.0.0.0/0| restricted-ssh | <font color="red">非準拠</font> |
    | すべてのTCP | 0.0.0.0/0| restricted-common-ports<br>restricted-ssh | <font color="red">非準拠</font> |
    | すべてのトラフィック | 0.0.0.0/0 | restricted-common-ports<br>restricted-ssh | <font color="red">非準拠</font> |
    | すべてのTCP | 1.0.0.0/8 | - (対象外のソース条件のため) | <font color="green">準拠</font> |
    | HTTPS (443/tcp) | 0.0.0.0/0 | - (対象外のポート条件のため) | <font color="green">準拠</font> |

## 3-2. 自動修復の設定方法
検出された非準拠のセキュリティグループのルールに対して「AWS Systems Manager(SSM) Automation」でSSMドキュメントを実行し、自動削除するように設定します。
簡単に設定方法を説明します。詳細は下記のAWSドキュメントを参照ください。
- 参考：[AWS Config ルールによる非準拠リソースの修復](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/remediation.html) 

### 3-2-1. 事前準備：IAMポリシーとロールの作成
- 修復アクションがセキュリティグループのインバウンドルールを削除するために必要なIAMポリシーとロールの作成について説明します。
- 最小権限で設定するため、Actionに **e2:RevokeSecurityGroupIngress** のみ許可したポリシーを持つIAMロールを作成しておきます。

#### IAM ポリシー作成
- 名前(例)：RevokeSecurityGroupIngress
- **ec2:RevokeSecurityGroupIngress** を許可
  ```json
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "ec2:RevokeSecurityGroupIngress",
              "Resource": "*"
          }
      ]
  }
  ```
    
#### IAM ロールを作成し、ポリシーをアタッチ
- 名前(例)：DisablePublicAccessForSecurityGroup
- 許可ポリシー：**RevokeSecurityGroupIngress** ※作成したポリシーを選択
- 信頼関係：信頼ポリシー(JSON)
    ```json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "ssm.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    ```

### 3-2-2. Configルールの修復アクションの設定
検出で設定した各Configルールごとに修復設定が必要です。**restricted-common-ports**、**restricted-ssh** に対してそれぞれ設定します。
- AWS Config ＞ アクション ＞ 修復の管理
![config-automation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/8a67d05d-1536-7613-6937-175cf9c7902b.png)


  - SSMドキュメントを選択：**[AWS-DisablePublicAccessForSecurityGroup](https://docs.aws.amazon.com/ja_jp/systems-manager-automation-runbooks/latest/userguide/automation-aws-disablepublicaccessforsecuritygroup.html)**
    - セキュリティグループのパブリックアクセスの無効化 (SSH/RDP)

# 4. 標準の修復アクションでは対応できないケース
AWSで用意されている修復アクション：**<font color="red">AWS-DisablePublicAccessForSecurityGroup では「すべてのTCP」、「すべてのトラフィック」のインバウンドルールは削除されません。</font>**
  - :warning: <font color="Red">未対応ルール：すべてのTCP（0-65535）、すべてのトラフィック</font>
    ![sg-automation-ng-rules.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/e9b2ab06-e434-749b-c0d3-fcce2c14ef46.png)
       - ポート番号を指定しない条件のルール削除には対応していません。
   - プロトコル指定の条件は修復できます。（SSH 22/tcp、RDP 3389/tcpを指定）
***
- 検出と修復についてまとめると以下になります。（ソース条件：0.0.0.0/0）
    | タイプ | 検出：Configルール | 修復：SSMドキュメント |
    | --- | --- | --- |
    | RDP (3389/tcp) | restricted-common-ports | AWS-DisablePublicAccessForSecurityGroup |
    | SSH (22/tcp) | restricted-ssh | AWS-DisablePublicAccessForSecurityGroup |
    | すべてのTCP | restricted-common-ports<br>restricted-ssh | <font color="red">**未対応**</font> ※カスタマイズで対応 |
    | すべてのトラフィック | restricted-common-ports<br>restricted-ssh | <font color="red">**未対応**</font> ※カスタマイズで対応 |
  - 「すべてのトラフィック」、「すべてのTCP」のルールを自動修復したい場合は、カスタマイズで対応が必要となります。

# 5. 修復のカスタマイズ方法（SSMドキュメント）
修復のカスタマイズで「すべてのTCP」、「すべてのトラフィック」のルールの自動修復に対応する方法を説明します。

- Systems Manager (SSM) ドキュメントのカスタマイズで対応します。
  - AWS Systems Manager > ドキュメント
  - **AWS-DisablePublicAccessForSecurityGroup** を選択
  - アクション ＞ ドキュメントのクローン作成

![ssm-document-customize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583919/7af5a02f-6056-3ec7-5c5e-cb3a650d0f61.png)

  - ドキュメントエディタ ＞ 編集 でYAMLで設定されている条件をカスタマイズできます。
### 任意の条件を追加する
- 既存の設定を参考に、コピペで条件を追加していく感じでカスタマイズできます。
- **[RevokeSecurityGroupIngress](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RevokeSecurityGroupIngress.html)** のAPIを使用します。（詳細は **[APIリファレンス](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RevokeSecurityGroupIngress.html)** 参照）
---
- 例）すべてのTCP条件 (IPv4)
    ```yaml
        - name: DisableALLTCPFromIpV4
            action: 'aws:executeAwsApi'
            inputs:
              Service: ec2
              Api: RevokeSecurityGroupIngress
              GroupId: '{{GroupId}}'
              IpPermissions:
                - IpProtocol: tcp
                  FromPort: 0
                  ToPort: 65535
                  IpRanges:
                    - CidrIp: 0.0.0.0/0
    ```
  - FromPort、ToPortでポート範囲を指定できます。
  - すべてのTCPポートの場合、FromPort: 0、ToPort: 65535を指定します。
  - IpProtocolやFromPort/ToPort条件で任意ポート条件にカスタマイズ対応できます。

---
- 例）すべてのトラフィック条件（IPv4）
    ```yaml
        - name: DisableALLTrafficFromIpV4
            action: 'aws:executeAwsApi'
            inputs:
              Service: ec2
              Api: RevokeSecurityGroupIngress
              GroupId: '{{GroupId}}'
              IpPermissions:
                - IpProtocol: '-1'
                  IpRanges:
                    - CidrIp: 0.0.0.0/0
    ```
  > 引用：[Amazon EC2 > API Reference - RevokeSecurityGroupIngress](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RevokeSecurityGroupIngress.html)
  > - IpProtocol:
  >   - The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers). Use -1 to specify all.
    - :warning:「すべて」のプロトコル条件を指定する場合は、文字列で <font color="Red">**'-1'**</font> を指定
      - ※値のタイプは文字列なので、-1 ではエラーになります。
---

# 6. まとめ
- AWSの設定不備対策として、AWS Configルール／修復アクションで自動化しよう

- 検出の設定は超簡単！AWSで用意されているものを活用

- 自動修復もAWSで用意されているものを活用。不十分なケースにはカスタマイズで対応
  - 未対応：「すべてのTCP」、「すべてのトラフィック」条件の自動修復ができない
    - → SSMドキュメントのカスタマイズで対応。ひと手間かかるが、比較的簡単
---
# 補足1. AWS Security Hub利用時
検出だけならSecurity Hubを有効化することで、簡単にAWSセキュリティベストプラクティスへの準拠状況をチェックできるのでお勧めです。
セキュリティグループのRDP/SSHの設定不備対策で使えるものをピックアップしました。
### 【検出①】 CIS AWS Foundations Benchmark v1.2.0
- SSHとRDPの無制限許可の検出が可能（restricted-ssh、restricted-common-ports)
  - [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)

### 【検出②】 AWS基礎セキュリティのベストプラクティス v1.0.0
- リスクの高いTCPポートの無制限許可を検出(20,21,22,23,25,110,135,143,445,1433,1434,3000,3306,3389,4333,5000,5432,5500,5601,8080,8088,8888)
  - [EC2.19 Security groups should not allow unrestricted access to ports with high risk](https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-19)

### 【修復】「AWSでの自動化されたセキュリティ対応」の導入
  - [AWSでの自動化されたセキュリティ対応 | AWS ソリューションライブラリ](https://aws.amazon.com/jp/solutions/implementations/automated-security-response-on-aws/)
    - CloudFormationで導入。SSHとRDPの自動修復に対応可能（EC2.13、EC2.14）
    - Amazon EventBridgeで有効化
      - SC_2.0.0_EC2.13_AutoTrigger (SSH)、SC_2.0.0_EC2.14_AutoTrigger (RDP)

    :::note warn
    - EC2.13、EC2.14の修復は「すべてのTCP」、「すべてのトラフィック」条件には対応していません。
    - EC2.19の修復アクションは提供されていません。
    - Security HubのルールはAWS Configでは修復設定できません。 
    :::
    * GitHubのコード「ASR-SC_2.0.0_EC2.13」を参考にしてカスタマイズするなどの対応が必要となります。
      - CDK利用など、難易度は高いかもしれません※詳細は下記をご確認ください。
        - 参考：[Automated Security Response on AWS > Implementation Guide](https://docs.aws.amazon.com/ja_jp/solutions/latest/automated-security-response-on-aws/developer-guide.html)

    - 「すべてのXXX」のルールについては、重複検出になりますが、本記事の方法を併用することで自動修復に対応できます。(Security Hubのルールと別で追加設定)
---
# 補足2. AWS Control Tower利用時
複数アカウント利用時、統制したいなどでAWS Control Towerを導入しているケースについて補足します。

### 【検出】SSH/RDPの無制限許可のコントロールを有効にする
  - AWS Control Towerで用意されているコントロール：
      - [**[AWS-GR_RESTRICTED_SSH]**](https://docs.aws.amazon.com/controltower/latest/userguide/strongly-recommended-controls.html#ssh-disallow-internet) 
        -  SSH を介した無制限のインターネット接続が許可されているかどうかを検出する
      - [**[AWS-GR_RESTRICTED_COMMON_PORTS]**](https://docs.aws.amazon.com/controltower/latest/userguide/strongly-recommended-controls.html#rdp-disallow-internet) 
        - 無制限の着信 TCP トラフィックが許可されているかどうかを検出する
        
    - その他、[**[CT.EC2.PR.3]**](https://docs.aws.amazon.com/controltower/latest/userguide/ec2-rules.html#ct-ec2-pr-3-description)、[**[CT.EC2.PR.4]**](https://docs.aws.amazon.com/controltower/latest/userguide/ec2-rules.html#ct-ec2-pr-4-description)などセキュリティグループ関連のコントロールがあります。
    
- 参考：[AWS Control Tower コントロールメタデータのテーブル](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/control-metadata-tables.html)
- 参考：[コントロールの制限事項](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/control-limitations.html)  :warning: 大阪リージョン(ap-northeast-3)など未対応


### 【修復】AWS Config 適合パックを使う
- 本記事で紹介したAWS Configの修復アクションでも個別に修復対応できますが、AWS Control Towerは統制や設定効率化などで導入すると思いますので、適合パックを使うなどで効率化したほうがよいでしょう。
- [参考：AWS Config 適合パックを使用したAWS Control Tower発見的ガードレールの実装](https://aws.amazon.com/jp/blogs/news/aws-control-tower-detective-guardrails-as-an-aws-config-conformance-pack/)