Dify と Amazon Bedrock を使って、簡単にセキュリティオペレーション自動化

~ Amazon GuardDuty 検知結果の自動解析を例に ~

2024-09-03
デベロッパーのためのクラウド活用方法

Author : 小笠原 清志 (株式会社サイバーエージェント)

セキュリティオペレーションの自動化実現には LLM の相性が良い

こんにちは。サイバーエージェントのシステムセキュリティ推進グループの小笠原と申します。

私は普段、セキュリティ部署の技術チームに所属しインハウスのセキュリティエンジニアとしてセキュリティ対応を行っています。技術チームではテクノロジーを駆使して、セキュアな開発環境の構築・提供や、オペレーションの自動化を行っています。

昨今、LLM の進歩によりセキュリティオペレーションの自動化がさらに加速しています。

AWS では Amazon GuardDuty などの既存のセキュリティサービスと Amazon Bedrock の生成 AI サービスを組み合わせることで、セキュリティオペレーションの自動化を効率よく実現することができるようになりました。

去年 ~ 今年にかけて LLM の周辺ツールがますます充実したことで、LLM のテクノロジーがさらに使いやすくなってきました。
今回は Dify というツールを使い、ほぼノーコードでセキュリティオペレーションの自動化を実現していきます。


1. 完成図

構築する仕組みは以下のような構成になります。仕組み全体の流れと、アーキテクチャを下記の図に示します。

画像をクリックすると拡大します

  • Difyサーバーの構築
    • Dify を使ってセキュリティオペレーションのワークフローを作成します
    • ワークフロー内では、Amazon Bedrock を使って生成 AI で処理を実行します
    • サーバー構築ではコンテナイメージが提供されているのでそれらを起動するのみです
  • Amazon GuardDuty のセキュリティイベントを解析
    • 今回は脅威検知の解析を自動化します
    • セキュリティの専門知識がない人でも分かりやすく状況把握できるものを目指します
  • Amazon Bedrock を使って LLM の API を呼び出す
    • Bedrock の API を呼び出すには通常、Dify サーバーに IAM ユーザーのキーを登録する必要があります
    • しかし、今回は Amazon EC2 に IAM ロールを割り当てることで、IAM ユーザーを作成する必要がなくなりセキュアになります

2. Dify サーバーの構築

まずは、メインとなる Dify サーバーを構築します。

今回は自身の AWS アカウントで Dify サーバーをホストしますが、SaaS サービスとしても提供されていますので、SaaS 利用が可能であればさらにお手軽に環境を用意できます。
ただし、セキュリティオペレーションで扱われるデータはセンシティブなものも含まれる可能性があるため、自分たちの環境にホストする方法をご案内します。

2-1. Amazon EC2 インスタンス作成

Dify に求められる CPU、MEM の要件に注意しつつ、以下のようなインスタンスを作成します。

  • AMI : Amazon Linux 2023
  • Instance type : t3.medium (2vCPU, 4GB MEM が必要)
  • セキュリティグループ : インバウンドルールに HTTP(80) を追加
    • 必要に応じてソース ip の制限等を設定
    • 後に Application Load Balancer (ALB) を利用するため、その際には ALB のセキュリティグループからのみ通信を制限するように設定
  • その他は任意です

2-2. docker install

EC2 インスタンスが作成できたらコンテナを実行するための docker をインストールします。

$ sudo dnf install docker git
$ sudo usermod -a -G docker ssm-user # またはec2-user
$ sudo systemctl enable docker
$ sudo systemctl start docker
$ docker -v
Docker version 25.0.3, build 4debf41

# ここで一度ログアウトして、再度ログインする。(グループが反映されてdockerコマンドが使えるようになる)

2-3. docker compose install

Dify は docker compose を使ってコンテナを実行できます。
最新のインストール方法は 公式ドキュメント を参照してください。

$ DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
$ mkdir -p $DOCKER_CONFIG/cli-plugins
$ curl -SL https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
$ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
$ docker compose version
Docker Compose version v2.29.1

2-4. Dify サーバーの立ち上げ

Dify は OSS として公開されていますので、GitHub から ソースコード をダウンロードし、サーバーを立ち上げます。

$ git clone https://github.com/langgenius/dify.git
$ cd dify/docker
$ cp .env.example .env
$ docker compose up -d

Dify には複数のサービスが含まれていることがわかります。
今回は利用しないサービスもありますが、それぞれのサービスの役割・特徴は以下のようになります。

$ docker compose ps --services
api       # バックエンドのAPI(Python)
db        # DB(PostgreSQL)
nginx     # nginx(リバースプロキシ)
redis     # Redis
sandbox
ssrf_proxy 
weaviate   # ベクトルストア(他のOSSを選択可能)
web        # フロントエンド(Next.js)
worker     # ワーカー

ベクトルストアは weaviate がデフォルトで利用できますが、他の OSS を選択することも可能です。

2-5. Dify サーバーへのアクセスコントロール

ここまでで、Dify サーバーの立ち上げは完了です。

デフォルトでは https でのアクセス (通信の暗号化) は対応していません。お使いの環境にあわせていくつかの選択肢があります。

  • Dify 内の nginx 設定を修正して直接 SSL/TLS 終端する
  • ALB を使って SSL/TLS 終端してから Dify サーバーにルーティングする
  • VPN で内部ネットワークにトンネルして http でアクセスする

今回は ALB を使う手順を記載します。ALB 側で IP アドレス制限や OIDC 認証 (Amazon Cognito など) を挟むことができます。また、 Dify サーバーをプライベートサブネットに配置すれば直接インターネットフェーシングにせずに済むため、サーバーの脆弱性リスクを軽減できます。

画像をクリックすると拡大します

2-5-1. Application Load Balancer の作成

まずはターゲットグループを作成します。

ターゲットの種類は「インスタンス」を指定し、次ページで先ほど作成した EC2 インスタンスをチェックしてターゲットに登録

画像をクリックすると拡大します

ヘルスチェック設定は以下を指定

  • パス : /signin
  • ステータス : 200

画像をクリックすると拡大します

ALB を作成します。

  • リスナーは https(443) を、転送先のターゲットグループは先程作成したものを指定
  • 適切なセキュリティグループを指定
    • https(443) を許可するセキュリティグループを指定
    • IP 制限をかける場合はここで設定 (オプション)
  • リスナールールを追加
    • ここで認証の設定も可能 (オプション)
  • その他は基本的にデフォルトのまま
    • Amazon VPC とサブネットは今回使用しているものを指定

画像をクリックすると拡大します

Dify の管理コンソールにアクセスしてみましょう。以下の URL にアクセスして管理者ユーザーを作成してください

https://{ALB の DNS 名または IP アドレス}/install

カスタムのドメインを使用する場合は、別途 AWS Certificate Manager, Amazon Route53 (DNS) などの設定が必要です。

管理者ユーザーの作成が完了したらログインしてください。
 

画像をクリックすると拡大します


3. Dify の設定とワークフロー構築

Dify サーバーが構築できたら Amazon Bedrock を利用できるように準備します。

3-1. モデルの有効化

リージョンは任意ですが、今回は バージニア(us-east-1) で有効化の設定を行います。
LLM 界隈はアップデートが激しく最新の LLM モデルを利用するにはバージニアまたはオレゴンで有効化しておくとすぐに利用できる可能性が高まります。

今回は以下の 2 つのモデルを有効化しました。

  • Amazon Titan Embeddings G1 - Text (ベクトル検索で利用)
  • Anthropic Claude 3.5 Sonnet (チャットやテキスト生成で利用)

※ 2024 年 8 月 7 日に Anthropic Claude 3.5 Sonnet が東京リージョンで利用可能になりました。今回用いるモデルはいずれも東京で利用可能です。

画像をクリックすると拡大します

3-2. Amazon Bedrock の設定

Dify サーバーから Amazon Bedrock を呼び出すための権限を設定します。
以下のポリシーで IAM ロールを作成し、Dify サーバー (EC2) にロールを割り当てます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "bedrock:InvokeModel*",
            "Resource": [
                "*"
            ]
        }
    ]
}

3-3. Dify のモデル設定

Dify のコンソール画面にログインして右上のメニューから「設定」を選択します。

画像をクリックすると拡大します

設定画面の「モデルプロバイダー」メニューを開き、Amazon Bedrock を探し「セットアップ」を選択します。

画像をクリックすると拡大します

先ほど有効化したモデル anthropic.claude-3-5-sonnet-20240620-v1:0 を入力し保存を選択します。ここで利用可能な状態になっているかがチェックされます。

画像をクリックすると拡大します

最後に、システムモデル設定で Claude 3.5 Sonnet と amazon.titan-embed-text-v1 を選択し「保存」を選択します。

画像をクリックすると拡大します

ここまでで Dify から Amazon Bedrock を利用できるようになりました。

3-4. ナレッジの登録

Amazon GuardDuty の Finding を LLM で解説させるために、公式のドキュメントをナレッジとして登録します。ナレッジを利用すると RAG という手法で LLM にコンテキストを与えることができます。これにより、より具体的で正確な回答を得ることができます。

こちら から PDF ドキュメントをダウンロードしてください。

もし、最新のドキュメントを取得したい場合は、以下の 2 つの URL にアクセスし、印刷 > PDF に保存 で PDF ファイルをダウンロードします。

画像をクリックすると拡大します

Dify のナレッジメニューで「知識を作成」を選択して、ダウンロードした GuardDuty の Finding に関するドキュメント (2 つの PDF ファイル) をアップロードし、次に進みます。

画像をクリックすると拡大します

ナレッジの作成設定で、「質問と回答形式でセグメント化(使用言語: 日本語)」を有効にしてナレッジ作成を実行します。

画像をクリックすると拡大します

この設定でナレッジを作成する場合かなり時間がかかってしまいます。ただ、ナレッジ作成においては適切なチャンキング処理 (ドキュメントの分割) が非常に重要で、目的のデータをコンテキストに含めることができるかがポイントになります。(RAG と言われる手法)

チャンク分割の処理は自前で実装しようと思うと大変ですが、Dify 側で良い感じに処理してくれます。この辺りは細かい機能なのですが、実運用に必須な機能を提供してくれる点も非常にパワフルなツールだということがわかります。

ここは多少お金と時間がかかってしまいますが、我慢して待ちます。

3-5. ワークフローを作成

いよいよ、セキュリティオペレーションの自動化 = ワークフロー定義の作成に入ります。

3-5-1. DSL ファイルのインポート

ワークフローを一から作るのではなく、事前に用意させてもらった DSL ファイルをインポートし、自身の環境に合わせて少し修正します。

こちら から DSL ファイルをダウンロードしてください

メニューから スタジオ 画面に遷移し「DSL ファイルをインポート」を選択して先ほどダウンロードした DSL ファイルをアップロードしてください。

画像をクリックすると拡大します

3-5-2. ワークフローの修正

インポートが完了すると GuardDutyHandler というワークフローが作成されます。しかし、このままではワークフローを実行することができません。以下の 2 点を修正します。

  • ナレッジを選択する
  • 通知先の Slack webhook URL を設定する

画像をクリックすると拡大します

3-5-3. ワークフローのテスト

ワークフローのテストは右上の「実行」から行うことができます。

以下の必須パラメータを設定して実行します。

  • finding : テスト用の JSON ファイルを指定
  • type : GuardDuty の Finding タイプを指定
  • severity : 1.0 ~ 8.0 の数字を指定

成功すると指定した Slack チャンネルに以下のような通知が飛んできます。

画像をクリックすると拡大します

ダミーのデータになりますが、GuardDuty の Finding を解説し、次に何をすべきかをユーザーに通知することができました。これを見ればセキュリティの専門家でなくても状況を把握できるようになります。

3-5-4. ワークフローの公開

設定が完了したら、右上の「公開する」を選択してください。

3-5-5. API からワークフローを実行できるようにする

ワークフローが作成できたら、API から実行できるようにします。

API を有効にするには、左メニューの APIアクセス 画面に遷移して、APIキー を生成してください。

画像をクリックすると拡大します

API キーを使って以下のようなリクエストでワークフローを実行することが可能になります。

curl -X POST "http://${HOST}/v1/workflows/run" \
--header "Authorization: Bearer ${API_KEY}" \
--header 'Content-Type: application/json' \
--data-raw '{
    "inputs": {
      "type": "Recon:EC2/PortProbeUnprotectedPort",
      "severity": 4.0,
      "finding": "{...}",
    },
    "response_mode": "blocking",
    "user": "alice"
}'

4. Amazon GuardDuty と Dify のワークフロー連携させる

最後に、Amazon GuardDutyの イベントを Dify のワークフローに連携させます。
以下のような構成で Dify のワークフローを呼び出すことにします。

Amazon GuardDuty → Amazon EventBridge → AWS Lambda → Difyワークフロー(API)

  • GuardDury を有効化します
  • Amazon EventBridge のルールを作成し AWS Lambda 関数を呼び出すように設定します
  • Lambda 関数内で、GuardDuty の Finding イベントを取得、パースして Dify の API にリクエストを送信します
  • Dify がワークフローを実行し、解析結果がSlackに通知されます

この辺りの設定は今回の記事の趣旨から外れるため、ポイントを絞って記載します。

4-1. Lambda 関数を作成

EventBridge からイベントデータを受け取り、パースして Dify の API にリクエストを送信するための Lambda 関数を作成します。

  • 新規に Lambda 関数を作成します
    • 関数名は「AnalyzeGuardDuty」とします
    • ランタイムは「Python 3.11」を選択します
    • 適切な IAM ロールを設定します
  • Lambda コードは こちらのページ からダウンロードして、zip ファイルをアップロードしてください
  • Dify の API の接続先情報を環境変数に設定します
    • HOST : Dify サーバーの IP アドレス
    • API_KEY : 先ほど生成した Dify の API キー
  • その他 Lambda の設定
    • タイムアウトは 5 分程度に設定してください (LLM の処理に数十秒かかる可能性があるため)
    • Amazon VPC 設定で、Dify サーバーが配置されているサブネットにアクセスできるようにしてください
      • もし、Dify サーバーがインターネットからアクセスできる場合はこの設定は不要です

4-2. Amazon EventBridge のルールを作成

 

EventBridge のルール作成では、以下のように設定します。

  • 新規ルールの作成
  • イベントソースで「AWS のサービス」を選択
  • サービスで「GuardDuty」を選択
  • イベントタイプで「GuardDuty Finding」を選択
  • イベントパターンで以下を指定
{
  "source": ["aws.guardduty"],
  "detail-type": ["GuardDuty Finding"],
  "detail": {
    "severity": [{
      "numeric": [">=", 7]
    }]
  }
}
  • ターゲットで先程作成した Lambda 関数を選択

上記の設定では Severity 7 以上でフィルターしています。
全ての Finding データを LLM に解析させるとコストがかかってしまう可能性があるため、ここでフィルターの設定をいれておきます。

画像をクリックすると拡大します

最終的に AWS Lambda の画面で上記のようになっていれば設定完了です。

4-3. Amazon GuardDuty でサンプルのFindingを生成し一連のフローをテストする

それでは最後に全体を通してテストします。
今回はテストなので GuardDuty のサンプルの Finding を生成します。

  • Amazon GuardDuty の「設定」画面に遷移します
  • 「検出結果サンプルの生成」を選択します

画像をクリックすると拡大します

数分後に、GuardDuty のサンプルの Finding が生成されます。ワークフローが実行、Slack へ通知が届いたら成功です。

4-4. ワークフローのログを確認

ワークフローのログ画面で、どのようなデータが入って、途中のプロセスでどのような処理が行われたかを確認できます。

画像をクリックすると拡大します


5. おわりに

いかがでしたでしょうか。今回は GuardDuty のデータを処理しましたが、LLM を利用することでどんなセキュリティのイベントも解析が可能になります。(AWS CloudTrail やアクセスログなど)イベントログの解析だけでなく、レポート生成や Runbook の作成、リカバリーや封じ込めの対応なども柔軟に行うことができそうです。

まずはみなさんのセキュリティ業務で特に頻度が高く負担になっているところからワークフロー作成を検討してはいかがでしょうか。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

小笠原 清志
株式会社サイバーエージェント
システムセキュリティ推進グループ

2017 年に株式会社サイバーエージェントに入社。セキュリティエンジニアおよびソフトウェアエンジニアとして、プロダクトのセキュリティに関するコンサルティングとソフトウェア開発を担当。現在はセキュリティグループのエンジニアリング組織マネージャとして、OSS や社内のセキュリティプロダクトの開発に携わりながら、組織のセキュリティ強化に取り組んでいる。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する