mcpField
A
anonymize-logs

anonymize-logs

github.com/elasticセキュリティ16511 回インストール5 週間前に更新
リポジトリ

anonymize-logs について

共有やコミットの前に、顧客提供のログファイルや単一行ログを匿名化するスキルです。識別につながる値を置き換えながら、元の構造と書式を維持します。

主な機能

  1. 01ログファイルと単一行ログの匿名化
  2. 02区切り文字・引用符・フィールド順の維持
  3. 03改行と入力形式の保持
  4. 04出現箇所を通じた置換の一貫性
  5. 05識別情報の置き忘れ確認

活用シーン

  1. 01共有用の顧客ログの準備
  2. 02ログサンプルのコミット前の識別情報削除

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/elastic/integration-skills --skill anonymize-logs

インストール後、Claude Code で/anonymize-logsを入力して読み込まれたか確認します。

詳細

ログの匿名化

顧客から提供されたログをサニタイズし、安全に共有またはコミットできるようにします。置き換えるのは識別情報のみです。元の構造、区切り文字、引用符、フィールドの順序、改行は保持してください。

入力はファイルでも、syslog/KV/NDJSON の単一行でもかまいません。出力は入力と同じ形式にしてください。サニタイズの一環として、整形、折り返し、切り捨て、値の「修正」を行わないでください。

提供するもの

入力提供方法
サニタイズするログファイルファイルに @ メンションするか、インラインで貼り付けます
出力先(任意)パスを自由に入力します。デフォルトでは同じディレクトリに .sanitized のサフィックスを付けて出力します
インプレースでの上書き(任意)元のファイルを上書きするには「in place」と入力します

鉄則 — 内容を再フォーマットしない

機密性の高い値のみを置き換えてください。それ以外には一切手を加えないでください。

パーサーやログを確認する人は、正確な空白、区切り文字、引用符、行構造に依存しています。

  • NDJSON(1 行につき JSON オブジェクト 1 つ):整形、再インデント、再構成を行わないでください。各行は 1 行のコンパクトな JSON オブジェクトのままにしてください。
  • Syslog/CEF/キーと値のログ:スペースの追加や削除、引用符の変更、フィールド順序の正規化を行わないでください。
  • 複数行のログ:行のグループ化を正確に保持してください。
  • 実在する人物、システム、組織を特定できる値のみを置き換えてください。フィールド名、区切り文字、構造上のトークンなど、それ以外はすべて一字一句そのまま保持してください。
  • syslog の PRI/RFC5424 ヘッダーを追加、削除、書き換えないでください。syslog らしく見せるために、PRI(または任意の PRI)を使って、ヘッダーのない行に <134> を付けないでください。
  • 切り捨ては匿名化の手段ではありません。 サニタイズを「完了」するために、繰り返されるフィールドを削除したり、末尾の KV ペアを落としたり、行の残りを切り取ったりしないでください。代わりに、2 パスのマップを使用してください。

ワークフロー

ステップ 1 — 2 パスでの置換

読み進めながら置換しないでください。異なる元の値が同じプレースホルダーに置き換わること、または最初に出現した箇所だけを置換し、後続のコピーが残ることは、どちらも失敗です。

  1. ファイルまたは行全体をスキャンして、機密トークン(ネストされたものも含む。URL クエリパラメーター、複合 ID 内の 16 進数の DWORD、パスセグメントなど)ごとに、対応表 元の値 → プレースホルダー を作成します。
  2. 元の値が異なる場合は、異なるプレースホルダーを割り当てる必要があります。同一の場合は、同じプレースホルダーを割り当てる必要があります。
  3. 対応表をグローバルに適用します(すべての出現箇所)。
  4. もう一度スキャンして、置換漏れがないか確認します(URL 内の IP アドレス、ベンダー ID 内の 16 進数形式の IP アドレス、製品名のように見えるホスト名など)。

最低限、次の項目を対象にします。

  • 認証情報:API キー、ベアラートークン、パスワード、OAuth トークン、Base64 エンコードされた認証情報、秘密鍵と証明書(PEM ブロック、SSH 秘密鍵)、TLS/SSH フィンガープリント(JA3/JA4 ハッシュ、SSH ホスト鍵フィンガープリント、証明書フィンガープリント)、DHCP フィンガープリント、不完全なシークレット(token_prefix、password_hash_prefix、hashed_token)。一部が露出しただけでも、認証情報が特定される可能性があります。
  • 個人識別情報:メールアドレス(CC/BCC リスト、代理人/所有者/作成者のメールアドレスに関する各種フィールドを含む)、ユーザー名、表示名、従業員 ID、電話番号、プリンシパル名(例:[email protected])、メールの件名と本文。
  • 組織識別情報:会社名、テナント ID(home_tenant_id、resource_tenant_id、aad_tenant_id の各種フィールドを含む)、アカウント ID、サブスクリプション ID、請求先アカウント ID、パスや JSON フィールドに埋め込まれた組織のスラッグ、組織単位のパス(例:orgunit_path、org_unit_path)、部署名と部署 ID、コストセンター ID、パイプ名、タスク名、レジストリパス内の Windows SID(セキュリティ識別子)。
  • インフラストラクチャ識別情報:内部ホスト名、FQDN、プライベート IP アドレス、MAC アドレス、内部 URL(ステージング/本番のホスト名、内部ツールドメイン)、クラウドリソース ID(ARN、S3 バケット名、GCP プロジェクト ID、Azure サブスクリプション名/リソース名)、Kubernetes クラスター名、ノード名、ポッド名、名前空間名、コンテナー名とコンテナー ID、データベースのホスト名と名前(database.host、database.name、database_principal_name を含む)、Windows ドメイントポロジーのフィールド(ドメインコントローラーのホスト名、NT ドメイン名、domain_controller_object_guid、domain_controller_object_sid)。
  • デバイスとハードウェアの識別情報:シリアル番号、ハードウェア UUID、マシン ID、デバイス UUID、特定のデバイス固有の BIOS/ファームウェアのバージョン文字列。device_id/serial/類似のフィールド内の値を含みます。
  • ファイルシステムパス:ユーザー名、組織名、内部システム構造が含まれるプロセスのコマンドライン、ファイルパス、レジストリキーのパス、ログファイルのパス(例:C:\Users\alice\、/home/bob/、HKLM\...\S-1-5-21-...)。
  • 接続文字列:データベース URI、Redis URL、認証情報や内部ホスト名を含むあらゆる接続文字列。
  • リソースの所有権:所有者のメールアドレス、作成者のメールアドレス、最終更新者の ID、代理ユーザーのメールアドレス、担当者のメールアドレス、偽装者フィールドなど、リソースに対する操作を行った特定の人物を示すあらゆるフィールド。
  • 追跡用識別子:セッション ID、リクエスト ID/相関 ID、トランザクション ID、または実在のエンティティに紐づく不透明な長い文字列。
  • ハッシュ値:機密情報から導出できる可能性がある場合は置き換えます(パスワードハッシュ、HMAC シークレットなど)。ファイルハッシュ(ファイル内容の MD5、SHA1、SHA256)や、その他のコンテンツアドレス可能な参照(Git SHA、識別子として使われる TLS 証明書ハッシュ)はそのまま残します。
  • 地理的な詳細情報:正確な GPS 座標、実在する住所。地理情報補完フィールドに含まれる都市名と国名は、通常そのまま残して問題ありません。インベントリまたはトポロジーフィールド内の都市/拠点トークン(場所の階層、ホスト名のビルコードなど)は識別情報として置き換えます。

以下のネストされた識別情報や複合識別情報も対象にします。

置換しながら、プレースホルダーの規則と形式ルール(以下を参照)を適用してください。

ネストされた識別情報と複合識別情報

見落としやすい項目です。URL 内、複合 ID 内、パスの各セグメントにネストされたトークンも含め、マップに追加してください。

16 進数の複合 ID に隠れた IPv4 アドレス。 ベンダー ID の中には、{0x00000001,0x1,0xcb007114,0x00000002} のようなものがあります。16 進数の dword が IPv4 アドレスである可能性があります(両方のエンディアンを試してください)。origin/src/dst の IP アドレスを置き換える場合は、各 dword を IPv4 アドレスとしてデコードしてください。どちらかのデコード結果が妥当なパブリック/プライベート IP アドレスで、置換済みの origin と一致しない場合は、その dword を origin に使用したものと同じドキュメント用 IP アドレスの 16 進数表記に置き換えてください(0x + 8 桁の 16 進数を維持してください)。周囲の {0x…,0x…} 形式は維持し、IP アドレスを含む dword だけを変更してください。例:0xcb007114 → 203.0.113.20(ビッグエンディアン)。origin を 198.51.100.10 に置き換えた場合は、0xc633640a を使用してください。

トポロジーを表すホスト名。 SW-BLDG-01、CHI-FW-01、DC1-VPN-MGMT は DNS 名ではありません。ホスト名/syslog ホスト/デバイス名のフィールドでは、サイト/役割/建物を示すコードを置き換えてください。%NAME-6-302018 のようなベンダー syslog のメッセージ IDは置き換えないでください。ホスト名ではなく、製品のニーモニックです。プレースホルダーには、元の長さの区分(短いトークンか FQDN か)に合わせて、host-1.example.local または example-fw-01 を使用してください。

ポリシー/ACL/アクセスグループ名。 ポリシー、ACL、アクセスグループの値では、日付のような \d{8,14} の連続部分を、同じ桁数の 20240101000000 に置き換えてください。vs\d+ は vs01 に置き換えるか、vs/日付の接尾辞を削除して example-policy にしてください。名前に含まれる VLAN 番号は vlan100 に置き換えてください。トークンの種類(ポリシー名らしさ)は維持してください。例:vlan200-20240115103000 → vlan100-20240101000000。

インターフェース名。 ethN-MM.VLAN は eth1-01.100 に置き換えてください(eth とドット付きのサブユニット形式を維持してください)。IF-<org>-…/場所を表す語は IF-Example に置き換えてください(IF- 接頭辞がある場合は維持してください)。汎用的な inside/outside/lan/wan は、サイト名ではなくインターフェースの役割を表す場合はそのままでもかまいません。そのトークンが顧客のサイト名または組織名の場合は、置き換えることを優先してください。

組織単位を含む Windows/SMB パス。 最後の 2 階層より上にあるディレクトリ要素は、汎用的なセグメント(example-department、E01、EXAMPLE-UNIT)に置き換えてください。階層の深さとバックスラッシュを維持し、汎用的な OS ファイルである場合は末尾のファイル名(Thumbs.db)を維持してください。\2026\ のような年のフォルダーは識別情報ではないため、そのままでもかまいません。

接頭辞を維持する不透明な ID。 SaaS や ID プラットフォームの ID には、短い種類の接頭辞と長い大文字小文字混在の接尾辞を持つものがよくあります。接尾辞を置き換え、接頭辞は維持してください。同じ元の値には、同じプレースホルダーを使用してください。URL パス内の base64 ブロブも、同じ長さの合成 base64 に置き換えてください。実在しそうなアプリ/役割の表示名は、汎用的な名前(Example Application Role Management)に置き換えてください。

デバイスのシリアル番号と MDM ID。 device_id/serial/DeviceId(および類似のフィールド)にある長い 16 進数/英数字の値は、文字種と長さが同じ合成値(SN000000000001、SEC123ABCDEFG45H)に置き換えてください。実際のデバイスや MDM のシリアル番号を残さないでください。

ID ストア名とグループ階層。 <NAME>-AD/ID ストアは EXAMPLE-AD に置き換えてください。ハッシュ区切りの階層では、Location#All Locations#/Device Type#All Device Types# のような構造上の接頭辞を維持し、実在する都市/サイト名である末尾の要素を置き換えてください(Example-Site)。ユーザー名をサニタイズした後も実在しそうなストア名は、必ず置き換えてください。

URL とクエリ文字列内にネストされた IP アドレス。 最上位の src_ip/dst_ip を置き換えた後、URL のクエリとパスを調べ、ip=、src=、dst= およびドット区切りの 4 つ組を探してください。同じホストの IP アドレスがほかにも出現している場合は、すでに使用した同じ RFC 5737 IP アドレスを使用してください。該当するものがなければ 198.51.100.10 を使用してください。周囲の URL が不正な形式でも、必ず置き換えてください。

OCSP/AIA/CRL 証明書パス。 http://ocsp.digicert.com/AAAAAAAAAAAAAAAAAAAAAAAAAAAA のような場合、ホストはそのままでもかまいません(公開 CA)。パスには証明書のシリアル番号/発行者の情報が含まれます。ホスト名が ocsp./crl./cacerts. に一致する場合(公開・非公開を問わず)、パスを同じ長さの合成 base64/16 進数文字列(ゼロまたは A)に置き換えてください。/ の数と文字種を維持してください。 ユーザー名内の JNDI/インターポレーションの検査文字列。 フィールドに ${jndi:、${lower:、または ${::- が含まれている場合は、フィールド値全体を合成ユーザー名(alice.johnson、または元の引用符/アポストロフィを維持する必要がある場合は Lab1's User)に置き換えます。検査用 URL は残さないでください。前後の引用符は維持します。

顧客テレメトリ内の公開宛先ホスト名。 公開ホスト(docs.google.com、api.github.com)は、ログのソースとなるベンダー APIの場合に限り、そのまま残せます。ファイアウォール、プロキシ、DNS、UTM、コンテンツフィルターのイベントでは、宛先ホスト名と宛先 IP は顧客テレメトリです。youtube.com などのよく知られた一般向けサイトや、公開ユニキャスト IP であっても置き換えてください。ログのソースである製品のホスト(GitHub の監査ログ内の api.github.com)は維持します。

ステップ 2 — 構造が維持されていることを確認する

サニタイズ後、以下を確認してください。

  • 行数が変わっていないこと。末尾の KV ペアを削除しないでください
  • 出力の長さが入力の 70% 以上であること。ただし、長いトークンを同じ形状のプレースホルダーに置き換えるだけの場合を除きます(クエリを短くすれば 2k の URL は短くできますが、syslog の行の残りを削除しないでください)。繰り返しフィールドを削除して「完了」させる必要があるなら、やり方が間違っています。代わりに 2 パスのマップを使用してください
  • 2 回目の残存データスキャン:URL 内の ip=/src=/dst=/ドット区切りの 4 オクテット値、複合 ID 内の 16 進数 DWORD、ホスト名のようなトポロジートークン、デバイスのシリアル番号、プレフィックスを保持する不透明な ID
  • JSON 行が有効な JSON のままであること(NDJSON ファイルの場合):
    python3 -c "
    import json, sys
    with open('FILE') as f:
        for i, line in enumerate(f, 1):
            line = line.strip()
            if line:
                try: json.loads(line)
                except Exception as e: print(f'Line {i}: {e}')
    "
    
  • タイムスタンプが元の形式(タイムゾーンの略語を含む。「維持する項目」を参照)に一致していること
  • パーサーや条件分岐で使用される列挙値/ステータス値/アクション値が変更されていないこと

プレースホルダーの規則

書式に依存するパーサーが壊れる REDACTED 文字列ではなく、一貫性のある、実際にありそうな置換値を使用してください。

種類置換値
メールアドレス[email protected]、[email protected]
IPv4RFC 5737 の範囲:198.51.100.10、203.0.113.20、192.0.2.30
IPv62001:db8::10
ホスト名 / FQDNhost-1.example.local、srv-web-01.example.internal
トポロジーのホスト名host-1.example.local
ドメインexample.com、example.org、example.net
UUID89a1d5c1-2b3e-4f67-8a9b-0c1d2e3f4a5b
API キー / トークンsk_test_example_key_1234567890、dGVzdC10b2tlbi0xMjM0NTY3ODk=
ユーザー名alice.johnson、bob.smith
表示名Alice Johnson、Bob Smith
組織 / 会社名Example Corp、Acme Inc
アカウント / テナント ID000000000000、example-tenant-id
クラウドリソース IDarn:aws:iam::000000000000:user/example-user
S3 バケット名example-bucket
MAC アドレス00-00-5E-00-53-23(RFC 7042 の文書用範囲)
シリアル番号SN000000000001
デバイス / マシン ID合成 UUID または device-id-example-000001 を使用
MDM / ベンダー接頭辞付きデバイス ID同じ文字種と長さ(SEC123ABCDEFG45H)
Windows SIDS-1-5-21-000000000-000000000-000000000-1000
ファイルパス(Windows)C:\Users\example-user\AppData\...
ファイルパス(Unix)/home/example-user/... または ~ を使用
Kubernetes クラスターexample-cluster、example-node-1
電話番号734-555-0100(555 番台はフィクション用に予約されています)
データベースのホスト / 名前db-host.example.local、example_database
部門 / 組織単位example-department、/example-org/example-unit
ハッシュ化 / 一部表示されたトークン同じ形式の完全な合成トークンに置換
DHCP フィンガープリントexample-dhcp-fingerprint-000001
JA4 フィンガープリント同じ長さの 16 進文字列に置換
トランザクション / シーケンス / イベントインスタンス ID(数値)元と同じ桁数の合成整数を使用 — 例:48273915 → 10000002
セッション / リクエスト / 相関 ID同じ長さの合成文字列(長さと文字種を維持)。説明的な名前は使用しない
複合 ID 内の 16 進 dword8 桁の 16 進数、0x 接頭辞を付ける。origin / src に使用したものと同じ RFC 5737 IP をエンコード
日付付きポリシー / ACLexample-policy、vlan100-20240101000000
インターフェース ethN-MM.VLANeth1-01.100
型接頭辞付きの不透明な ID接頭辞を維持し、接尾辞を合成値にする
ID ストアEXAMPLE-AD
ロケーション階層の末端Example-Site
OCSP / CRL / AIA パス同じ長さの A / 0 の Base64
JNDI ユーザー名alice.johnson(引用符を維持)

一貫性のルール:ファイル全体で、同一の元の値には同一のプレースホルダーを割り当ててください。同じ IP が 10 回登場する場合、10 回すべて同じ置換 IP にする必要があります。これにより、イベント間の相関をテスト可能な状態に保てます。まず対応表をすべて作成してから、全体に適用してください。異なる元の値には、必ず異なるプレースホルダーを割り当ててください — 30 個のユーザー名を alice.johnson にまとめてはいけません。入れ子になったコピー(src 内の IP、URL の ip= 内の同じ IP、複合 ID 内の 16 進表現)は、すべてその元の値に対応するプレースホルダーを使用してください。

形式のルール — 置換後も元の形式に合わせる

置換後の値はすべて、元の値と同じ形式にする必要があります。パーサーと後続処理は、フィールドの有無だけでなく値の形式にも依存します。

  • 数値 ID → 数値 ID:/d/123/edit → /d/456/edit。/d/example-document-id/edit のようにはしないでください
  • トランザクション/シーケンス/イベントインスタンス ID → 同じ形式の数値:イベントごとの追跡識別子の場合は、桁数を保ってマスキングします。例:CEF cn1=48273915 cn2=3061847 → cn1=10000002 cn2=1000002
  • UUID → UUID:実際の UUID は、説明的な文字列ではなく、同じバージョンの合成 UUID に置き換える必要があります
  • URL → URL:機密情報を含む部分(ホスト名、パス内の ID、入れ子になった ip=/src=/dst=)のみを置き換えます。スキーム、パス構造、クエリ文字列の形式、および不正な文字は維持します
    • https://docs.google.com/drawings/d/123/edit → https://docs.google.com/drawings/d/000000000000/edit(ホストではなく ID を置き換えます。docs.google.com は公開サービス名であり、組織識別子ではありません。このルールはベンダー API のログに適用されます)
    • https://internal.corp.com/api/v1/resource → https://host-redacted.example.local/api/v1/resource(内部ホスト名を置き換え、パスは維持します)
    • ファイアウォール/プロキシ/UTM のテレメトリでは、宛先ホストと IP も置き換えます(「保持する情報」を参照)。不正な形式の URL を https://example.com/path や /some/api に書き換えないでください
  • 文字列 ID → 同じ長さまたは同じ形式の文字列:不透明な英数字 ID は、説明的な名前ではなく、同程度の長さの不透明な英数字プレースホルダーに置き換えます
  • URL 内のホスト名と単独のホスト名:実際の内部インフラ、またはファイアウォール/プロキシ/UTM ログにおける顧客がアクセスした宛先を示すホスト名のみを置き換えます。docs.google.com、api.github.com、s3.amazonaws.com などのよく知られた公開ホスト名は、SaaS/ベンダー API ログでは組織ではなくサービスを示すため、置き換える必要はありません

不正な形式または意味のない値は置き換えてはいけません。 壊れている、合成されたものに見える、または実際の識別情報を含まない値(例:http://1=Y +z\\、00/00/0000、N/A、空文字列、プレースホルダーのように見える値)は、そのまま変更せずに残します。不正な形式の値を整形式のプレースホルダーに置き換えると、形式が変わってしまいます。不正な形式を維持したまま、そこに含まれる個人情報(実際の IP、ホスト名、ユーザー)を置き換えることはできます。余分な引用符、エンコードされていない { }、URL 内のスペース、切り詰められたフィールド、U+FFFD も維持してください。

置き換える形式に迷った場合は、同じファイル内にある同じフィールド型の近接する値を確認し、その形式に合わせてください。

保持するもの

次のものは置き換えないでください。

  • プロトコル名、アクションを表す動詞、イベント種別、重大度レベル(ALLOW、DENY、INFO、ERROR)
  • Windows イベント ID など、製品で定義されたイベントコード/タイプ ID。これらはイベントの意味を表すものであり、顧客固有のイベントインスタンスではありません
  • ベンダーの Syslog メッセージ ID(%NAME-6-302018)。これらは製品のニーモニックであり、ホスト名ではありません
  • HTTP ステータスコード、ポート番号、数値のメトリック値(件数、サイズ、所要時間)
  • フィールド名とキー
  • タイムスタンプ(形式とタイムゾーンはそのまま維持してください)。タイムゾーンの略称、エポック値、クロックフィールドは変更しないでください。
    • Jun 27 14:06:33.189 JST を Jul 24 00:47:24.618 CET に変更しないでください
    • エポック/Unix タイムスタンプは、わずかな差であってもずらしたり、その他の方法で変更したりしないでください。数値のクロックフィールド(eventtime、エポックミリ秒など)はバイト単位でそのまま維持してください。
    • JST、EDT、EST、Eastern、(GMT-3:00)Buenos Aires, Georgetown を別のタイムゾーンに置き換えないでください。日付パーサーは略称をキーとしているため、JST を CET に置き換えると解析が壊れるうえ、地理情報も(誤ったものに)変わってしまいます。タイムゾーン略称のプライバシー保護は対象外です。そのまま維持してください
  • 構造トークン(角括弧、中括弧、パイプ、カンマ、タブ)
  • URL に含まれる、一般に知られた公開サービスのホスト名(docs.google.com、api.github.com など)。ただし、それがログソースのベンダー APIである場合に限ります。機密性のあるパス ID は置き換え、ホスト名はそのままにしてください。ファイアウォール、プロキシ、DNS、UTM、コンテンツフィルターのイベントでは、宛先ホスト名と宛先 IP アドレスは顧客のテレメトリです。よく知られた一般向けサイト(youtube.com)やパブリックユニキャスト IP アドレスであっても置き換えてください。ログソースである製品ホスト(GitHub の監査ログにおける api.github.com など)はそのままにしてください
  • ファイルハッシュ(ファイルコンテンツの MD5、SHA1、SHA256)。これらはコンテンツアドレス可能で安全なため、置き換えないでください
  • ユーザーエージェント文字列(Mozilla/5.0 ...)。ブラウザー/OS の種類は明らかになりますが、個人は特定されないため、そのままにして問題ありません
  • 地理情報のエンリッチメントフィールドに含まれる市区町村名と国名。置き換えるのは正確な座標と住所のみです
  • Syslog PRI/RFC5424 ヘッダー。追加、削除、書き換えをしないでください

コメント