Censys のログを収集する
このドキュメントでは、Google Cloud Storage V2 を使用して Censys ログを Google Security Operations に取り込む方法について説明します。
Censys は、API を通じて包括的な攻撃対象領域管理とインターネット インテリジェンスを提供します。この統合により、Censys ASM からホスト検出イベント、リスクイベント、アセットの変更を収集し、分析とモニタリングのために Google SecOps に転送できます。
始める前に
次の前提条件を満たしていることを確認します。
- Google SecOps インスタンス
- Cloud Storage API が有効になっている GCP プロジェクト
- GCS バケットを作成および管理する権限
- GCS バケットの IAM ポリシーを管理する権限
- Cloud Run サービス、Pub/Sub トピック、Cloud Scheduler ジョブを作成する権限
- Censys ASM への特権アクセス
Censys API 認証情報を収集する
- app.censys.io で Censys ASM コンソールにログインします。
- ページ上部の [インテグレーション] に移動します。
- API キーと組織 ID をコピーして保存します。
- API ベース URL(
https://api.platform.censys.io)をメモします。
Google Cloud Storage バケットを作成する
- Google Cloud Console に移動します。
- プロジェクトを選択するか、新しいプロジェクトを作成します。
- ナビゲーション メニューで、[Cloud Storage > バケット] に移動します。
- [バケットを作成] をクリックします。
次の構成情報を提供してください。
設定 値 バケットに名前を付ける グローバルに一意の名前( censys-logsなど)を入力します。ロケーション タイプ ニーズに基づいて選択します(リージョン、デュアルリージョン、マルチリージョン)。 ロケーション ロケーションを選択します(例: us-central1)。ストレージ クラス Standard(頻繁にアクセスされるログにおすすめ) アクセス制御 均一(推奨) 保護ツール 省略可: オブジェクトのバージョニングまたは保持ポリシーを有効にする [作成] をクリックします。
Cloud Run functions のサービス アカウントを作成する
Cloud Run 関数には、GCS バケットに書き込む権限を持つサービス アカウントが必要です。
サービス アカウントの作成
- GCP Console で、[IAM と管理>サービス アカウント] に移動します。
- [サービス アカウントを作成] をクリックします。
- 次の構成の詳細を指定します。
- サービス アカウント名: 「
censys-data-collector-sa」と入力します。 - サービス アカウントの説明: 「
Service account for Cloud Run function to collect Censys logs」と入力します。
- サービス アカウント名: 「
- [作成して続行] をクリックします。
- [このサービス アカウントにプロジェクトへのアクセスを許可する] セクションで、次のロールを追加します。
- [ロールを選択] をクリックします。
- [ストレージ オブジェクト管理者] を検索して選択します。
- [+ 別のロールを追加] をクリックします。
- [Cloud Run 起動元] を検索して選択します。
- [+ 別のロールを追加] をクリックします。
- [Cloud Functions 起動元] を検索して選択します。
- [続行] をクリックします。
- [完了] をクリックします。
これらのロールは、次の目的で必要です。
- Storage オブジェクト管理者: ログを GCS バケットに書き込み、状態ファイルを管理する
- Cloud Run 起動元: Pub/Sub が関数を呼び出すことを許可する
- Cloud Functions 起動元: 関数の呼び出しを許可する
GCS バケットに対する IAM 権限を付与する
GCS バケットに対する書き込み権限をサービス アカウントに付与します。
- [Cloud Storage] > [バケット] に移動します。
- バケット名をクリックします。
- [権限] タブに移動します。
- [アクセス権を付与] をクリックします。
- 次の構成の詳細を指定します。
- プリンシパルを追加: サービス アカウントのメールアドレス(例:
censys-data-collector-sa@PROJECT_ID.iam.gserviceaccount.com)を入力します。 - ロールを割り当てる: [Storage オブジェクト管理者] を選択します。
- プリンシパルを追加: サービス アカウントのメールアドレス(例:
- [保存] をクリックします。
Pub/Sub トピックの作成
Cloud Scheduler がパブリッシュし、Cloud Run functions がサブスクライブする Pub/Sub トピックを作成します。
- GCP Console で、[Pub/Sub> トピック] に移動します。
- [トピックを作成] をクリックします。
- 次の構成の詳細を指定します。
- トピック ID: 「
censys-data-trigger」と入力します。 - その他の設定はデフォルトのままにします。
- トピック ID: 「
- [作成] をクリックします。
ログを収集する Cloud Run 関数を作成する
Cloud Run 関数は、Cloud Scheduler からの Pub/Sub メッセージによってトリガーされ、Censys ASM API からログを取得して GCS に書き込みます。
- GCP Console で、[Cloud Run] に移動します。
- [サービスを作成] をクリックします。
- [関数] を選択します(インライン エディタを使用して関数を作成します)。
[構成] セクションで、次の構成の詳細を指定します。
設定 値 サービス名 censys-data-collectorリージョン GCS バケットと一致するリージョンを選択します(例: us-central1)。ランタイム [Python 3.12] 以降を選択します。 [トリガー(省略可)] セクションで、次の操作を行います。
- [+ トリガーを追加] をクリックします。
- [Cloud Pub/Sub] を選択します。
- [Cloud Pub/Sub トピックを選択してください] で、Pub/Sub トピック(
censys-data-trigger)を選択します。 - [保存] をクリックします。
[認証] セクションで、次の操作を行います。
- [認証が必要] を選択します。
- Identity and Access Management(IAM)を確認します。
- 下にスクロールして、[コンテナ、ネットワーキング、セキュリティ] を開きます。
- [セキュリティ] タブに移動します。
- サービス アカウント: サービス アカウントを選択します(
censys-data-collector-sa)。
- サービス アカウント: サービス アカウントを選択します(
[コンテナ] タブに移動します。
- [変数とシークレット] をクリックします。
環境変数ごとに [+ 変数を追加] をクリックします。
変数名 値の例 GCS_BUCKETcensys-logsGCS_PREFIXcensys/STATE_KEYcensys/state.jsonCENSYS_API_KEYyour-censys-api-keyCENSYS_ORG_IDyour-organization-idAPI_BASEhttps://api.platform.censys.io
[変数とシークレット] タブで [リクエスト] まで下にスクロールします。
- リクエストのタイムアウト:
600秒(10 分)を入力します。
- リクエストのタイムアウト:
[コンテナ] の [設定] タブに移動します。
- [リソース] セクションで次の操作を行います。
- メモリ: 512 MiB 以上を選択します。
- CPU: [1] を選択します。
- [完了] をクリックします。
- [リソース] セクションで次の操作を行います。
[実行環境] までスクロールします。
- [デフォルト](推奨)を選択します。
[リビジョン スケーリング] セクションで、次の操作を行います。
- [インスタンスの最小数] に「
0」と入力します。 - インスタンスの最大数:
100と入力します(または、予想される負荷に基づいて調整します)。
- [インスタンスの最小数] に「
[作成] をクリックします。
サービスが作成されるまで待ちます(1 ~ 2 分)。
サービスを作成すると、インライン コードエディタが自動的に開きます。
関数コードを追加する
- [関数のエントリ ポイント] に「main」と入力します。
インライン コードエディタで、次の 2 つのファイルを作成します。
- 最初のファイル: main.py:
import functions_framework from google.cloud import storage import json import urllib3 import gzip import os from datetime import datetime, timedelta, timezone from typing import Dict, List, Any, Optional from urllib.parse import urlencode # Initialize HTTP client with timeouts http = urllib3.PoolManager( timeout=urllib3.Timeout(connect=5.0, read=30.0), retries=False, ) # Initialize Storage client storage_client = storage.Client() @functions_framework.cloud_event def main(cloud_event): """ Cloud Run function triggered by Pub/Sub to fetch logs from Censys ASM API and write to GCS. Args: cloud_event: CloudEvent object containing Pub/Sub message """ # Get environment variables bucket_name = os.environ.get('GCS_BUCKET') prefix = os.environ.get('GCS_PREFIX', 'censys/') state_key = os.environ.get('STATE_KEY', 'censys/state.json') censys_api_key = os.environ.get('CENSYS_API_KEY') censys_org_id = os.environ.get('CENSYS_ORG_ID') api_base = os.environ.get('API_BASE', 'https://api.platform.censys.io') if not all([bucket_name, censys_api_key, censys_org_id]): print('Error: Missing required environment variables') return try: collector = CensysCollector( bucket_name=bucket_name, prefix=prefix, state_key=state_key, api_key=censys_api_key, org_id=censys_org_id, api_base=api_base ) # Get last collection time last_collection_time = collector.get_last_collection_time() current_time = datetime.now(timezone.utc) print(f'Collecting events since {last_collection_time}') # Collect different types of events logbook_events = collector.collect_logbook_events() risk_events = collector.collect_risks_events() # Save events to GCS collector.save_events_to_gcs(logbook_events, 'logbook') collector.save_events_to_gcs(risk_events, 'risks') # Update state collector.save_collection_time(current_time) print(f'Successfully processed {len(logbook_events)} logbook events and {len(risk_events)} risk events') except Exception as e: print(f'Error processing logs: {str(e)}') raise class CensysCollector: def __init__(self, bucket_name: str, prefix: str, state_key: str, api_key: str, org_id: str, api_base: str): self.bucket_name = bucket_name self.prefix = prefix self.state_key = state_key self.headers = { 'Authorization': f'Bearer {api_key}', 'X-Organization-ID': org_id, 'Content-Type': 'application/json' } self.api_base = api_base self.bucket = storage_client.bucket(bucket_name) def get_last_collection_time(self) -> Optional[datetime]: """Get the last collection timestamp from GCS state file.""" try: blob = self.bucket.blob(self.state_key) if blob.exists(): state_data = blob.download_as_text() state = json.loads(state_data) return datetime.fromisoformat(state.get('last_collection_time', '2024-01-01T00:00:00Z')) except Exception as e: print(f'No state file found or error reading state: {e}') return datetime.now(timezone.utc) - timedelta(hours=1) def save_collection_time(self, collection_time: datetime): """Save the current collection timestamp to GCS state file.""" state = {'last_collection_time': collection_time.strftime('%Y-%m-%dT%H:%M:%SZ')} blob = self.bucket.blob(self.state_key) blob.upload_from_string( json.dumps(state), content_type='application/json' ) def collect_logbook_events(self, cursor: str = None) -> List[Dict[str, Any]]: """Collect logbook events from Censys ASM API using cursor-based pagination.""" events = [] url = f"{self.api_base}/v3/logbook" params = {} if cursor: params['cursor'] = cursor try: query_string = urlencode(params) if params else '' full_url = f"{url}?{query_string}" if query_string else url response = http.request('GET', full_url, headers=self.headers) # Handle rate limiting with exponential backoff if response.status == 429: retry_after = int(response.headers.get('Retry-After', '60')) print(f'Rate limited (429). Retrying after {retry_after}s...') import time time.sleep(retry_after) return self.collect_logbook_events(cursor) if response.status != 200: print(f'API request failed with status {response.status}: {response.data}') return [] data = json.loads(response.data.decode('utf-8')) events.extend(data.get('logbook_entries', [])) # Handle cursor-based pagination next_cursor = data.get('next_cursor') if next_cursor: events.extend(self.collect_logbook_events(next_cursor)) print(f'Collected {len(events)} logbook events') return events except Exception as e: print(f'Error collecting logbook events: {e}') return [] def collect_risks_events(self) -> List[Dict[str, Any]]: """Collect risk events from Censys ASM API.""" events = [] url = f"{self.api_base}/v3/risks" try: response = http.request('GET', url, headers=self.headers) # Handle rate limiting with exponential backoff if response.status == 429: retry_after = int(response.headers.get('Retry-After', '60')) print(f'Rate limited (429). Retrying after {retry_after}s...') import time time.sleep(retry_after) return self.collect_risks_events() if response.status != 200: print(f'API request failed with status {response.status}: {response.data}') return [] data = json.loads(response.data.decode('utf-8')) events.extend(data.get('risks', [])) print(f'Collected {len(events)} risk events') return events except Exception as e: print(f'Error collecting risk events: {e}') return [] def save_events_to_gcs(self, events: List[Dict[str, Any]], event_type: str): """Save events to GCS in compressed NDJSON format.""" if not events: return timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') filename = f"{self.prefix}{event_type}_{timestamp}.json.gz" try: # Convert events to newline-delimited JSON ndjson_content = '\n'.join(json.dumps(event, separators=(',', ':')) for event in events) # Compress with gzip gz_bytes = gzip.compress(ndjson_content.encode('utf-8')) blob = self.bucket.blob(filename) blob.upload_from_string( gz_bytes, content_type='application/gzip' ) print(f'Saved {len(events)} {event_type} events to {filename}') except Exception as e: print(f'Error saving {event_type} events to GCS: {e}') raise- 2 つ目のファイル: requirements.txt:
functions-framework==3.* google-cloud-storage==2.* urllib3>=2.0.0[デプロイ] をクリックして、関数を保存してデプロイします。
デプロイが完了するまで待ちます(2 ~ 3 分)。
Cloud Scheduler ジョブの作成
Cloud Scheduler は、定期的に Pub/Sub トピックにメッセージをパブリッシュし、Cloud Run functions の関数をトリガーします。
- GCP Console で、[Cloud Scheduler] に移動します。
- [ジョブを作成] をクリックします。
次の構成情報を提供してください。
設定 値 名前 censys-data-collector-hourlyリージョン Cloud Run functions と同じリージョンを選択する 周波数 0 * * * *(1 時間ごとに正時)タイムゾーン タイムゾーンを選択します(UTC を推奨)。 ターゲット タイプ Pub/Sub トピック Pub/Sub トピック( censys-data-trigger)を選択するメッセージ本文 {}(空の JSON オブジェクト)[作成] をクリックします。
スケジュールの頻度のオプション
ログの量とレイテンシの要件に基づいて頻度を選択します。
頻度 CRON 式 ユースケース 5 分毎 */5 * * * *大容量、低レイテンシ 15 分ごと */15 * * * *検索量が普通 1 時間ごと 0 * * * *標準(推奨) 6 時間ごと 0 */6 * * *少量、バッチ処理 毎日 0 0 * * *履歴データの収集
統合をテストする
- Cloud Scheduler コンソールで、ジョブを見つけます。
- [強制実行] をクリックして、ジョブを手動でトリガーします。
- 数秒待ちます。
- Cloud Run > サービスに移動します。
- 関数名(
censys-data-collector)をクリックします。 - [Logs] タブをクリックします。
関数が正常に実行されたことを確認します。次の内容を確認します。
Collecting events since YYYY-MM-DDTHH:MM:SS+00:00 Collected X logbook events Collected X risk events Saved X logbook events to censys/logbook_YYYYMMDD_HHMMSS.json.gz Saved X risks events to censys/risks_YYYYMMDD_HHMMSS.json.gz Successfully processed X logbook events and X risk events[Cloud Storage] > [バケット] に移動します。
バケット名をクリックします。
プレフィックス フォルダ(
censys/)に移動します。新しい
.json.gzファイルが現在のタイムスタンプで作成されたことを確認します。
ログにエラーが表示された場合:
- HTTP 401: 環境変数で API 認証情報を確認する
- HTTP 403: アカウントに必要な権限があることを確認する
- HTTP 429: レート制限 - 関数はバックオフで自動的に再試行されます
- 環境変数が不足している: 必要な変数がすべて設定されていることを確認します
Google SecOps サービス アカウントを取得する
Google SecOps は、一意のサービス アカウントを使用して GCS バケットからデータを読み取ります。このサービス アカウントにバケットへのアクセス権を付与する必要があります。
サービス アカウントのメールアドレスを取得する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- [単一フィードを設定] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
Censys logs)。 - [ソースタイプ] として [Google Cloud Storage V2] を選択します。
- [ログタイプ] として [CENSYS] を選択します。
- [サービス アカウントを取得する] をクリックします。
一意のサービス アカウント メールアドレスが表示されます(例:)。
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comこのメールアドレスをコピーして、次のステップで使用します。
Google SecOps サービス アカウントに IAM 権限を付与する
Google SecOps サービス アカウントには、GCS バケットに対する Storage オブジェクト閲覧者ロールが必要です。
- [Cloud Storage] > [バケット] に移動します。
- バケット名をクリックします。
- [権限] タブに移動します。
- [アクセス権を付与] をクリックします。
- 次の構成の詳細を指定します。
- プリンシパルを追加: Google SecOps サービス アカウントのメールアドレスを貼り付けます。
- ロールを割り当てる: [ストレージ オブジェクト閲覧者] を選択します。
- [保存] をクリックします。
Censys のログを取り込むように Google SecOps でフィードを構成する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- [単一フィードを設定] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
Censys logs)。 - [ソースタイプ] として [Google Cloud Storage V2] を選択します。
- [ログタイプ] として [CENSYS] を選択します。
- [次へ] をクリックします。
次の入力パラメータの値を指定します。
ストレージ バケットの URL: 接頭辞パスを含む GCS バケット URI を入力します。
gs://censys-logs/censys/次のように置き換えます。
censys-logs: GCS バケット名。censys/: ログが保存されるオプションの接頭辞/フォルダパス(ルートの場合は空のままにします)。
例:
- ルートバケット:
gs://censys-logs/ - 接頭辞あり:
gs://censys-logs/censys/
- ルートバケット:
Source deletion option: 必要に応じて削除オプションを選択します。
- なし: 転送後にファイルを削除しません(テストにおすすめ)。
- 転送されたファイルを削除する: 転送が完了した後にファイルを削除します。
転送されたファイルと空のディレクトリを削除する: 転送が完了した後にファイルと空のディレクトリを削除します。
ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。
アセットの名前空間: アセットの名前空間。
Ingestion labels: このフィードのイベントに適用されるラベル。
[次へ] をクリックします。
[Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。
UDM マッピング テーブル
| ログフィールド | UDM マッピング | 論理 |
|---|---|---|
| assetId | read_only_udm.principal.asset.hostname | assetId フィールドが IP アドレスでない場合、principal.asset.hostname にマッピングされます。 |
| assetId | read_only_udm.principal.asset.ip | assetId フィールドが IP アドレスの場合、principal.asset.ip にマッピングされます。 |
| assetId | read_only_udm.principal.hostname | assetId フィールドが IP アドレスでない場合は、principal.hostname にマッピングされます。 |
| assetId | read_only_udm.principal.ip | assetId フィールドが IP アドレスの場合、principal.ip にマッピングされます。 |
| associatedAt | read_only_udm.security_result.detection_fields.value | associatedAt フィールドは security_result.detection_fields.value にマッピングされます。 |
| autonomousSystem.asn | read_only_udm.additional.fields.value.string_value | autonomousSystem.asn フィールドは文字列に変換され、キー「autonomousSystem_asn」を持つ additional.fields.value.string_value にマッピングされます。 |
| autonomousSystem.bgpPrefix | read_only_udm.additional.fields.value.string_value | autonomousSystem.bgpPrefix フィールドは、キーが「autonomousSystem_bgpPrefix」の additional.fields.value.string_value にマッピングされます。 |
| バナー | read_only_udm.principal.resource.attribute.labels.value | バナー フィールドは、キー「banner」を使用して principal.resource.attributes.labels.value にマッピングされます。 |
| クラウド | read_only_udm.metadata.vendor_name | cloud フィールドは metadata.vendor_name にマッピングされます。 |
| comments.refUrl | read_only_udm.network.http.referral_url | comments.refUrl フィールドは network.http.referral_url にマッピングされます。 |
| data.cve | read_only_udm.additional.fields.value.string_value | data.cve フィールドは、キー「data_cve」を使用して additional.fields.value.string_value にマッピングされます。 |
| data.cvss | read_only_udm.additional.fields.value.string_value | data.cvss フィールドは、キーが「data_cvss」の additional.fields.value.string_value にマッピングされます。 |
| data.ipAddress | read_only_udm.principal.asset.ip | data.ipAddress フィールドが assetId フィールドと等しくない場合、principal.asset.ip にマッピングされます。 |
| data.ipAddress | read_only_udm.principal.ip | data.ipAddress フィールドが assetId フィールドと等しくない場合、principal.ip にマッピングされます。 |
| data.location.city | read_only_udm.principal.location.city | location.city フィールドが空の場合、data.location.city フィールドは principal.location.city にマッピングされます。 |
| data.location.countryCode | read_only_udm.principal.location.country_or_region | location.country フィールドが空の場合、data.location.countryCode フィールドは principal.location.country_or_region にマッピングされます。 |
| data.location.latitude | read_only_udm.principal.location.region_coordinates.latitude | location.coordinates.latitude フィールドと location.geoCoordinates.latitude フィールドが空の場合、data.location.latitude フィールドは float に変換され、principal.location.region_coordinates.latitude にマッピングされます。 |
| data.location.longitude | read_only_udm.principal.location.region_coordinates.longitude | location.coordinates.longitude フィールドと location.geoCoordinates.longitude フィールドが空の場合、data.location.longitude フィールドは float に変換され、principal.location.region_coordinates.longitude にマッピングされます。 |
| data.location.province | read_only_udm.principal.location.state | location.province フィールドが空の場合、data.location.province フィールドは principal.location.state にマッピングされます。 |
| data.mailServers | read_only_udm.additional.fields.value.list_value.values.string_value | data.mailServers 配列の各要素は、キー「Mail Servers」と value.list_value.values.string_value が要素の値に設定された個別の additional.fields エントリにマッピングされます。 |
| data.names.forwardDns[].name | read_only_udm.network.dns.questions.name | data.names.forwardDns 配列の各要素は、name フィールドが要素の name フィールドに設定された個別の network.dns.questions エントリにマッピングされます。 |
| data.nameServers | read_only_udm.additional.fields.value.list_value.values.string_value | data.nameServers 配列の各要素は、キーが「Name nameServers」、value.list_value.values.string_value が要素の値に設定された個別の additional.fields エントリにマッピングされます。 |
| data.protocols[].transportProtocol | read_only_udm.network.ip_protocol | data.protocols[].transportProtocol フィールドが TCP、EIGRP、ESP、ETHERIP、GRE、ICMP、IGMP、IP6IN4、PIM、UDP、VRRP のいずれかの場合、network.ip_protocol にマッピングされます。 |
| data.protocols[].transportProtocol | read_only_udm.principal.resource.attribute.labels.value | data.protocols[].transportProtocol フィールドは、キー「data_protocols {index}」を使用して principal.resource.attribute.labels.value にマッピングされます。 |
| http.request.headers[].key、http.request.headers[].value.headers.0 | read_only_udm.network.http.user_agent | http.request.headers[].key フィールドが「User-Agent」の場合、対応する http.request.headers[].value.headers.0 フィールドは network.http.user_agent にマッピングされます。 |
| http.request.headers[].key、http.request.headers[].value.headers.0 | read_only_udm.network.http.parsed_user_agent | http.request.headers[].key フィールドが「User-Agent」の場合、対応する http.request.headers[].value.headers.0 フィールドはユーザー エージェント文字列として解析され、network.http.parsed_user_agent にマッピングされます。 |
| http.request.headers[].key、http.request.headers[].value.headers.0 | read_only_udm.principal.resource.attribute.labels.key、read_only_udm.principal.resource.attribute.labels.value | http.request.headers 配列の各要素について、key フィールドは principal.resource.attribute.labels.key にマッピングされ、value.headers.0 フィールドは principal.resource.attribute.labels.value にマッピングされます。 |
| http.request.uri | read_only_udm.principal.asset.hostname | http.request.uri フィールドのホスト名部分が抽出され、principal.asset.hostname にマッピングされます。 |
| http.request.uri | read_only_udm.principal.hostname | http.request.uri フィールドのホスト名部分が抽出され、principal.hostname にマッピングされます。 |
| http.response.body | read_only_udm.principal.resource.attribute.labels.value | http.response.body フィールドは、キー「http_response_body」を持つ principal.resource.attributes.labels.value にマッピングされます。 |
| http.response.headers[].key、http.response.headers[].value.headers.0 | read_only_udm.target.hostname | http.response.headers[].key フィールドが「Server」の場合、対応する http.response.headers[].value.headers.0 フィールドは target.hostname にマッピングされます。 |
| http.response.headers[].key、http.response.headers[].value.headers.0 | read_only_udm.principal.resource.attribute.labels.key、read_only_udm.principal.resource.attribute.labels.value | http.response.headers 配列の各要素について、key フィールドは principal.resource.attribute.labels.key にマッピングされ、value.headers.0 フィールドは principal.resource.attribute.labels.value にマッピングされます。 |
| http.response.statusCode | read_only_udm.network.http.response_code | http.response.statusCode フィールドは整数に変換され、network.http.response_code にマッピングされます。 |
| ip | read_only_udm.target.asset.ip | ip フィールドは target.asset.ip にマッピングされます。 |
| ip | read_only_udm.target.ip | ip フィールドは target.ip にマッピングされます。 |
| isSeed | read_only_udm.additional.fields.value.string_value | isSeed フィールドは文字列に変換され、キー「isSeed」を持つ additional.fields.value.string_value にマッピングされます。 |
| location.city | read_only_udm.principal.location.city | location.city フィールドは principal.location.city にマッピングされます。 |
| location.continent | read_only_udm.additional.fields.value.string_value | location.continent フィールドは、キーが「location_continent」の additional.fields.value.string_value にマッピングされます。 |
| location.coordinates.latitude | read_only_udm.principal.location.region_coordinates.latitude | location.coordinates.latitude フィールドは float に変換され、principal.location.region_coordinates.latitude にマッピングされます。 |
| location.coordinates.longitude | read_only_udm.principal.location.region_coordinates.longitude | location.coordinates.longitude フィールドは float に変換され、principal.location.region_coordinates.longitude にマッピングされます。 |
| location.country | read_only_udm.principal.location.country_or_region | location.country フィールドは principal.location.country_or_region にマッピングされます。 |
| location.geoCoordinates.latitude | read_only_udm.principal.location.region_coordinates.latitude | location.coordinates.latitude フィールドが空の場合、location.geoCoordinates.latitude フィールドは float に変換され、principal.location.region_coordinates.latitude にマッピングされます。 |
| location.geoCoordinates.longitude | read_only_udm.principal.location.region_coordinates.longitude | location.coordinates.longitude フィールドが空の場合、location.geoCoordinates.longitude フィールドは float に変換され、principal.location.region_coordinates.longitude にマッピングされます。 |
| location.postalCode | read_only_udm.additional.fields.value.string_value | location.postalCode フィールドは、キーが「Postal code」の additional.fields.value.string_value にマッピングされます。 |
| location.province | read_only_udm.principal.location.state | location.province フィールドは principal.location.state にマッピングされます。 |
| オペレーション | read_only_udm.security_result.action_details | operation フィールドは security_result.action_details にマッピングされます。 |
| perspectiveId | read_only_udm.principal.group.product_object_id | perspectiveId フィールドは principal.group.product_object_id にマッピングされます。 |
| ポート | read_only_udm.principal.port | ポート フィールドは整数に変換され、principal.port にマッピングされます。 |
| risks[].severity、risks[].title | read_only_udm.security_result.category_details | risks[].severity フィールドが risks[].title フィールドと連結され、security_result.category_details にマッピングされます。 |
| serviceName | read_only_udm.network.application_protocol | serviceName フィールドが「HTTP」または「HTTPS」の場合、network.application_protocol にマッピングされます。 |
| sourceIp | read_only_udm.principal.asset.ip | sourceIp フィールドは principal.asset.ip にマッピングされます。 |
| sourceIp | read_only_udm.principal.ip | sourceIp フィールドは principal.ip にマッピングされます。 |
| timestamp | read_only_udm.metadata.event_timestamp | タイムスタンプ フィールドはタイムスタンプとして解析され、metadata.event_timestamp にマッピングされます。 |
| transportFingerprint.id | read_only_udm.metadata.product_log_id | transportFingerprint.id フィールドは文字列に変換され、metadata.product_log_id にマッピングされます。 |
| transportFingerprint.raw | read_only_udm.additional.fields.value.string_value | transportFingerprint.raw フィールドは、キー「transportFingerprint_raw」を使用して additional.fields.value.string_value にマッピングされます。 |
| type | read_only_udm.metadata.product_event_type | type フィールドは metadata.product_event_type にマッピングされます。 |
| - | read_only_udm.metadata.product_name | metadata.product_name には「CENSYS_ASM」という値が割り当てられます。 |
| - | read_only_udm.metadata.vendor_name | metadata.vendor_name には「CENSYS」という値が割り当てられます。 |
| - | read_only_udm.metadata.event_type | イベントタイプは、特定のフィールドの有無に基づいて決定されます。has_princ_machine_id と has_target_machine が true で、has_network_flow が false の場合は NETWORK_CONNECTION、has_network_flow が true の場合は NETWORK_DNS、has_princ_machine_id が true の場合は STATUS_UPDATE、それ以外の場合は GENERIC_EVENT です。 |
ご不明な点がございましたら、コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。