はじめに
GuardDutyの抑制ルールをCloudFormationで設定するときのポイントについてお話します。
※結論だけ知りたい方は間を飛ばして最下部「まとめ」をご覧ください。
抑制ルールとは
AWSの ドキュメント では下記のように説明されています。
抑制ルールは、フィルター属性と値の組み合わせで構成される基準のセットで、指定した条件に一致する新しい検出結果を自動的にアーカイブして検出結果をフィルタリングするために使用する条件のセットのことです。抑制ルールを使用して、重要ではない検出結果、誤検出の検出結果、対応を行わない脅威をフィルタリングすることにより、環境に最も影響があるセキュリティの脅威を認識しやすくなります。
GuardDutyは機械学習を利用してAWS上の様々な脅威(検出結果タイプ)を検出してくれる便利なサービスですが、必ずしも全ての検出結果が対応を要するものではなく、AWS側では本当の脅威かどうか判断できない(=AWS利用者でしか判断できない)脅威も検出してくれます。
そのため、通知されるイベントをできるかぎり必要なもののみに限定することが、GuardDutyを運用していく上では重要と考えられます。
抑制ルールの使用例
抑制ルールの使用例についてご紹介します。
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS
この検出結果タイプは ドキュメント で下記のように説明されています。
インスタンス起動ロールを通じて EC2 インスタンス専用に作成された認証情報は、AWS 内の別のアカウントから使用されています。
「AWS 内の別のアカウントから」というのがポイントです。
例えば、複数のAWSアカウントのVPCをTrangit Gatewayで接続し、特定のAWSアカウントでインターネット向けアウトバウンド通信を集約しているような構成で検出されることがあります。
このような構成において、VPCエンドポイント経由ではなくインターネット経由でAWSのAPIへのアクセスがある場合、検出されます。
下記のAND条件で抑制ルールを作成することで検出結果を自動アーカイブすることができます。
- 検出結果タイプが「UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS」である
- 「API 発信者の IPv4 アドレス」 がNat GatewayのIPである
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS
この検出結果タイプは ドキュメント で下記のように説明されています。
インスタンス作成ロールで EC2 インスタンス専用に作成された認証情報が外部 IP アドレスから使用されています。
「外部 IP アドレスから」というのがポイントです。
例えば、オンプレミスとAWSをDirectConnectで接続し、オンプレミス環境でインターネット向けアウトバウンド通信を集約しているような構成で検出されることがあります。
このような構成において、VPCエンドポイント経由ではなくインターネット経由でAWSのAPIへのアクセスがある場合、検出されます。
下記のAND条件で抑制ルールを作成することで検出結果を自動アーカイブすることができます。
- 検出結果タイプが「UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS」である
- 「API 発信者の IPv4 アドレス」 がGateway(オンプレミス)のIPである
CloudFormationの躓きポイント
抑制ルールをCloudFormationで実装する場合、「AWS::GuardDuty::Filter」リソースを利用します。
CloudFormationテンプレートを作成してデプロイしてみたところ、下記のエラーが発生しました。
The request is rejected because an invalid or out-of-range value is specified as an input parameter.
エラーメッセージからは、どこの値が「invalid or out-of-range」なのか読み取れません。
ドキュメントを見ていたところ、「Rank」という必須プロパティが怪しいことに気がつきました。
以下に ドキュメント から一部抜粋します。
Specifies the position of the filter in the list of current filters. Also specifies the order in which this filter is applied to the findings. The minimum value for this property is 1 and the maximum is 100.
フィルターの適用順序を指定するもので、最小値が1、最大値が100だそうです。
By default, filters may not be created in the same order as they are ranked. To ensure that the filters are created in the expected order, you can use an optional attribute, DependsOn, with the following syntax: "DependsOn":[ "ObjectName" ].
順序どおり作成されない場合があり、順序どおり作成するには「DependsOn」属性を指定する必要があるそうです。
(必須というわけではない・・・?)
わたしが作成したテンプレートは下記の状態になっていました。
- Rankの値は1から100の間に収まっているが、1~10、20~30、といったように間が空いている
- DependsOn属性を利用していない
ここから以下の仮説を立てました。
- 1から連番で番号を振らないとダメなのでは?
- 1から順番に作成しないとダメ(=複数の抑制ルールを作成するならDependsOnが必須)なのでは?
上記仮説に沿ってテンプレートを修正したところ、無事デプロイに成功することができました。
まとめ
複数の抑制ルールをCloudFormationでデプロイする場合のポイントは下記のとおりです。
- Rankプロパティは1から連番で振る
- DependsOn属性でRank1から順に作成されるよう指定する
後から思えば何てことのない躓きポイントだったかもしれませんが、わたしと同様に躓いた方の参考になれば幸いです。