セキュリティの一元化:ログの混乱から「シングルペイン・オブ・グラス」へ
セキュリティツールを実行することと、実際に安全であることは別物だということを、私は身をもって学びました。本番ノードの1つが深夜にSSHブルートフォース攻撃を受けた際、私の「セキュリティスタック」が単に読まれていないログの山に過ぎなかったことに気づいたのです。DockerイメージにTrivy、コードにSemgrep、ネットワークにNmapを使用しているなら、CI/CDパイプライン全体に散らばった、互換性のない3つのレポート形式を眺めていることでしょう。何が修正され、何が依然として脅威なのかを追跡することは、ロジスティクス上の大きな混乱を招きます。
DefectDojoはこのギャップを埋めてくれます。150以上のセキュリティスキャナーを標準でサポートし、洗練された情報集約拠点として機能します。15ものマイクロサービスを個別に監査する代わりに、インフラ全体の定義されたリスクプロファイルを1つの画面で確認できます。生のデータを、優先順位付けされた「ToDoリスト」へと変換してくれるのです。
クイックスタート(5分)
Docker Composeは、PostgreSQLやRedisの設定に苦労することなく、DefectDojoを立ち上げる最も確実な方法です。5分足らずで環境を準備できます。
1. クローンと起動
git clone https://github.com/DefectDojo/django-DefectDojo
cd django-DefectDojo
# セットアップスクリプトを実行
./dc-build.sh
./dc-up.sh postgres-redis
データベースのマイグレーションが完了するまで少し待ちます。docker-compose logs -f initializer を使用してログを確認してください。プロセスが終了すると、ランダムに生成された管理者パスワードが表示されます。これをすぐにコピーしてください。最初のログインで必要になります。
2. ダッシュボードへのアクセス
ブラウザで http://localhost:8080 にアクセスします。ユーザー名に admin、先ほど保存したパスワードを使用します。これで、エンタープライズ級の脆弱性管理プラットフォームがマシン上で稼働しました。
ディープダイブ:スキャナーの統合
DefectDojoはデータによって真価を発揮します。3つの主要なツールから結果をエクスポートし、正しく取り込む方法を見ていきましょう。
ステップ 1:Semgrep によるコードスキャン
Semgrepは、ソースコード内のハードコードされた認証情報やSQLインジェクションのリスクなど、安全でないパターンを特定します。スムーズにインポートするために、結果をJSON形式で出力する必要があります。
# リポジトリをスキャンしてJSON出力を保存
semgrep scan --json -o semgrep_results.json .
ステップ 2:Trivy によるコンテナスキャン
Trivyはコンテナセキュリティのゴールドスタンダードです。古いOSパッケージや(脆弱なバージョンのOpenSSLのような)脆弱性のある依存関係をフラグ立てします。
# コンテナイメージをスキャンし、JSONレポートを生成
trivy image --format json -o trivy_results.json my-app:latest
ステップ 3:Nmap によるネットワークスキャン
Nmapは、どのポートがインターネットに公開されているかを明らかにします。DefectDojoはNmapのXML出力を処理し、許可されていないサービスの変更を追跡するのに役立ちます。
# 特定のIP範囲をスキャンし、XMLとして保存
nmap -sV -oX nmap_results.xml 192.168.1.0/24
ステップ 4:検出結果(Findings)のインポート
DefectDojoは、**Product Type** → **Product** → **Engagement** というシンプルな階層を使用します。「Product」をアプリケーション、「Engagement」を「週次スプリントスキャン」のような特定のテストサイクルと考えてください。
- Product: プロジェクト名(例:「Fintech-API-v2」)
- Engagement: コンテキスト(例:「Q2 セキュリティ監査」)
- Test: 特定のスキャナー出力のコンテナ
Engagement内で **プラス (+)** アイコンをクリックし、**Import Scan Results** を選択します。「Trivy Scan」など対応するスキャナータイプを選択し、ファイルをアップロードすると、ダッシュボードが自動的に深刻度別に検出結果を分類します。
高度な使い方:パイプラインの自動化
手動アップロードは単発の監査には適していますが、スケールしません。有能なエンジニアは DefectDojo API を使用して、CI/CD プロセス中に結果を自動的にプッシュします。これにより、すべてのマージリクエストで新しい脆弱性がチェックされるようになります。
Python による自動化
UIの「User」セクションからAPIキーを取得します。以下のPythonスクリプトは、Semgrepレポートを特定のEngagementにプログラムでアップロードする方法を示しています。
import requests
DD_URL = "http://localhost:8080/api/v2/import-scan/"
API_KEY = "your_api_key_here" # ここにAPIキーを入力
ENGAGEMENT_ID = 1
headers = {"Authorization": f"Token {API_KEY}"}
files = {'file': open('semgrep_results.json', 'rb')}
data = {
'scan_type': 'Semgrep JSON Report',
'engagement': ENGAGEMENT_ID,
'active': True,
'verified': False
}
response = requests.post(DD_URL, headers=headers, data=data, files=files)
print("成功!" if response.status_code == 201 else f"エラー: {response.text}")
GitHub Actions との統合
ワークフローにセキュリティを直接組み込みます。以下のスニペットは、コードをプッシュするたびに Trivy を実行し、結果をダッシュボードにプッシュします。
- name: Trivy スキャンの実行
run: trivy image --format json -o trivy-results.json my-image:latest
- name: DefectDojo へのアップロード
run: |
curl -X POST "$DD_URL/api/v2/import-scan/" \
-H "Authorization: Token $DD_API_KEY" \
-F "[email protected]" \
-F "scan_type=Trivy Scan" \
-F "engagement=$DD_ENGAGEMENT_ID"
長期運用のための実践的なヒント
脆弱性ダッシュボードは、クリーンな状態を保ってこそ価値があります。ノイズを管理する方法を以下に示します。
重複排除(Deduplication)の活用
重複排除は DefectDojo の最も強力な機能です。同じイメージを毎日スキャンする場合、同じバグに対して30個の同一チケットは必要ありません。システム設定で重複排除を有効にすると、これらが1つの検出結果に集約され、問題が最初に確認された日時と最後に確認された日時が追跡されます。これにより、手動レビューの負荷を最大90%削減できます。
レビューワークフローの確立
スキャナーはしばしば誤検知(False Positive)を出します。レポートがインポートされると、検出結果は「Active」ですが未検証の状態になります。セキュリティ責任者は「High(高)」および「Critical(緊急)」の項目を確認し、正当な脅威を「Verified(検証済み)」としてマークする必要があります。環境に関係のない検出結果は「False Positive」としてマークし、メトリクスから除外しましょう。
SLA の遵守
DefectDojo を使用してサービスレベル合意(SLA)を追跡します。例えば、「Critical」な脆弱性は24時間以内にパッチを適用し、「Medium」な問題は14日間の猶予を持たせる、といった運用が考えられます。システムは期限切れの項目をハイライトするため、どのチームにサポートが必要か一目でわかります。このデータ駆動型のアプローチにより、チームを疲弊させることなく、高いセキュリティ基準を維持できます。
影響の大きい修正を優先する
「Critical」なものがなくなるまで、「Low」の検出結果は無視してください。ダッシュボードを使用して、複数の製品に共通する脆弱性を見つけましょう。1つの共有ライブラリの脆弱性を修正するだけで、5つや6つのマイクロサービスのセキュリティ負債が同時に解消されることもよくあります。

