Security Hub Automation Rulesを使ってみた

## はじめに
Security HubでAutomation Rulesが使えるようになったので、試してみました。

https://dev.classmethod.jp/articles/security-hub-automation-rules/

上記記事にもありますが、この機能を利用する事で、条件により、Security Hubのコントロールの重要度やワークフローステータスの変更(特定のリソースだけ抑制済みにするなど)を自動で行えるようになります。

これまで、環境の特性や運用上、セキュリティ標準の重要度とは別の重要度を独自に設定したり、特定のリソースについては、利用用途が違う為、ワークフローステータスを抑制済みにしたいという場合、対応が難しい状態でしたが、この機能により、管理コンソールからの設定で自動で制御できるようになります。

Security Hubの類似機能である、OCIのCloud Guardでは、標準とは別に独自のレシピを設定する事ができていましたが、AWSでも同様の事が実現できそうです。

今回は、Security Hubに最近追加されたコントロールである、`【S3.15】S3 buckets should be configured to use Object Lock`について、特定のS3バケットのみチェック対象とし、対象外のS3バケットについては、自動的にワークフローステータスが抑制済みになるよう設定してみたいと思います。

背景として、AWS Config用、S3アクセスログ用のS3バケットがObject Lockが設定されたS3バケットをサポートしない事と、オブジェクトを上書きする用途で利用しているバケットが存在するのが理由です。

その為、今回は、CloudTrailのログとVPCフローログを出力している2つのS3バケットのみコントロールのチェック対象になるようにし、その他のS3バケットについては、ワークフローステータスを自動で抑制済みにしてみる事にします。

S3のObject Lock機能については、以下の記事などを参照ください。

https://dev.classmethod.jp/articles/amazon-s3-object-lock-research/

## Security Hubのオートメーションルールを作成する前に
ルールを作成する前に、作成対象のコントロールのステータスと、チェック対象リソースのコンプライアンスステータスを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/580a1e2a-2cc0-40f5-d271-aa03414a9f5a.png)
下のチェック結果の一覧で、コンプライアンスステータスが「PASSED」になっているのが、CloudTrailのログとVPCフローログを保管しているバケット、それ以外はオブジェクトロックがサポート対象外だったり、用途的にオブジェクトの上書きや削除を禁止したくないバケットになります。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/61d0f363-f407-42a3-d3ce-421545439521.png)
オートメーションルールを作成する前に、コンプライアンスステータスが「FAILD」になっているリソースの検出結果jsonの内容を確認しておきます。

オートメーションルールを作成する際の条件指定で、「Product Name」、「GeneratorId」、「ResourceId」などを指定しますが、条件が何を意味していて、何の値を指定したらよいのか初見では分からないのですが、jsonの内容を確認しておく事で、何を設定したらよいか理解する事ができます。

以下は、コンプライアンスステータスが「FAILD」になっているリソースのjsonの例です。
```json
{
  "SchemaVersion": "2018-10-08",
  "Id": "arn:aws:securityhub:ap-northeast-1:XXXXXXXXXXXX:security-control/S3.15/finding/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "ProductArn": "arn:aws:securityhub:ap-northeast-1::product/aws/securityhub",
  "ProductName": "Security Hub",
  "CompanyName": "AWS",
  "Region": "ap-northeast-1",
  "GeneratorId": "security-control/S3.15",
  "AwsAccountId": "XXXXXXXXXXXX",
  "Types": [
    "Software and Configuration Checks/Industry and Regulatory Standards"
  ],
  "FirstObservedAt": "2023-04-05T20:26:53.685Z",
  "LastObservedAt": "2023-06-14T18:39:28.991Z",
  "CreatedAt": "2023-04-05T20:26:53.685Z",
  "UpdatedAt": "2023-06-14T18:39:18.676Z",
  "Severity": {
    "Label": "MEDIUM",
    "Normalized": 40,
    "Original": "MEDIUM"
  },
  "Title": "S3 buckets should be configured to use Object Lock",
  "Description": "This control checks if an Amazon S3 bucket has been configured to use Object Lock. The control fails if the S3 bucket isn't configured to use Object Lock.",
  "Remediation": {
    "Recommendation": {
      "Text": "For information on how to correct this issue, consult the AWS Security Hub controls documentation.",
      "Url": "https://docs.aws.amazon.com/console/securityhub/S3.15/remediation"
    }
  },
  "ProductFields": {
    "RelatedAWSResources:0/name": "securityhub-s3-bucket-default-lock-enabled-XXXXXXXX",
    "RelatedAWSResources:0/type": "AWS::Config::ConfigRule",
    "aws/securityhub/ProductName": "Security Hub",
    "aws/securityhub/CompanyName": "AWS",
    "aws/securityhub/annotation": "S3 default lock is not enabled",
    "Resources:0/Id": "arn:aws:s3:::awsconfig-xxxx",
    "aws/securityhub/FindingId": "arn:aws:securityhub:ap-northeast-1::product/aws/securityhub/arn:aws:securityhub:ap-northeast-1:XXXXXXXXXXXX:security-control/S3.15/finding/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  },
  "Resources": [
    {
      "Type": "AwsS3Bucket",
      "Id": "arn:aws:s3:::awsconfig-xxxx",
      "Partition": "aws",
      "Region": "ap-northeast-1",
      "Details": {
        "AwsS3Bucket": {
          "OwnerId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
          "CreatedAt": "2021-10-25T05:15:51.000Z"
        }
      }
    }
  ],
  "Compliance": {
    "Status": "FAILED",
    "RelatedRequirements": [
      "NIST.800-53.r5 CP-6(2)"
    ],
    "SecurityControlId": "S3.15",
    "AssociatedStandards": [
      {
        "StandardsId": "standards/nist-800-53/v/5.0.0"
      }
    ]
  },
  "WorkflowState": "NEW",
  "Workflow": {
    "Status": "NEW"
  },
  "RecordState": "ACTIVE",
  "FindingProviderFields": {
    "Severity": {
      "Label": "MEDIUM",
      "Original": "MEDIUM"
    },
    "Types": [
      "Software and Configuration Checks/Industry and Regulatory Standards"
    ]
  },
  "ProcessedAt": "2023-06-14T18:39:34.058Z"
}
```
オートメーションルールでは、以下ようなキーの値を条件に指定する事ができますが、各キーの上記jsonでの対応を一覧にしてみます。
| オートメーションルールの検索条件キー | 対応するjson項目名 | 備考 |
|:-|:-|:-|
| AwsAccountId | AwsAccountId |  |
| CompanyName | CompanyName |  |
| ComplianceAssociatedStandardsId | Complianceの項目内のAssociatedStandards項目内のStandardsId |  |
| ComplianceSecurityControlId | Complianceの項目内のSecurityControlId | GeneratorIdと類似? |
| ComplianceStatus | Complianceの項目内のStatus |  |
| Confidence | 不明 |  |
| CreatedAt | CreatedAt |  |
| Criticality | 不明 |  |
| Description | Description |  |
| FirstObservedAt | FirstObservedAt |  |
| GeneratorId | GeneratorId | ComplianceSecurityControlIdと類似? |
| Id | Id? | ※要確認 |
| LastObservedAt |  LastObservedAt |  |
| NoteText |  不明 |  |
| NoteUpdatedAt |  不明 |  |
| NoteUpdatedBy |  不明 |  |
| ProductArn |  ProductArn |  |
| ProductName |  ProductName |  |
| RecordState |  RecordState |  |
| RelatedFindingsId |  不明 |  |
| RelatedFindingsProductArn |  不明 |  |
| ResourceDetailsOther |  Resourcesの項目内のDetails項目内のキーと値 | ※恐らく。要確認。 |
| ResourceId |  Resourcesの項目内のId |  |
| ResourcePartition |  Resourcesの項目内のPartition |  |
| ResourceRegion |  Resourcesの項目内のRegion |  |
| ResourceTags | 不明 | ※要確認。Resourcesの項目内のTagとして出力される? |
| ResourceType | Resourcesの項目内のType |  |
| SeverityLabel | FindingProviderFieldsの項目内のSeverity項目内のLabel |  |
| SourceUrl | Remediation項目内のRecommendation項目内のUrl |  |
| Title | Title |  |
| Type | Resources項目内のType |  |
| UpdatedAt | UpdatedAt |  |
| UserDefinedFields | 不明 |  |
| VerificationState | 不明 |  |
| WorkflowStatus | Workflowの項目内のstatus |  |

少しルールで指定できる条件と値が分かりにくいのと、上記記述に間違いもあるかもしれませんが、上記記述を参考にルールを作成してみます。

Automation Rulesの公式ドキュメントについては、以下を参照ください。

https://docs.aws.amazon.com/securityhub/latest/userguide/automation-rules.html

## Security Hubのオートメーションルールの作成
新規に追加された「オートメーション」をクリックし、オートメーションの一覧で「ルールを作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/a9dc52cb-303a-793e-53fd-24f269b73a2e.png)
ルールの作成画面では、テンプレートからとカスタムルールを選択できます。
※個人的には、条件と値に何を設定すればよいのかさえ分かっていれば、どちらを選択しても問題ないと思います。

「カスタムルールを作成」を選択した場合、条件を1から追加して設定します。
「テンプレートからルールを作成」を選択すると、3つの用途用に予めいくつかの条件が追加された状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/f0b08187-8ef7-2bdd-bc19-e71122d4af2f.png)
ルールテンプレートには、以下の3つがあります。
- Elevate severity of findings that relate to important resources
    - 重要なリソースに関連する検出結果の重大度を変更したい場合のテンプレート
- Suppress informational findings
    - 検出された内容について、抑制したい場合のテンプレート
- Elevate severity of findings that relate to resources in production accounts
    - アカウントのリソースに関連する検出結果の重大度を変更したい場合のテンプレート

今回は、特定のS3バケットについて、検出結果を抑制したいため、2つめの`Suppress informational findings`のルールテンプレートを選択して条件設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/9fbbdddc-a63b-f230-b367-06a4e229da9c.png)
まず、ルール名とルールの説明を記載します。
複数のルールを作成するなどすると、何のためのルールか分かりにくくなると思われるため、なるべく詳細に書く方がよいと思います。

#### 条件
次に対象となるコントロールやリソースなどを指定するルールの条件を指定します。
条件には「キー」、「演算子」、「値」を指定しますが、これらが何にあたるのかについては、コンプライアンスステータスが「FAILD」になっているリソースの「検出結果json」の内容および、上述したキーとjsonの対応表を確認しつつ設定します。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/83d34259-9889-3e69-63d7-22aeea767e7b.png)
今回は、以下のように設定しました。
| キー | 演算子 | 値 |
|:-|:-|:-|
| Product Name | EQUALS | Security Hub |
| RecordState | EQUALS | ACTIVE |
| WorkflowStatus | EQUALS | NEW |
| ComplianceStatus | EQUALS | FAILED |
| GeneratorId | EQUALS | security-control/S3.15 |
| ResourceType | EQUALS | AwsS3Bucket |
| ResourceId | NOT_EQUALS | arn:aws:s3:::xxxx-flowlog |
| ResourceId | NOT_EQUALS | arn:aws:s3:::xxxx-cloudtrail-logs |

:::note info
この環境では、S3バケットにタグを付けていなかったため、チェック対象にするリソース以外を条件に指定しましたが、これだと今後チェック対象にしたいバケットが追加された場合にルールの変更が必要になってしまうため、タグのキーと値により条件指定をした方が望ましいです。

しかし、試しにS3バケットにタグを追加し、「ResourceTags」をオートメーションルールの条件のキーとし、演算子を「EQUALS」、値にタグのキーと値を指定してみましたが、この指定では抑制済みにしたいバケットの条件として使えなかった(プレビューに何も表示されなかった)ため、また別途検証してみたいと思います。
:::

#### プレビュー
条件を設定した後、下の画像の「リフレッシュ」ボタンをクリックすると、条件に指定したキーと値にマッチする内容が一覧表示されます。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/f0679350-b534-5752-502d-b01a8d3a234f.png)
この一覧では、何のリソースがマッチしたのかまでは分かりませんが、抑制済みにしたいバケット数とプレビューで表示された件数が同じであったため、問題ないと判断しました。

#### 自動アクション
条件の設定が終わったら、マッチした際の自動アクションを設定します。
自動アクションでは、変更したくない項目について、選択肢の項目は「None」を、数値やテキストを入力する項目は空白にしておく必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/3fc3ac4b-0855-357b-d94c-8d37d0a8809b.png)
今回は、条件にマッチしたリソースについて、ワークフローステータスを抑制済みにしたいため、ワークフローステータスを「SUPPRESSED」、重要度、検証状態は「None」、重要度、信頼、タイプは空白としました。

最後の"注"に記載した内容は、自動アクションにより、抑制済みに変更された理由としてチェック結果に表示されるため、詳細に理由を記載しておく事をお勧めします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/c0d05ddc-d161-3ba8-f0f5-7b589c363c09.png)
自動アクションの設定後、「ルールを作成」ボタンをクリックする事で、オートメーションルールの作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/ed6534fb-7aeb-1ab4-e8b9-8678a58d5190.png)

#### オートメーションルール設定結果の確認
オートメーションルールに設定した内容が反映されるのは、Security Hubによるチェックが次に行われたタイミングになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/83442c54-ae7d-139b-10b1-1fd96908039d.png)
オートメーションルールを設定した翌日に改めて確認した所、意図通りCloudTrailのログ用とVPCフローログ用の2つのバケット以外については、全てワークフローステータスが抑制済みになっており、コントロールステータスも「成功」になりました。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/802942dd-3464-f3ee-eaf1-1aaf6cf00510.png)
また、オートメーションルールにより自動で抑制済みになったリソースについては、更新済み列の時間の下のアイコンをクリックする事で、Security Hubのオートメーションルールによる更新である事と、自動アクションの「注」に記載した内容が理由として表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/a5577ef1-e4ee-f667-d343-1ce2d4449b05.png)

以上で、意図通りにオートメーションルールが設定できている事が確認できました。

## おわりに
条件の指定にタグが使えなかった理由は不明ですが、オートメーションルールを利用する事により、これまで手動で確認し対応していたワークフローステータスの抑制や、独自のセキュリティ基準での運用が可能となりそうです。

セキュリティ運用上、有用な機能だと思いますので、今後も活用していきたいと思います。