Cloudflare Zero TrustのログをGoogle Cloud StorageにプッシュしBigQueryで解析する
はじめに
WED株式会社で情報システムを担当しているsaitosnです。
当社ではCloudflareを活用し、Zero Trustを使って社用端末のネットワークセキュリティを強化しています。
本記事では、Zero Trustで収集したログをGoogle Cloud Storage(以下GCS)にプッシュし、BigQueryで解析する方法をご紹介します。
DNSログを活用してユーザーが利用しているAIサービスを可視化し、未許可のサービス(シャドーIT)の実態を把握してみます。
なぜLogpushが必要か
Cloudflare Zero Trustのログ管理には、以下の課題があります。
保存期間の制限: GatewayログはStandardプランで30日間、Enterpriseプランでも180日間しか保存されない
検索性の課題: 大量のログから必要な情報を効率的に抽出することが困難
これらの課題を解決するため、Logpushを活用してログを外部ストレージに保存し、分析基盤を構築することにしました。
Logpushの種類
2025年5月現在、Logpushは以下のサービスに対応しています。
- Cloudflare R2
- Amazon S3
- Google Cloud Storage
- Sumo logic
- Microsoft Azure
- Datadog
- Splunk
- New Relic
- S3互換
- HTTP送信
今回はGoogle Cloud Storageを選択しました。
事前準備
- Google Cloudプロジェクトの作成
- Cloud Storageの有効化
- ログ保存用バケットの作成
CloudflareでLogpushを設定する
詳細な手順はGoogleCloudの公式ドキュメントを参照していただくとして、特に重要なポイントを解説します。
- Cloudflareにログインし、左サイドバーの[分析とログ]から[Logpush]を選択する
- [Logpushジョブを作成する]をクリック
- LogPush先のサービスとしてGCSを選択
- 事前準備で作成したバケット名と、ログを格納するフォルダ名を入力する
- GCSのバケットの権限を付与する必要があるため、サービスアカウントを登録します。
5-1. GCSにアクセスし、バケットを開く
5-2. [権限]タブを開き、[Grant access]をクリック
5-3. [新しいプリンシパル]に手順4の画面に表示されていたサービスアカウントを入力
5-4. [ロール]でStorageオブジェクト管理者を選択し、保存する
- データセットにて[ゲートウェイ DNS]を選択する
- [ジョブ名]を入力し、プッシュしたいログについて選択して保存する
- 今回はすべてのログ、すべてのフィールドを取得しています。
- DNSログですべてのログを出力すると当社の場合は50デバイスで1日232MiBほどでした
利用者数が多い場合は、フィルタリングを利用して保管するデータ容量を減らすことで、費用を削減した方が良いかもしれません
- Logpushのページにデータセットが表示されたら完了
BigQueryでの分析環境構築
json形式で保存されたログをBigQueryで分析するため、外部テーブルを作成します。
事前準備
- GCSの対象のバケットのgsutilURIを取得する(バケットの構成タブで確認可能)
- BigQueryを有効にする
- データセットを作成しておく
GCSのログをテーブルに変換する
- BigQueryを開き、作成したデータセットをクリックする
- SQLクエリを開き以下のクエリを実行する
CREATE OR REPLACE EXTERNAL TABLE `データセット名.テーブル名`
OPTIONS (
format = 'JSON',
uris = ['gsutilURI/ログ格納先フォルダ名/*.log.gz'],
compression = 'GZIP'
);
- データセット内に指定したテーブル名のテーブルが作成されることを確認する。
実際にSQLで一番アクセスされてるドメインを確かめてみる
まず、基本的な分析として、2025年5月27日のログを使ってアクセス数の多いドメインを確認してみました。
実行したクエリ
SELECT
QueryName,
ApplicationName,
COUNT(*) as query_count,
FROM `データセット名.テーブル名`
GROUP BY QueryName, ApplicationName
ORDER BY query_count DESC
LIMIT 10
QueryName | ApplicationName | query_count |
---|---|---|
ssl.gstatic.com | Google (Do Not Inspect) | 29,915 |
signaler-pa.clients6.google.com | Google Services (Do Not Inspect) | 24,777 |
play.google.com | Google Play Store (Do Not Inspect) | 21,915 |
slack.com | Slack | 21,157 |
waa-pa.clients6.google.com | Google Drive | 18,751 |
www.notion.so | Notion (Do Not Inspect) | 18,282 |
edgeapi.slack.com | Slack | 18,045 |
calendar.google.com | Google Calendar | 16,455 |
api2.cursor.sh | - | 16,053 |
www.google.com | Google Drive (Do Not Inspect) | 14,899 |
結果は当社がメインで利用しているGoogle Workspace、Slack、Notionといった業務ツールが上位を占めました。
唯一その三つに含まれないのがapi2.cursor.sh
AIコードエディタであるCursorのドメインでした。
一番使われているAIツールを洗い出してみる
次に、社内で利用されているAIサービスを特定するため、主要なAIサービスのドメインパターンでフィルタリングしました。
といっても、ドメイン名は手打ちするしかないので、かなり面倒です。
蛇の道は蛇ということで、今回はAIにAIサービスのドメインの一覧を出してもらい、一致したものを抽出しました。
そのため、抜けてるものやAIでないものも含まれていますのでご了承ください。
WITH ai_tools_domains AS (
SELECT
-- メインドメインを抽出
REGEXP_EXTRACT(QueryName, r'^(?:.*\.)?([^.]+\.[^.]+)$') as main_domain,
QueryName as original_query,
Email,
Datetime
FROM `データセット名.テーブル名`
WHERE REGEXP_CONTAINS(QueryName, r'(?i)(openai|chatgpt|anthropic|claude|gemini|bard|copilot|perplexity|poe\.com|character\.ai|replika|chai\.ml|janitor\.ai|meta\.ai|llama|cursor|codeium|tabnine|replit|codex|kite|sourcegraph|supermaven|continue\.dev|aider|v0\.dev|bolt\.new|windsurf|midjourney|stability|stablediffusion|dall-e|leonardo\.ai|runwayml|clipdrop|playground\.ai|nightcafe|artbreeder|deepai|imagine\.art|craiyon|bluewillow|tensor\.art|picso|elevenlabs|murf\.ai|speechify|resemble|suno|udio|boomy|soundraw|voicemod|replica|jasper|copy\.ai|writesonic|rytr|grammarly|quillbot|notebooklm|gamma\.app|tome\.app|beautiful\.ai|designs\.ai|wordtune|hypotenuse|you\.com|phind|devv|consensus|elicit|scholarai|semantic-scholar|synthesia|d-id|heygen|fliki|pictory|luma\.ai|pika\.art|viggle|huggingface|replicate|cohere|together\.ai|fireworks|anyscale|modal|runpod|banana|cerebrium)')
)
SELECT
main_domain,
COUNT(*) as total_queries,
COUNT(DISTINCT Email) as unique_users,
STRING_AGG(DISTINCT original_query ORDER BY original_query LIMIT 10) as subdomain_variations
FROM ai_tools_domains
GROUP BY main_domain
ORDER BY total_queries DESC
LIMIT 100
抽出されたクエリに対して、AIじゃないものを削除した結果が以下になりました。
ついでにAIにサービス概要と用途を追加してもらっています。
順位 | サービス名 | アクセス数 | ユーザー数 | サービス概要 | 主な用途 |
---|---|---|---|---|---|
1 | Cursor.sh | 25,796 | 8 | AIコードエディタ | AIペアプログラミング、コード生成 |
2 | ChatGPT.com | 2,667 | 18 | OpenAI対話型AI | 汎用AIチャット |
3 | Anthropic.com | 1,547 | 12 | Claude AI開発元 | AI API、コンソール |
4 | OpenAI.com | 1,276 | 9 | ChatGPT/GPT開発元 | AI API、認証 |
5 | GitHub Copilot | 1,063 | 9 | AIコード補完 | IDE統合コード支援 |
6 | Claude.ai | 637 | 11 | Anthropic対話型AI | AIチャット |
7 | Gamma.app | 565 | 1 | AIプレゼン作成 | スライド自動生成 |
8 | Google.com | 277 | 14 | Gemini,NotebookLM 含む | Gemini AI、AI Studio、NotebookLM |
9 | Huggingface.co | 166 | 6 | AIモデルハブ | オープンソースAIモデル |
10 | Perplexity.ai | 163 | 2 | AI検索エンジン | AIパワード検索 |
11 | Sourcegraph.com | 111 | 2 | AIコード検索 | コードベース分析 |
12 | Ollama.com | 21 | 2 | ローカルLLM実行 | オープンソースAI実行環境 |
13 | Bolt.new | 2 | 1 | AI Webアプリ生成 | フルスタック開発 |
アクセス数で見てみるとCursorが1番でした。
ユーザー数は8名にも関わらず、AIエージェントなだけあって通信の回数が尋常じゃないですね。
今現在、情シスが把握している当社のAIツールは以下になります。
- Cursor
- ChatGPT , OpenAI API
- Claude , Anthropic API
- Google , Gemini , NotebookLM
- Huggingface
- Perplexity
実際に見てみると、会社として把握しているAIツール以外にも、Gamma.app(プレゼン作成)やSourcegraph(コード検索)などが利用されていることがわかりました。
セキュリティとコンプライアンスの観点から
上記の分析により、以下の対応が可能になりました。
- シャドーITの早期発見
- SaaS利用状況の可視化
- データに基づいたセキュリティポリシーの策定
ただし、アクセスログの取り扱いには十分な注意が必要です。
当社では、基本的に部署やチーム単位での傾向分析に留め、個人の特定はセキュリティインシデント対応時のみに限定しています。
プライバシーに配慮し、業務上必要な範囲での利用に留めましょう。
まとめ
Cloudflare Zero TrustのLogpush機能とBigQueryを組み合わせることで、以下を実現できました!
- 長期的なログ保存: 30日の制限を超えた分析が可能に
- 高度な分析環境: SQLによる柔軟なデータ分析
- シャドーITの可視化: DNSログから未把握のサービス利用を発見
- データドリブンな意思決定: 実際の利用状況に基づいたセキュリティポリシー策定
情シス担当者として、限られたリソースで効果的なセキュリティ管理を実現するには、様々なサービスのデータ活用が不可欠です。Zero Trustの導入を検討している方、ログ分析基盤の構築を考えている方の参考になれば幸いです。
なお、今回の分析はDNSログに限定しましたが、HTTPログやNetworkログも同様に分析可能です。
ニーズやリソースに応じて、ぜひ試してみてください。
Discussion