Symantec WSS のログを収集する
このドキュメントでは、Amazon S3 を使用して Symantec Web Security Service(WSS)ログを Google Security Operations に取り込む方法について説明します。パーサーは、まずログメッセージを JSON として解析しようとします。失敗した場合は、一連のより具体的な grok パターンを使用して未加工テキストからフィールドを抽出し、最終的に抽出されたデータを統合データモデル(UDM)にマッピングします。
始める前に
次の前提条件を満たしていることを確認してください。
- Google SecOps インスタンス。
- Symantec Web Security Service への特権アクセス。
- AWS(S3、Identity and Access Management(IAM)、Lambda、EventBridge)への特権アクセス。
Symantec WSS の前提条件(ID、API キー、組織 ID、トークン)を収集する
- 管理者として Symantec Web Security Service ポータルにログインします。
- [アカウント]> [API 認証情報] に移動します。
- [追加] をクリックします。
- 次の構成の詳細を入力します。
- API 名: わかりやすい名前を入力します(例:
Google SecOps Integration)。 - 説明: API 認証情報の説明を入力します。
- API 名: わかりやすい名前を入力します(例:
- [保存] をクリックし、生成された API 認証情報を安全にコピーします。
- WSS ポータル URL と Sync API エンドポイントを記録します。
- 次の詳細をコピーして安全な場所に保存します。
- WSS_API_USERNAME。
- WSS_API_PASSWORD。
- WSS_SYNC_URL。
Google SecOps 用に AWS S3 バケットと IAM を構成する
- バケットの作成のユーザーガイドに沿って、Amazon S3 バケットを作成します。
- 後で参照できるように、バケットの名前とリージョンを保存します(例:
symantec-wss-logs)。 - IAM ユーザーの作成のユーザーガイドに沿って、ユーザーを作成します。
- 作成したユーザーを選択します。
- [セキュリティ認証情報] タブを選択します。
- [アクセスキー] セクションで [アクセスキーを作成] をクリックします。
- [ユースケース] として [サードパーティ サービス] を選択します。
- [次へ] をクリックします。
- 省略可: 説明タグを追加します。
- [アクセスキーを作成] をクリックします。
- [CSV ファイルをダウンロード] をクリックし、[アクセスキー] と [シークレット アクセスキー] を保存して、今後の参照に備えます。
- [完了] をクリックします。
- [権限] タブを選択します。
- [権限ポリシー] セクションの [権限を追加] をクリックします。
- [権限を追加] を選択します。
- [ポリシーを直接アタッチする] を選択します。
- AmazonS3FullAccess ポリシーを検索します。
- ポリシーを選択します。
- [次へ] をクリックします。
- [権限を追加] をクリックします。
S3 アップロードの IAM ポリシーとロールを構成する
- AWS コンソールで、[IAM] > [ポリシー] に移動します。
- [ポリシーを作成> [JSON] タブ] をクリックします。
- 次のポリシーをコピーして貼り付けます。
ポリシー JSON(別のバケット名を入力した場合は
symantec-wss-logsを置き換えます):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::symantec-wss-logs/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::symantec-wss-logs/symantec/wss/state.json" } ] }[次へ] > [ポリシーを作成] をクリックします。
[IAM] > [ロール] > [ロールの作成] > [AWS サービス] > [Lambda] に移動します。
新しく作成したポリシーを関連付けます。
ロールに「
SymantecWssToS3Role」という名前を付けて、[ロールを作成] をクリックします。
Lambda 関数を作成する
- AWS コンソールで、[Lambda] > [Functions] > [Create function] に移動します。
- [Author from scratch] をクリックします。
次の構成情報を提供してください。
設定 値 名前 symantec_wss_to_s3ランタイム Python 3.13 アーキテクチャ x86_64 実行ロール SymantecWssToS3Role関数を作成したら、[コード] タブを開き、スタブを削除して次のコード(
symantec_wss_to_s3.py)を貼り付けます。#!/usr/bin/env python3 # Lambda: Pull Symantec WSS logs and store raw payloads to S3 # - Time window via millisecond timestamps for WSS Sync API. # - Preserves vendor-native format (CSV/JSON/ZIP). # - Retries with exponential backoff; unique S3 keys to avoid overwrites. import os, json, time, uuid from urllib.request import Request, urlopen from urllib.error import URLError, HTTPError import boto3 S3_BUCKET = os.environ["S3_BUCKET"] S3_PREFIX = os.environ.get("S3_PREFIX", "symantec/wss/") STATE_KEY = os.environ.get("STATE_KEY", "symantec/wss/state.json") WINDOW_SEC = int(os.environ.get("WINDOW_SECONDS", "3600")) # default 1h HTTP_TIMEOUT= int(os.environ.get("HTTP_TIMEOUT", "60")) WSS_SYNC_URL = os.environ.get("WSS_SYNC_URL", "https://portal.threatpulse.com/reportpod/logs/sync") API_USERNAME = os.environ["WSS_API_USERNAME"] API_PASSWORD = os.environ["WSS_API_PASSWORD"] TOKEN_PARAM = os.environ.get("WSS_TOKEN_PARAM", "none") MAX_RETRIES = int(os.environ.get("MAX_RETRIES", "3")) USER_AGENT = os.environ.get("USER_AGENT", "symantec-wss-to-s3/1.0") s3 = boto3.client("s3") def _load_state(): try: obj = s3.get_object(Bucket=S3_BUCKET, Key=STATE_KEY) return json.loads(obj["Body"].read()) except Exception: return {} def _save_state(st): s3.put_object( Bucket=S3_BUCKET, Key=STATE_KEY, Body=json.dumps(st, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) def _ms_timestamp(ts: float) -> int: """Convert Unix timestamp to milliseconds for WSS API""" return int(ts * 1000) def _fetch_wss_logs(start_ms: int, end_ms: int) -> tuple[bytes, str, str]: # WSS Sync API parameters params = f"startDate={start_ms}&endDate={end_ms}&token={TOKEN_PARAM}" url = f"{WSS_SYNC_URL}?{params}" attempt = 0 while True: req = Request(url, method="GET") req.add_header("User-Agent", USER_AGENT) req.add_header("X-APIUsername", API_USERNAME) req.add_header("X-APIPassword", API_PASSWORD) try: with urlopen(req, timeout=HTTP_TIMEOUT) as r: blob = r.read() content_type = r.headers.get("Content-Type", "application/octet-stream") content_encoding = r.headers.get("Content-Encoding", "") return blob, content_type, content_encoding except (HTTPError, URLError) as e: attempt += 1 print(f"HTTP error on attempt {attempt}: {e}") if attempt > MAX_RETRIES: raise # exponential backoff with jitter time.sleep(min(60, 2 ** attempt) + (time.time() % 1)) def _determine_extension(content_type: str, content_encoding: str) -> str: """Determine file extension based on content type and encoding""" if "zip" in content_type.lower(): return ".zip" if "gzip" in content_type.lower() or content_encoding.lower() == "gzip": return ".gz" if "json" in content_type.lower(): return ".json" if "csv" in content_type.lower(): return ".csv" return ".bin" def _put_wss_data(blob: bytes, content_type: str, content_encoding: str, from_ts: float, to_ts: float) -> str: # Create unique S3 key for WSS data ts_path = time.strftime("%Y/%m/%d", time.gmtime(to_ts)) uniq = f"{int(time.time()*1e6)}_{uuid.uuid4().hex[:8]}" ext = _determine_extension(content_type, content_encoding) key = f"{S3_PREFIX}{ts_path}/symantec_wss_{int(from_ts)}_{int(to_ts)}_{uniq}{ext}" s3.put_object( Bucket=S3_BUCKET, Key=key, Body=blob, ContentType=content_type, Metadata={ 'source': 'symantec-wss', 'from_timestamp': str(int(from_ts)), 'to_timestamp': str(int(to_ts)), 'content_encoding': content_encoding } ) return key def lambda_handler(event=None, context=None): st = _load_state() now = time.time() from_ts = float(st.get("last_to_ts") or (now - WINDOW_SEC)) to_ts = now # Convert to milliseconds for WSS API start_ms = _ms_timestamp(from_ts) end_ms = _ms_timestamp(to_ts) print(f"Fetching Symantec WSS logs from {start_ms} to {end_ms}") blob, content_type, content_encoding = _fetch_wss_logs(start_ms, end_ms) print(f"Retrieved {len(blob)} bytes with content-type: {content_type}") if content_encoding: print(f"Content encoding: {content_encoding}") key = _put_wss_data(blob, content_type, content_encoding, from_ts, to_ts) st["last_to_ts"] = to_ts st["last_successful_run"] = now _save_state(st) return { "statusCode": 200, "body": { "success": True, "s3_key": key, "content_type": content_type, "content_encoding": content_encoding, "from_timestamp": from_ts, "to_timestamp": to_ts, "bytes_retrieved": len(blob) } } if __name__ == "__main__": print(lambda_handler())[構成] > [環境変数] に移動します。
[編集>新しい環境変数を追加] をクリックします。
次の表に示す環境変数を入力し、サンプル値を実際の値に置き換えます。
環境変数
キー 値の例 S3_BUCKETsymantec-wss-logsS3_PREFIXsymantec/wss/STATE_KEYsymantec/wss/state.jsonWINDOW_SECONDS3600HTTP_TIMEOUT60MAX_RETRIES3USER_AGENTsymantec-wss-to-s3/1.0WSS_SYNC_URLhttps://portal.threatpulse.com/reportpod/logs/syncWSS_API_USERNAMEyour-api-username(ステップ 2 から)WSS_API_PASSWORDyour-api-password(ステップ 2 から)WSS_TOKEN_PARAMnone関数が作成されたら、そのページにとどまるか、[Lambda] > [関数] > [your-function] を開きます。
[CONFIGURATION] タブを選択します。
[全般設定] パネルで、[編集] をクリックします。
[Timeout] を [5 minutes (300 seconds)] に変更し、[Save] をクリックします。
EventBridge スケジュールを作成する
- [Amazon EventBridge] > [Scheduler] > [スケジュールの作成] に移動します。
- 次の構成の詳細を入力します。
- 定期的なスケジュール: レート(
1 hour)。 - ターゲット: Lambda 関数
symantec_wss_to_s3。 - 名前:
symantec-wss-1h
- 定期的なスケジュール: レート(
- [スケジュールを作成] をクリックします。
(省略可)Google SecOps の読み取り専用 IAM ユーザーと鍵を作成する
- AWS コンソールで、[IAM] > [ユーザー] に移動します。
- [ユーザーを追加] をクリックします。
- 次の構成の詳細を入力します。
- ユーザー: 「
secops-reader」と入力します。 - アクセスの種類: [アクセスキー - プログラムによるアクセス] を選択します。
- ユーザー: 「
- [ユーザーを作成] をクリックします。
- 最小限の読み取りポリシー(カスタム)を関連付ける: [ユーザー] > [secops-reader] > [権限] > [権限を追加] > [ポリシーを直接関連付ける] > [ポリシーを作成]。
JSON:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::symantec-wss-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::symantec-wss-logs" } ] }名前 =
secops-reader-policy。[ポリシーを作成> 検索/選択> 次へ> 権限を追加] をクリックします。
secops-readerのアクセスキーを作成します。[セキュリティ認証情報] > [アクセスキー] に移動します。[アクセスキーを作成] をクリックします。
CSV をダウンロードします。(これらの値はフィードに貼り付けます)。
Symantec WSS のログを取り込むように Google SecOps でフィードを構成する
- [SIEM 設定] > [フィード] に移動します。
- [+ 新しいフィードを追加] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
Symantec WSS logs)。 - [ソースタイプ] として [Amazon S3 V2] を選択します。
- [Log type] として [Symantec WSS] を選択します。
- [次へ] をクリックします。
- 次の入力パラメータの値を指定します。
- S3 URI:
s3://symantec-wss-logs/symantec/wss/ - Source deletion options: 必要に応じて削除オプションを選択します。
- ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。
- アクセスキー ID: S3 バケットにアクセスできるユーザー アクセスキー。
- シークレット アクセスキー: S3 バケットにアクセスできるユーザーのシークレット キー。
- アセットの名前空間: アセットの名前空間。
- Ingestion labels: このフィードのイベントに適用されるラベル。
- S3 URI:
- [次へ] をクリックします。
- [Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。
UDM マッピング テーブル
| ログフィールド | UDM マッピング | ロジック |
|---|---|---|
| category_id | read_only_udm.metadata.product_event_type | category_id が 1 の場合、read_only_udm.metadata.product_event_type は Security に設定されます。category_id が 5 の場合、read_only_udm.metadata.product_event_type は Policy に設定されます。 |
| collector_device_ip | read_only_udm.principal.ip、read_only_udm.principal.asset.ip | collector_device_ip フィールドの値 |
| connection.bytes_download | read_only_udm.network.received_bytes | connection.bytes_download フィールドの値を整数に変換 |
| connection.bytes_upload | read_only_udm.network.sent_bytes | connection.bytes_upload フィールドの値を整数に変換 |
| connection.dst_ip | read_only_udm.target.ip | connection.dst_ip フィールドの値 |
| connection.dst_location.country | read_only_udm.target.location.country_or_region | connection.dst_location.country フィールドの値 |
| connection.dst_name | read_only_udm.target.hostname | connection.dst_name フィールドの値 |
| connection.dst_port | read_only_udm.target.port | connection.dst_port フィールドの値を整数に変換 |
| connection.http_status | read_only_udm.network.http.response_code | connection.http_status フィールドの値を整数に変換 |
| connection.http_user_agent | read_only_udm.network.http.user_agent | connection.http_user_agent フィールドの値 |
| connection.src_ip | read_only_udm.principal.ip、read_only_udm.src.ip | connection.src_ip フィールドの値。src_ip または collector_device_ip が空でない場合は、read_only_udm.src.ip にマッピングされます。 |
| connection.tls.version | read_only_udm.network.tls.version_protocol | connection.tls.version フィールドの値 |
| connection.url.host | read_only_udm.target.hostname | connection.url.host フィールドの値 |
| connection.url.method | read_only_udm.network.http.method | connection.url.method フィールドの値 |
| connection.url.path | read_only_udm.target.url | connection.url.path フィールドの値 |
| connection.url.text | read_only_udm.target.url | connection.url.text フィールドの値 |
| cs_connection_negotiated_cipher | read_only_udm.network.tls.cipher | cs_connection_negotiated_cipher フィールドの値 |
| cs_icap_status | read_only_udm.security_result.description | cs_icap_status フィールドの値 |
| device_id | read_only_udm.target.resource.id、read_only_udm.target.resource.product_object_id | device_id フィールドの値 |
| device_ip | read_only_udm.intermediary.ip、read_only_udm.intermediary.asset.ip | device_ip フィールドの値 |
| device_time | read_only_udm.metadata.collected_timestamp、read_only_udm.metadata.event_timestamp | device_time フィールドの値が文字列に変換されます。when が空の場合、read_only_udm.metadata.event_timestamp にマッピングされます |
| hostname | read_only_udm.principal.hostname、read_only_udm.principal.asset.hostname | ホスト名フィールドの値 |
| log_time | read_only_udm.metadata.event_timestamp | log_time フィールドの値がタイムスタンプに変換されます。when と device_time が空の場合、read_only_udm.metadata.event_timestamp にマッピングされます。 |
| msg_desc | read_only_udm.metadata.description | msg_desc フィールドの値 |
| os_details | read_only_udm.target.asset.platform_software.platform、read_only_udm.target.asset.platform_software.platform_version | os_details フィールドの値。os_details が空でない場合は、解析されて os_name と os_ver が抽出されます。os_name に Windows が含まれている場合、read_only_udm.target.asset.platform_software.platform は WINDOWS に設定されます。os_ver は read_only_udm.target.asset.platform_software.platform_version にマッピングされます |
| product_data.cs(Referer) | read_only_udm.network.http.referral_url | product_data.cs(Referer)フィールドの値 |
| product_data.r-supplier-country | read_only_udm.principal.location.country_or_region | product_data.r-supplier-country フィールドの値 |
| product_data.s-supplier-ip | read_only_udm.intermediary.ip、read_only_udm.intermediary.asset.ip | product_data.s-supplier-ip フィールドの値 |
| product_data.x-bluecoat-application-name | read_only_udm.target.application | product_data.x-bluecoat-application-name フィールドの値 |
| product_data.x-bluecoat-transaction-uuid | read_only_udm.metadata.product_log_id | product_data.x-bluecoat-transaction-uuid フィールドの値 |
| product_data.x-client-agent-sw | read_only_udm.observer.platform_version | product_data.x-client-agent-sw フィールドの値 |
| product_data.x-client-agent-type | read_only_udm.observer.application | product_data.x-client-agent-type フィールドの値 |
| product_data.x-client-device-id | read_only_udm.target.resource.type、read_only_udm.target.resource.id、read_only_udm.target.resource.product_object_id | 空でない場合、read_only_udm.target.resource.type は DEVICE に設定されます。product_data.x-client-device-id フィールドの値が read_only_udm.target.resource.id と read_only_udm.target.resource.product_object_id にマッピングされる |
| product_data.x-client-device-name | read_only_udm.src.hostname、read_only_udm.src.asset.hostname | product_data.x-client-device-name フィールドの値 |
| product_data.x-cs-client-ip-country | read_only_udm.target.location.country_or_region | product_data.x-cs-client-ip-country フィールドの値 |
| product_data.x-cs-connection-negotiated-cipher | read_only_udm.network.tls.cipher | product_data.x-cs-connection-negotiated-cipher フィールドの値 |
| product_data.x-cs-connection-negotiated-ssl-version | read_only_udm.network.tls.version_protocol | product_data.x-cs-connection-negotiated-ssl-version フィールドの値 |
| product_data.x-exception-id | read_only_udm.security_result.summary | product_data.x-exception-id フィールドの値 |
| product_data.x-rs-certificate-hostname | read_only_udm.network.tls.client.server_name | product_data.x-rs-certificate-hostname フィールドの値 |
| product_data.x-rs-certificate-hostname-categories | read_only_udm.security_result.category_details | product_data.x-rs-certificate-hostname-categories フィールドの値 |
| product_data.x-rs-certificate-observed-errors | read_only_udm.network.tls.server.certificate.issuer | product_data.x-rs-certificate-observed-errors フィールドの値 |
| product_data.x-rs-certificate-validate-status | read_only_udm.network.tls.server.certificate.subject | product_data.x-rs-certificate-validate-status フィールドの値 |
| product_name | read_only_udm.metadata.product_name | product_name フィールドの値 |
| product_ver | read_only_udm.metadata.product_version | product_ver フィールドの値 |
| proxy_connection.src_ip | read_only_udm.intermediary.ip、read_only_udm.intermediary.asset.ip | proxy_connection.src_ip フィールドの値 |
| received_bytes | read_only_udm.network.received_bytes | received_bytes フィールドの値が整数に変換された |
| ref_uid | read_only_udm.metadata.product_log_id | ref_uid フィールドの値 |
| s_action | read_only_udm.metadata.description | s_action フィールドの値 |
| sent_bytes | read_only_udm.network.sent_bytes | sent_bytes フィールドの値が整数に変換される |
| severity_id | read_only_udm.security_result.severity | severity_id が 1 または 2 の場合、read_only_udm.security_result.severity は LOW に設定されます。severity_id が 3 または 4 の場合、read_only_udm.security_result.severity は MEDIUM に設定されます。severity_id が 5 または 6 の場合、read_only_udm.security_result.severity は HIGH に設定されます。 |
| supplier_country | read_only_udm.principal.location.country_or_region | supplier_country フィールドの値 |
| target_ip | read_only_udm.target.ip、read_only_udm.target.asset.ip | target_ip フィールドの値 |
| user.full_name | read_only_udm.principal.user.user_display_name | user.full_name フィールドの値 |
| user.name | read_only_udm.principal.user.user_display_name | user.name フィールドの値 |
| user_name | read_only_udm.principal.user.user_display_name | user_name フィールドの値 |
| uuid | read_only_udm.metadata.product_log_id | uuid フィールドの値 |
| when | read_only_udm.metadata.event_timestamp | when フィールドの値がタイムスタンプに変換される |
| read_only_udm.metadata.event_type | ホスト名が空で、connection.dst_ip が空でない場合は NETWORK_UNCATEGORIZED に設定します。ホスト名が空でない場合は SCAN_NETWORK に設定します。has_principal と has_target が true の場合、NETWORK_CONNECTION に設定します。has_principal が true で、has_target が false の場合、STATUS_UPDATE に設定します。has_principal と has_target が false の場合、GENERIC_EVENT に設定します |
|
| read_only_udm.metadata.log_type | 常に SYMANTEC_WSS に設定 |
|
| read_only_udm.metadata.vendor_name | 常に SYMANTEC に設定 |
|
| read_only_udm.security_result.action | product_data.sc-filter_result が OBSERVED または PROXIED の場合、ALLOW に設定します。product_data.sc-filter_result が DENIED の場合、BLOCK に設定します |
|
| read_only_udm.security_result.action_details | product_data.sc-filter_result フィールドの値 | |
| read_only_udm.target.resource.type | product_data.x-client-device-id が空でない場合は DEVICE に設定 |
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。