Dify と Amazon Bedrock を使って、簡単にセキュリティオペレーション自動化 ~ Amazon GuardDuty 検知結果の自動解析を例に ~
2024-09-03 | Author : 小笠原 清志 (株式会社サイバーエージェント)
セキュリティオペレーションの自動化実現には LLM の相性が良い
こんにちは。サイバーエージェントのシステムセキュリティ推進グループの小笠原と申します。
私は普段、セキュリティ部署の技術チームに所属しインハウスのセキュリティエンジニアとしてセキュリティ対応を行っています。技術チームではテクノロジーを駆使して、セキュアな開発環境の構築・提供や、オペレーションの自動化を行っています。
昨今、LLM の進歩によりセキュリティオペレーションの自動化がさらに加速しています。
AWS では Amazon GuardDuty などの既存のセキュリティサービスと Amazon Bedrock の生成 AI サービスを組み合わせることで、セキュリティオペレーションの自動化を効率よく実現することができるようになりました。
去年 ~ 今年にかけて LLM の周辺ツールがますます充実したことで、LLM のテクノロジーがさらに使いやすくなってきました。
今回は Dify というツールを使い、ほぼノーコードでセキュリティオペレーションの自動化を実現していきます。
オペレーション自動化の変化
 
 
                    
                 ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。
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.12-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 には複数のサービスが含まれていることがわかります。 今回は利用しないサービスもありますが、それぞれのサービスの役割・特徴は以下のようになります。 ベクトルストアは weaviate がデフォルトで利用できますが、他の OSS を選択することも可能です。
$ docker compose ps --services
api       # バックエンドのAPI(Python)
db        # DB(PostgreSQL)
nginx     # nginx(リバースプロキシ)
redis     # Redis
sandbox
ssrf_proxy 
weaviate   # ベクトルストア(他のOSSを選択可能)
web        # フロントエンド(Next.js)
worker     # ワーカー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 を作成
ALB を作成します。
- リスナーは https(443) を、転送先のターゲットグループは先程作成したものを指定 
                    - 証明書等の設定など詳細は 公式ドキュメント を参照
 
- 適切なセキュリティグループを指定 
                    - https(443) を許可するセキュリティグループを指定
- IP 制限をかける場合はここで設定 (オプション)
 
- リスナールールを追加 
                    - ここで認証の設定も可能 (オプション)
 
- その他は基本的にデフォルトのまま 
                    - Amazon VPC とサブネットは今回使用しているものを指定
 
 
- Amazon VPC とサブネットは今回使用しているものを指定
 
 
                管理者ユーザーを作成
Dify の管理コンソールにアクセスしてみましょう。以下の URL にアクセスして管理者ユーザーを作成してください
https://{ALB の DNS 名または IP アドレス}/install
カスタムのドメインを使用する場合は、別途 AWS Certificate Manager, Amazon Route53 (DNS) などの設定が必要です。
管理者ユーザーの作成が完了したらログインしてください。
  
 
 
                3. Dify の設定とワークフロー構築
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 のモデル設定
 
 
                Amazon Bedrock のセットアップ
 
 
                Anthropic Claude 3.5 Sonnet を入力
 
 
                システムモデル設定
最後に、システムモデル設定で 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 ファイルをダウンロードします。
 
 
                GuardDuty の Finding に関するドキュメントをアップロード
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 関数を選択
- ターゲットで先程作成した 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 の作成、リカバリーや封じ込めの対応なども柔軟に行うことができそうです。
まずはみなさんのセキュリティ業務で特に頻度が高く負担になっているところからワークフロー作成を検討してはいかがでしょうか。
筆者プロフィール
小笠原 清志
株式会社サイバーエージェント
システムセキュリティ推進グループ
2017 年に株式会社サイバーエージェントに入社。セキュリティエンジニアおよびソフトウェアエンジニアとして、プロダクトのセキュリティに関するコンサルティングとソフトウェア開発を担当。現在はセキュリティグループのエンジニアリング組織マネージャとして、OSS や社内のセキュリティプロダクトの開発に携わりながら、組織のセキュリティ強化に取り組んでいる。
 
 
                Did you find what you were looking for today?
Let us know so we can improve the quality of the content on our pages