Cloud One File Storage Security拡張編:Amazon S3のマルウェアファイル検出時にSlack通知を行う

AWS

2024.3.6

Topics

はじめに

こんにちは、Shunです。

今回は、Cloud One File Storage Security(以降、C1FSS)を使用して、S3のマルウェアファイル検出時にSlack通知を行う方法をご紹介します。

Trend Micro Cloud One™ – File Storage Security は、 Amazon Web Services (AWS) Azureや GCPなどのクラウド ストレージ サービス内のファイルに対するマルウェア対策スキャンを提供します。

以下の記事では、C1FSSのセットアップについて取り上げました。

関連記事
Cloud One File Storage Securityを活用したAmazon S3マルウェアスキャンの手順

これまでのセットアップでは、アップロードされたファイルがマルウェアと判断された場合、そのファイルにタグが付けられるだけで、ユーザーへの通知は行われませんでした。

このため、異常なファイルがS3に残され、他のユーザーによってダウンロードされると、マルウェアが拡散するリスクが生じます。

そこで今回は、マルウェア検出時にすぐに対応ができるよう、Slackへ通知するための追加テンプレートのデプロイ方法をご紹介します。

以下が公式ドキュメントです。(検索後の処理内のプラグインに記載があります。)

公式ドキュメント: Sample code plugins

前提

  • Slackのワークスペースを保有していること
  • Terraformのセットアップが完了していること
  • C1FSSのセットアップが完了していること

構成図

以下の構成図では、赤枠で囲まれた箇所が今回追加で構築する箇所です。

実装手順

1. GitHubから追加テンプレートのダウンロード

まず、GitHubから追加テンプレートをダウンロードします。

C1FSSのセットアップではCloudFormationがテンプレートとして用意されていましたが、Slack通知の追加テンプレートはTerraformとして用意されています。

cloudone-filestorage-plugins/post-scan-actions/aws-python-slack-notificationディレクトリ配下のファイルを使用します。

テンプレート: Post Scan Action – Slack Notification

2. Slackアプリの作成

次に、Slack通知を行うためのアプリを作成します。

以下へアクセスします。

まず、「Create New App」を選択します。

次に、「From scratch」を選択します。

「App Name」には任意の名前を、「Pick a workspace」には通知させたいチャネルがあるワークスペースを選択します。

アプリ作成後、「Incoming Webhooks」を有効にします。

上部のボタンを「On」にし、下部の「Add New Webhook to Workspace」を選択します。

ワークスペースとの連携画面へ遷移し、通知を飛ばすチャネルの選択を行います。

これでWebhook URLが発行されます。

3. 追加テンプレートのデプロイ

これで、追加テンプレートのTerraformへ入力する値が揃いました。

post-scan-actions/aws-python-slack-notification/terraform/variables.tfを適宜書き換えてください。

post-scan-actions/aws-python-slack-notification/terraform/slack.tfvarsは使用しないため削除しても大丈夫です。)

# Configure the variables here
variable "region" {
  type = string
  description = "AWS region"
  default = "[デプロイ対象のリージョン]"
  validation {
    condition     = can(regex("[a-z][a-z]-[a-z]+-[1-2]", var.region))
    error_message = "Must be valid AWS Region names."
  }
}

variable "scan_result_topic_arn" {
  type = string
  default = "[C1FSSのデプロイ時にCloudFormaitonから出力されたScanResultTopicARN]"
  description = "The ARN of the scan result SNS topic in storage stack."
}

variable "slack_webhook_url" {
  type = string
  default = "[作成したWebhook URL]"
  description = "The URL of the Slack Webhook."
}

variable "slack_channel" {
  type = string
  default = "[通知先のチャネル]"
  description = "The name of the Slack channel."
}

variable "slack_username" {
  type = string
  default = "[作成したSlackアプリ名]"
  description = "The username of the Slack notification."
}

これで準備は完了となるので、デプロイを行います。

$ terraform init
$ terraform fmt
$ terraform plan
$ terraform apply

4. Slack通知の検証

実際にSlackへどのような通知がされるのかを見ていきます。

テストのために、EICARファイルを以下からダウンロードします。

EICAR テストファイルは、脅威(ウイルス / マルウェア)ではなく、ウイルス対策ソフト上で脅威の検知を模擬するために作成された、拡張子が .COM 形式の 68 バイトのファイルです。

引用: EICAR テストファイルとは?

S3へ配置してみると、Slackへ以下のような通知が届きます。

これでS3へマルウェアファイルがアップロードされたことに対して、すぐに対処ができるようになります。

通知内容はLambda内で定義されているため、必要に応じてカスタマイズも可能です。

import urllib3
import json
import os
http = urllib3.PoolManager()
import textwrap

def lambda_handler(event, context):

    url = os.environ['SLACK_URL']
    channel = os.environ['SLACK_CHANNEL']
    username = os.environ['SLACK_USERNAME']

    for record in event['Records']:

        #Message details from SNS event
        message = json.loads(record['Sns']['Message'])
        findings = message['scanning_result'].get('Findings')

        #ARN info to get AWS Account ID
        arn = json.dumps(record['EventSubscriptionArn'])
        account_id = arn.split(":")[4].strip()

        if findings:

            malwares = []
            types = []
            for finding in message['scanning_result']['Findings']:
                malwares.append(finding.get('malware'))
                types.append(finding.get('type'))

            body_text = textwrap.dedent('''
            WARNING
            AWS Account ID: {account}
            File URL: {file_url}
            Malware Name(s): {malwares}
            Malware Type(s): {types}
            ''').format(
            account=str(account_id),
            file_url=str(message['file_url']),
            malwares=', '.join(malwares),
            types=', '.join(types)
            )

            payload = {
                        "channel": channel,
                        "username": username,
                        "text": body_text,
                        "icon_emoji": ":rotating_light:"
                        }

            encoded_msg = json.dumps(payload).encode('utf-8')
            resp = http.request('POST',url, body=encoded_msg)

さいごに

今回紹介した追加テンプレートを使用することで、異常なファイルがS3にアップロードされた際に即座に警告を受け取ることができます。

他の追加テンプレートについても、今後別の記事でご紹介したいと思います。

最後まで読んでいただきありがとうございます!

Shun

好きな言葉は生ビール199円です。日本ビール協会認定1冠、AWS12冠、Google Cloud11冠

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら