Grafana Lokiによるログセキュリティ:5分でパスワードとAPIキーを自動マスキングする方法

Security tutorial - IT technology blog
Security tutorial - IT technology blog

「無害」なログに潜むリスク

console.logの設定ミスや、ログレベルをDEBUGにしたままにすることで、AWSのAPIキーやデータベースのパスワードがダッシュボード上に公開されてしまうことがあります。実際、大規模なデータ漏洩の多くは複雑な攻撃によるものではなく、DevOpsエンジニアが日常的に目にしているログから発生しています。

ログはデバッグのための共有リソースです。しかし、Grafanaへのアクセス権を持つ全員にプレーンテキストのパスワードが公開されている状態は、深刻な脆弱性です。ログ出力を禁止する(ほぼ不可能ですが)代わりに、Grafana Lokiに送信する直前のソースでデータマスキング(Data Masking)を行うのが最適な解決策です。

Grafana LokiにおけるPipeline Stagesの強力な機能

データを保存する前に処理を行うには、 Promtail または Grafana Alloy を使用します。これらのツールには非常に柔軟な pipeline_stages 機能が備わっています。これはスマートなフィルターのようなもので、入力されたログがルールに従って精査され、「クリーンな」データのみが次に送られます。

このツールセットの中で、 replace ステージは最も重要な要素です。正規表現(Regex)を使用して機密情報の形式に一致する文字列をスキャンし、それらを ********[MASKED] といった文字で上書きします。

実戦でのアドバイス: システムを構築する際、私は常に複雑なランダムパスワードを生成することを優先しています。よく利用するのは toolcraft.app/ja/tools/security/password-generator です。このツールはブラウザ上で完結して処理されるため、ネットワーク経由でパスワードが漏洩するリスクを回避できます。

実践:データセキュリティのためのPromtail設定

ステップ1:保護が必要なデータパターンの特定

まず、アプリケーションで頻繁に出現する機密データの形式をリストアップします。一般的には以下のようなものが含まれます:

  • 環境変数: DB_PASSWORD=admin123
  • JSON構造: "api_token": "secret-key-99"
  • 認証ヘッダー: Authorization: Bearer xyz123

ステップ2:promtail-config.yamlの設定

以下は、実際のプロジェクト向けに最適化した設定サンプルです。この pipeline_stages セクションを scrape_configs 内に追加してください。

scrape_configs:
- job_name: app_services
  static_configs:
  - targets:
      - localhost
    labels:
      job: nodejs_app
      __path__: /var/log/app/*.log

  pipeline_stages:
    # ステージ 1: クエリ文字列またはボディ内のパスワードを処理
    - replace:
        expression: "(?i)(password|passwd|pwd)=\"?([^\\s&;\"']+)\"?"
        replace: "$1=********"

    # ステージ 2: 特定形式のAPIキーを隠す(例:OpenAIやStripe)
    - replace:
        expression: "(sk-[a-zA-Z0-9]{20,})"
        replace: "[MASKED_KEY]"

    # ステージ 3: ヘッダー内のトークンを保護
    - replace:
        expression: "(?i)(Authorization: Bearer )([^\\s]+)"
        replace: "$1********"

技術的な注意点:

  • フラグ (?i) により、正規表現が大文字・小文字を区別しなくなるため、 Passwordpassword の両方を漏れなく処理できます。
  • replace 部分で $1 を使用することで、フィールド名は保持し、値のみを隠すことができます。

ステップ3:適用と確認

設定を反映させるために、Promtailサービスを再起動します:

sudo systemctl restart promtail

擬似的なログをシステムに流し込むことで、すぐにテストできます:

echo "Error: Connection failed for user=admin password=secret_pass" >> /var/log/app/test.log

Grafanaで確認すると、ログ行は安全に次のように表示されます: user=admin password=********

導入時の重要な注意点

1. CPUパフォーマンスの管理

すべてのログ行は保存前に正規表現フィルターを通過します。システムが1日に数百GBのログを出力する場合、複雑すぎる正規表現はCPU負荷を10〜15%増加させる可能性があります。パターンは可能な限りシンプルに保ちましょう。

2. インジェスト時(Ingest-time)かクエリ時(Query-time)か?

Grafanaでの閲覧時にLogQLを使ってデータを隠す方法を選ぶ人がいますが、これは致命的な間違いです。クエリ時に隠すだけでは、元のデータは依然としてLokiのデータベース内に存在します。ストレージに直接アクセスできる人なら誰でも読めてしまいます。必ずPromtail(インジェスト時)でマスキングを行ってください。

3. ステージの順序

アプリケーションが複数行のログ(Multiline)を出力する場合、 multiline ステージを replace よりも前に配置する必要があります。そうしないと、行をまたいだキーと値のペアがフィルターをすり抜け、機密情報が漏れてしまう可能性があります。

おわりに

ログのセキュリティは単なる技術的な問題ではなく、ユーザーへの責任であり法規制への準拠でもあります。わずか5分の設定で、法的なリスクや甚大なブランドダメージを回避できます。「泥棒を見て縄をなう」ことのないよう、今すぐロギングシステムを見直しましょう!

Share: