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、トークン)を収集する

  1. 管理者として Symantec Web Security Service ポータルにログインします。
  2. [アカウント]> [API 認証情報] に移動します。
  3. [追加] をクリックします。
  4. 次の構成の詳細を入力します。
    • API 名: わかりやすい名前を入力します(例: Google SecOps Integration)。
    • 説明: API 認証情報の説明を入力します。
  5. [保存] をクリックし、生成された API 認証情報を安全にコピーします。
  6. WSS ポータル URLSync API エンドポイントを記録します。
  7. 次の詳細をコピーして安全な場所に保存します。
    • WSS_API_USERNAME
    • WSS_API_PASSWORD
    • WSS_SYNC_URL

Google SecOps 用に AWS S3 バケットと IAM を構成する

  1. バケットの作成のユーザーガイドに沿って、Amazon S3 バケットを作成します。
  2. 後で参照できるように、バケットの名前リージョンを保存します(例: symantec-wss-logs)。
  3. IAM ユーザーの作成のユーザーガイドに沿って、ユーザーを作成します。
  4. 作成したユーザーを選択します。
  5. [セキュリティ認証情報] タブを選択します。
  6. [アクセスキー] セクションで [アクセスキーを作成] をクリックします。
  7. [ユースケース] として [サードパーティ サービス] を選択します。
  8. [次へ] をクリックします。
  9. 省略可: 説明タグを追加します。
  10. [アクセスキーを作成] をクリックします。
  11. [CSV ファイルをダウンロード] をクリックし、[アクセスキー] と [シークレット アクセスキー] を保存して、今後の参照に備えます。
  12. [完了] をクリックします。
  13. [権限] タブを選択します。
  14. [権限ポリシー] セクションの [権限を追加] をクリックします。
  15. [権限を追加] を選択します。
  16. [ポリシーを直接アタッチする] を選択します。
  17. AmazonS3FullAccess ポリシーを検索します。
  18. ポリシーを選択します。
  19. [次へ] をクリックします。
  20. [権限を追加] をクリックします。

S3 アップロードの IAM ポリシーとロールを構成する

  1. AWS コンソールで、[IAM] > [ポリシー] に移動します。
  2. [ポリシーを作成> [JSON] タブ] をクリックします。
  3. 次のポリシーをコピーして貼り付けます。
  4. ポリシー 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"
        }
      ]
    }
    
  5. [次へ] > [ポリシーを作成] をクリックします。

  6. [IAM] > [ロール] > [ロールの作成] > [AWS サービス] > [Lambda] に移動します。

  7. 新しく作成したポリシーを関連付けます。

  8. ロールに「SymantecWssToS3Role」という名前を付けて、[ロールを作成] をクリックします。

Lambda 関数を作成する

  1. AWS コンソールで、[Lambda] > [Functions] > [Create function] に移動します。
  2. [Author from scratch] をクリックします。
  3. 次の構成情報を提供してください。

    設定
    名前 symantec_wss_to_s3
    ランタイム Python 3.13
    アーキテクチャ x86_64
    実行ロール SymantecWssToS3Role
  4. 関数を作成したら、[コード] タブを開き、スタブを削除して次のコード(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())
    
  5. [構成] > [環境変数] に移動します。

  6. [編集>新しい環境変数を追加] をクリックします。

  7. 次の表に示す環境変数を入力し、サンプル値を実際の値に置き換えます。

    環境変数

    キー 値の例
    S3_BUCKET symantec-wss-logs
    S3_PREFIX symantec/wss/
    STATE_KEY symantec/wss/state.json
    WINDOW_SECONDS 3600
    HTTP_TIMEOUT 60
    MAX_RETRIES 3
    USER_AGENT symantec-wss-to-s3/1.0
    WSS_SYNC_URL https://portal.threatpulse.com/reportpod/logs/sync
    WSS_API_USERNAME your-api-username(ステップ 2 から)
    WSS_API_PASSWORD your-api-password(ステップ 2 から)
    WSS_TOKEN_PARAM none
  8. 関数が作成されたら、そのページにとどまるか、[Lambda] > [関数] > [your-function] を開きます。

  9. [CONFIGURATION] タブを選択します。

  10. [全般設定] パネルで、[編集] をクリックします。

  11. [Timeout] を [5 minutes (300 seconds)] に変更し、[Save] をクリックします。

EventBridge スケジュールを作成する

  1. [Amazon EventBridge] > [Scheduler] > [スケジュールの作成] に移動します。
  2. 次の構成の詳細を入力します。
    • 定期的なスケジュール: レート1 hour)。
    • ターゲット: Lambda 関数 symantec_wss_to_s3
    • 名前: symantec-wss-1h
  3. [スケジュールを作成] をクリックします。

(省略可)Google SecOps の読み取り専用 IAM ユーザーと鍵を作成する

  1. AWS コンソールで、[IAM] > [ユーザー] に移動します。
  2. [ユーザーを追加] をクリックします。
  3. 次の構成の詳細を入力します。
    • ユーザー: 「secops-reader」と入力します。
    • アクセスの種類: [アクセスキー - プログラムによるアクセス] を選択します。
  4. [ユーザーを作成] をクリックします。
  5. 最小限の読み取りポリシー(カスタム)を関連付ける: [ユーザー] > [secops-reader] > [権限] > [権限を追加] > [ポリシーを直接関連付ける] > [ポリシーを作成]
  6. 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"
        }
      ]
    }
    
  7. 名前 = secops-reader-policy

  8. [ポリシーを作成> 検索/選択> 次へ> 権限を追加] をクリックします。

  9. secops-reader のアクセスキーを作成します。[セキュリティ認証情報] > [アクセスキー] に移動します。

  10. [アクセスキーを作成] をクリックします。

  11. CSV をダウンロードします。(これらの値はフィードに貼り付けます)。

Symantec WSS のログを取り込むように Google SecOps でフィードを構成する

  1. [SIEM 設定] > [フィード] に移動します。
  2. [+ 新しいフィードを追加] をクリックします。
  3. [フィード名] フィールドに、フィードの名前を入力します(例: Symantec WSS logs)。
  4. [ソースタイプ] として [Amazon S3 V2] を選択します。
  5. [Log type] として [Symantec WSS] を選択します。
  6. [次へ] をクリックします。
  7. 次の入力パラメータの値を指定します。
    • S3 URI: s3://symantec-wss-logs/symantec/wss/
    • Source deletion options: 必要に応じて削除オプションを選択します。
    • ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。
    • アクセスキー ID: S3 バケットにアクセスできるユーザー アクセスキー。
    • シークレット アクセスキー: S3 バケットにアクセスできるユーザーのシークレット キー。
    • アセットの名前空間: アセットの名前空間
    • Ingestion labels: このフィードのイベントに適用されるラベル。
  8. [次へ] をクリックします。
  9. [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 のプロフェッショナルから回答を得ることができます。