はじめに
JAWS-UG名古屋でAWS上のネットワーク型IDSとしてAmazon GuardDutyを導入している話をしたところ、誤検知対策について興味があるというフィードバックを頂いたので導入方法とともに簡単にまとめてみました。
導入方法
- 単一リージョンに設置するだけならAWS CloudFormationから以下で紹介するスタックテンプレートを使ってスタックを作成すれば有効になります。
- クラスメソッドさんがStackSetsを使って全リージョンに展開するやり方を公開されていたので、それに若干手を加えたものを使用しています。
- 手を加えた点
- SNS TopicPolicyを設定
- オリジナルではsns:Publishが許可されていないのでCloudWatch EventsからSNSを叩けません。
- CloudWatch Eventsのターゲットをカスタマイズ
- デフォルトの通知では発生した事象を追いにくかったので、どのリソースでどういう事象が起きたのかを最低限拾えるようにInput Transformerで整形しています。
- Findings(検出した脅威)を調査する際、GuardDutyのコンソールからActionとTargetを見ているでこの2つも出せると楽になりますが、現状そこまで手を入れられていません。
- SNS TopicPolicyを設定
- 余談
- SNS TopicPolicyの件はクラスメソッドさんの記事にフィードバックしたつもりでいましたが、Disqusでの投稿がスパム扱いになってフィードバックできてないかも。
- 手を加えた点
AWSTemplateFormatVersion: 2010-09-09
Parameters:
EmailAddress:
Description: Enter email address to send notification.
Type: String
Resources:
GuardDutyDetector:
Type: 'AWS::GuardDuty::Detector'
Properties:
Enable: true
GuardDutySNSTopic:
Type: 'AWS::SNS::Topic'
Properties:
TopicName: GuardDutyTopic
Subscription:
- Endpoint: !Ref EmailAddress
Protocol: email
GuardDutySNSTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: GuardDuty-Topic-Policy
Version: '2012-10-17'
Statement:
- Sid: GuardDuty-Statement
Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sns:Publish
Resource: !Ref GuardDutySNSTopic
Topics:
- !Ref GuardDutySNSTopic
GuardDutyEvent:
Type: 'AWS::Events::Rule'
Properties:
Name: AlertGuardDutyFindings
Description: 'Alert to SNS topic when find threats by GuardDuty'
EventPattern: {
"source": [
"aws.guardduty"
],
"detail-type": [
"GuardDuty Finding"
]
}
Targets:
- Arn: !Ref GuardDutySNSTopic
Id: GuardDutyEventTarget
InputTransformer:
InputPathsMap:
"severity": "$.detail.severity"
"description": "$.detail.description"
"region": "$.region"
"title": "$.detail.title"
"type": "$.detail.type"
"account": "$.account"
InputTemplate: "\"Title: <title>\"\n\"Description: <description>\"\n\"Finding Type: <type>\"\n\"Severity: <severity>\"\n\"Account: <account>\"\n\"Region: <region>\""
誤検知対策
Severity(脅威の重大度)によるフィルタリング
- Severityの低いFindingsは発生頻度も高いので、Severityが高いFindingsを見落とさないようにCloudWatch Eventsでフィルタリングをかけます。
- 設定には以下のCLIを使用しています。
- 上述のスタックテンプレートを使用しなかった(できなかった)のは、CloudFormationを使ってEventPatternを設定するとSeverityのフィルタに使用している数値部分が文字列として展開されてしまうためです。
- EventPatternは>=4のような範囲指定ができないので、Medium以上(Severity>=4)の数値を配列として定義します。
$ aws --region=ap-northeast-1 events put-rule --name AlertGuardDutyFindings --event-pattern "{\"source\":[\"aws.guardduty\"],\"detail-type\":[\"GuardDuty Finding\"],\"detail\":{\"severity\":[4.0,4.1,4.2,4.3,4.4,4.5,4.6,4.7,4.8,4.9,5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2,6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7,7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5,8.6,8.7,8.8,8.9,4,5,6,7,8]}}"
環境ごとの通知方法見直し
- 開発環境として使用しているVPCを監視対象に含めると、低頻度なオペレーションを脅威として検出する場合があります。
- GitHub上のシェルスクリプトを実行
- 実際の攻撃手法として使われる場合があるので検出されるべき
- Railsの検証で3000番ポート以外(3001番ポートなど)を使用してHTTPアクセス
- 通常と異なるポートでHTTP通信を検出したため、検出されるべき
- GitHub上のシェルスクリプトを実行
- 開発環境用途なので、機微なデータを扱っていないことを踏まえるとアラートとして通知する必要はない。
- 通知レベルをワーニングに落としてもいいかも。
導入にあたって気をつけること
- VPC Flow Logs, AWS CloudTrail, DNSログを有効にしてください。
- GuardDutyを有効にしても分析するイベントがなければ意味がありません。
- GuardDutyの見方を他のエンジニアに伝えましょう。
- 基本的にはGuardDutyコンソールのActionとTargetを見れば何が起きたかわかるハズです。
- 通信方向(Inbound/Outbound)、通信先ホスト、プロトコルなど
- より詳細に追う場合は、分析元のログをAmazon Athenaに取り込んで手動で分析します。
- あとは普段やらないことを対象インスタンスでやっていないか、運用者にヒアリングするのが手っ取り早いこともあります。
- 基本的にはGuardDutyコンソールのActionとTargetを見れば何が起きたかわかるハズです。
最後に
- まだ”一応使えている”段階なので、「こうするといいよ!」とか、「こういうときどうしている?」とかフィードバックもらえると嬉しいです。
- 比較的かんたんに導入できて、(ログとイベント数によりますが)費用的にも安いのでまだやっていないという方はぜひ試してみてください。
- ちなみにAmazon GuardDutyははじめの30日は無料で使用でき、コンソールからその間の目安金額を確認することができます。