
秋も終わるなぁと思いながら公園を散歩してたらまだまだ紅葉が綺麗でした。カメラ持って出ればよかった…
さて、今回は GuardDuty Malware Protection for S3 の導入に関するレポートです。 GuardDuty Malware Protection for S3 は AWS の脅威検出サービスである GuardDuty が提供している S3 バケットのマルウェアスキャン機能です。 2024年6月に一般提供が開始され、AWS ネイティブの S3 スキャンサービスとして話題になりました。
ニーリーでは2024年9月ごろこのマルウェア保護を有効にしました。 この記事ではマルウェア保護の導入に向けて行った準備を振り返って紹介していこうと思います。 やってみた記事などはいくつか検索にヒットしますが、実際のプロダクトに対して導入してみたという話はまだまだ少ないんじゃないでしょうか。 導入の際の参考になれば幸いです。
目次
導入対象バケットの検討
まずは導入バケットの選定を行いました。 全てのバケットに導入できれば良いのですが、料金・予算のこともありますし、導入できるバケットの数にもクォータがあります。 検討していた頃は上限10までだったのですが、いまは25まで引き上げられてますね! 開発・本番などの環境ごとの事情やバケットの用途を考慮しつつ、どのバケットに対してマルウェアスキャンを導入するか検討しました。
導入対象のバケットを決めた後は、料金を見積もって費用的に導入可能かを確かめました。 マルウェア保護の料金は「スキャンされたデータ量に対する課金額」と「スキャンしたオブジェクト数に対する課金額」の合計で決まります(厳密にはここにS3 APIの利用料が上乗せされます)。
合計バケットサイズとオブジェクトの合計数はメトリクスから取得できるので、対象のバケットに対して直近一年間の差分から月間の差分を見積もりました。 今回の対象バケットはオブジェクトの削除がないバケットでしたが、削除がある場合はそのあたりも考慮してスキャン量の見積もりをする必要がありそうです。

アクセス対象のブロック
スキャンに対するアクセスのブロックはTBAC(Tag Based Access Control)を通じて行います。 マルウェア保護ではスキャンしたオブジェクトにスキャン結果をタグで付与するオプションを設定できます。 マルウェア保護が付与したタグを元にバケットのリソースポリシーを設定することで、スキャン結果に応じたアクセス制御をすることができます。
ドキュメントの例では結果が NO_THREATS_FOUND のものだけアクセスを許可する設定になってます。
しかし、今回導入するのは既に利用を開始しているバケットです。
スキャンは新規のオブジェクトのみ行われ、既存のオブジェクトにはタグがつかない状態になります。
ドキュメントの例そのままだと既存のオブジェクトに対してもアクセスがブロックされてしまうので、結果が THREATS_FOUND なもののアクセスをブロックするというポリシーで設定しました。
アラート通知の整備
実際のプロダクトにマルウェア保護を導入する際には、検知された場合にどう対応するかという運用も決めなければいけません。 迅速な対応のため、検知に気づくためのアラート設定も合わせて必要になります。
GuardDuty の検出結果は Security Hub に集約しており、Security Hub に集約された検出結果を EventBridge → SNS → Chatbot という経路で流してSlack通知する仕組みは既にありました。

今回はこの仕組みを流用してカスタマイズした投稿をSlackに流すようなアラート通知を構築しました。 投稿をカスタマイズすることで、Slackのメンションを担当チームに飛ばすなど通知内容の調整を行っています。
Slack 通知のカスタマイズは Chatbot に流すイベントを加工することで実現できます。 イベントの加工は EventBridge の 入力トランスフォーマー で行いました。
入力イベント(Security Hub イベント)の仕様は下記のドキュメントに書いてあります。 読むのはややしんどいので、入力トランスフォーマー設定画面のイベントサンプルと照らし合わせつつ読むのが良いと思います。
また、Slackカスタム通知用のイベントスキーマは下記のドキュメントが記載されています。 このスキーマに沿ってイベントを送ると通知をカスタマイズすることができます。
検知時対応の検討
通知を受け取ったらスムーズに対応できるよう、検知に対してどのようにアクションを取るのかも可能な範囲で事前に決めておきました。 コーポレート側のセキュリティ担当に相談しながら連絡経路を確認したり、誰の・どのファイルなのかを調査する手段を確立したりしました。 これらの対応手順はドキュメント化されており、Slack通知からリンクを辿れるようになっています。
運用していていざインシデントが起きたとなると対応時にはやっぱり焦ってしまうものです。 詳細な部分はどうしてもケースバイケースになってしまいますが、初動だけでも手順を用意して落ち着いて動けるようにするのは大事だと思います。
マルウェア保護の設定
諸々検討し終わったらいよいよマルウェア保護の導入作業です。詳細な手順についてはドキュメントがあったり記事がたくさん上がっているので省きますが、おおまかには
- GuardDutyに付与するための IAM ロールを用意する
- GuardDutyのコンソールから各バケットに対してMalware Protectionを有効にする
- バケットのリソースポリシーを編集して、TBACの設定を行う
という手順で設定していきます。
この際、導入作業は一気にやってしまうのではなく、TBACの設定だけは時間をおいて実施しました。 検知のみでブロックしないという状態でしばらく運用することで、検知頻度を確認した上でブロックを有効にできるようにしました。
運用してみて
9月に導入してからこの12月で3ヶ月ほどになります。 導入してから合計約100万ファイルほどアップロードされましたが、まだマルウェアは検知されていません。 もちろん、このあたりはサービスの性質などに大きく左右される部分で一概にまとめられませんが、誤検知には悩まされるかもと覚悟していたので個人的には少し意外でした。
マルウェアのアップロードはBE側のMIMEタイプチェックで対策していますが、アプリケーションでの実装はどうしても実装漏れが怖いものです。 ストレージ側でのスキャンで横断的に・最低限守れていることは大きな安心感につながっています。
おしまい
というわけで、GuardDuty Malware Protection for S3 の導入に際しての準備を紹介させていただきました。 実際にプロダクトに導入するとなると考慮すべき点や準備すべきものがいくつか出てくると思います。 この記事がそれらの洗い出しの一助になると嬉しいです。
明日のアドベントカレンダーはデザイナー音部さんの2本目の記事でデザインチームの紹介です!お楽しみに!!