コンテンツにスキップ

threat_detection pattern

概要

threat_detection patternモジュールでは、AWS環境に対する悪意あるアクティビティや不正な動作の脅威検出とチャットツールへの通知機能を提供します。

想定する適用対象環境

threat_detection patternは、Delivery環境およびRuntime環境のいずれでも使用されることを想定しています。

依存するpattern

threat_detection patternは、事前に以下のpatternが適用されていることを前提としています。

pattern名 利用する情報
network pattern チャット通知に用いるLambda関数を配置するVPCとサブネット

構築されるリソース

このpatternでは、以下のリソースが構築されます。

リソース名 説明
Amazon GuardDuty AWS環境に対する悪意あるアクティビティや不正な動作の脅威検出サービスを有効にします
AWS Lambda GuardDutyで検出した脅威イベントを、各種チャットツールへ通知するためのLambda関数を作成します
Amazon EventBridge GuardDutyで検出した脅威を通知するためのイベントを作成します
Amazon CloudWatch Logs Lambda関数のログが置かれるロググループ
AWS IAM Lambda関数に付与するIAM Roleと、そのIAM Roleに適用するIAM Policyを作成します

モジュールの理解に向けて

一般的に、インフラストラクチャに対する脅威に対しては素早く検出し調査、修正することが求められます。 threat_detection patternでは、AWS環境に対する脅威の検出とチャットツールへの通知を実現します。

本パターンで構築するリソースのアーキテクチャを下図に示します。 アーキテクチャ

GuardDutyによる脅威の検出

Amazon GuardDuty(以下、GuardDuty)は、利用しているAWSアカウントにおけるセキュリティ監視サービスです。
AWSが収集する各種ログを元に、例として以下のような悪意のあるアクティビティやユーザーによる予期しないアクティビティ、疑わしき操作や変更を検出できます。

  • マルウェアや意図しないビットコインマイニングに利用されているEC2インスタンス
  • 悪意あるIPアドレスやURL、ドメインとの通信
  • 普段利用しないAWSリージョンへのインスタンスデプロイ
  • パスワード強度を低下させるようなパスワードポリシーの変更

ℹ️ GuardDutyについての詳細は、公式ドキュメントを参照ください。

脅威検出イベントをチャットツールへ通知する

GuardDutyが脅威を検出したイベントをチームが利用するチャットツールへ通知することでリスクの早期発見ができ、素早い調査や対応が実施可能になります。

チャットツールに通知される内容は、GuardDutyの検出結果に基づいた以下の情報が通知されます。

通知項目 説明
Time 脅威検出イベントが発生した日時
AWS Account 脅威検出イベントが発生したAWS Account ID
AWS Region 脅威検出イベントが発生したAWSリージョン
Severity 脅威検出イベントの重大度の値
Type 発生した脅威検出イベントの種別
Description どのような脅威検出イベントが発生したかの説明

Eponaで通知先としてサポートしているチャットツールは以下になります。

ℹ️ チャットツールへの通知には、webhookを用いたTLS通信を利用しています。
通知先となるサービスのIncoming Webhookの設定は、Epona利用者で事前に実施いただく必要があります。

ℹ️ Eponaを導入する企業によってはコンプライアンスなどの観点で、社内で利用しているチャットツールへ通知する場合に送信元IPを制限するケースが想定されます。
これに対応するため、通知機能を実行するLambda関数はVPCに配置することで、送信元IPアドレスを固定化する構成となっています。

GuardDutyが検出した脅威の重大度について

GuardDutyの脅威検出結果には、AWSのセキュリティエンジニアにより重大度の値(Severity)が設定されています。
また、セキュリティ問題への対応の判断に役立つように、重大度の値に応じて3段階に重大度レベルが定義されています。

重大度の値重大度レベルについては、以下のドキュメントを参照してください。
Understanding Amazon GuardDuty findings

Eponaでは、通知を知らせるチャンネルを重大度レベル毎に設定することで通知の範囲を変更することを想定しています。

サンプルコード

threat_detection patternを使用したサンプルコードを、以下に記載します。

module "threat_detection" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/threat_detection?ref=v0.2.6"

  tags = {
    # 任意のタグ
    Environment        = "delivery"
    ManagedBy          = "epona"
  }

  # lambda関数の設定情報
  lambda_function_name = "my-guardduty-notification-function"
  lambda_timeout       = 5

  # Lambdaを配置するVPC情報
  vpc_id            = data.terraform_remote_state.delivery_network.outputs.network.vpc_id
  lambda_subnet_ids = data.terraform_remote_state.delivery_network.outputs.network.private_subnets

  # 通知先となるendpoint情報
  notification_lambda_config = {
    type = "slack",
    endpoints = {
      low    = "https://hooks.slack.com/xxxx/xxxx/xxxx/xxxx",
      medium = "https://hooks.slack.com/yyyy/yyyy/yyyy/yyyy",
      high   = "https://hooks.slack.com/zzzz/zzzz/zzzz/zzzz"
    }
  }
}

関連するpattern

threat_detection patternに関連するpatternはありません。

ログの集約

threat_detection patternでは、AWS Lambda関数のログをAmazon CloudWatch Logsに出力します。

このログは、datadog_log_trigger patternを使用することでDatadogに集約できます。

入出力リファレンス

Requirements

Name Version
terraform ~> 0.14.10
aws >= 3.37.0, < 4.0.0

Inputs

Name Description Type Default Required
lambda_function_name 検出結果を送信するLambda関数の名前 string n/a yes
lambda_subnet_ids Lambdaを配置するサブネットのIDリスト。参考:高可用性関数のために list(string) n/a yes
vpc_id このモジュールで作成するLambdaが配置される、VPCのID string n/a yes
create_guardduty Amazon GuardDutyを新規に作成する場合はtrue(すでに有効になっている場合は、falseを指定してください) bool true no
finding_publishing_frequency 既存の結果の再検出時に通知する頻度。選択可能な値は、GuardDuty APIリファレンスを参照してください。 string "SIX_HOURS" no
lambda_timeout 実行されたLambdaが停止するまでのタイムアウト設定。単位は秒で指定してください。 number 3 no
log_kms_key_id 通知先へ検知を送信するLambda関数のログ出力先である、CloudWatch Logsを暗号化するためのKMS CMKのARN string null no
log_retention_in_days 検出結果を送信するLambda関数のログの記録先である、CloudWatch Logsの保存期間を設定する。

値は、次の範囲の値から選ぶこと: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
Resource: aws_cloudwatch_log_group / retention_in_days
number null no
notification_lambda_config 検出結果を送信するLambda関数の設定値。
type: チャットサービス["slack" | "teams"]
endpoints: エンドポイントのurl情報
low/medium/high: それぞれの脅威度毎のIncoming Webhookのパス(通知しない場合は未設定もしくはnullを指定)

以下、設定例です。
{
type = "slack"
endpoints = {
medium = "https://hooks.slack.com/xxxx/xxxx"
high = "https://hooks.slack.com/yyyy/yyyy"
}
}
object({
type = string,
endpoints = map(string)
})
{
"endpoints": {
"high": null,
"low": null,
"medium": null
},
"type": "slack"
}
no
notification_lambda_handler 検出結果を送信するLambda関数のエントリーポイント string "index.handler" no
notification_lambda_runtime 検出結果を送信するLambda関数のランタイム string "nodejs12.x" no
notification_lambda_source_dir 検出結果を送信するLambda関数のソースコードが配置されたディレクトリのパス string null no
tags このモジュールで作成されるリソースに付与するタグ map(string) {} no

Outputs

Name Description
lambda_function_thread_detection_log_group_name Lambda関数のログ出力先となる、CloudWatch Logsロググループ名
lambda_function_threat_detection_arns 検出結果を送信するLambda関数のARN一覧

※ このドキュメントはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

© 2021 TIS Inc.