Mengumpulkan log Symantec WSS

Didukung di:

Dokumen ini menjelaskan cara menyerap log Symantec Web Security Service (WSS) ke Google Security Operations menggunakan Amazon S3. Pengurai pertama-tama mencoba mengurai pesan log sebagai JSON. Jika gagal, alat ini akan menggunakan serangkaian pola grok yang semakin spesifik untuk mengekstrak kolom dari teks mentah, yang pada akhirnya memetakan data yang diekstrak ke Model Data Terpadu (UDM).

Sebelum memulai

Pastikan Anda memenuhi prasyarat berikut:

  • Instance Google SecOps.
  • Akses istimewa ke Symantec Web Security Service.
  • Akses istimewa ke AWS (S3, Identity and Access Management (IAM), Lambda, EventBridge).

Kumpulkan prasyarat Symantec WSS (ID, kunci API, ID org, token)

  1. Login ke Symantec Web Security Service Portal sebagai administrator.
  2. Buka Account > API Credentials.
  3. Klik Tambahkan.
  4. Berikan detail konfigurasi berikut:
    • Nama API: Masukkan nama deskriptif (misalnya, Google SecOps Integration).
    • Deskripsi: Masukkan deskripsi untuk kredensial API.
  5. Klik Simpan dan salin kredensial API yang dibuat dengan aman.
  6. Catat URL Portal WSS dan endpoint Sync API Anda.
  7. Salin dan simpan detail berikut di lokasi yang aman:
    • WSS_API_USERNAME.
    • WSS_API_PASSWORD.
    • WSS_SYNC_URL.

Mengonfigurasi bucket AWS S3 dan IAM untuk Google SecOps

  1. Buat bucket Amazon S3 dengan mengikuti panduan pengguna ini: Membuat bucket
  2. Simpan Name dan Region bucket untuk referensi di masa mendatang (misalnya, symantec-wss-logs).
  3. Buat Pengguna dengan mengikuti panduan pengguna ini: Membuat pengguna IAM.
  4. Pilih Pengguna yang dibuat.
  5. Pilih tab Kredensial keamanan.
  6. Klik Create Access Key di bagian Access Keys.
  7. Pilih Layanan pihak ketiga sebagai Kasus penggunaan.
  8. Klik Berikutnya.
  9. Opsional: Tambahkan tag deskripsi.
  10. Klik Create access key.
  11. Klik Download CSV file untuk menyimpan Access Key dan Secret Access Key untuk referensi di masa mendatang.
  12. Klik Selesai.
  13. Pilih tab Permissions.
  14. Klik Tambahkan izin di bagian Kebijakan izin.
  15. Pilih Tambahkan izin.
  16. Pilih Lampirkan kebijakan secara langsung.
  17. Cari kebijakan AmazonS3FullAccess.
  18. Pilih kebijakan.
  19. Klik Berikutnya.
  20. Klik Add permissions.

Mengonfigurasi kebijakan dan peran IAM untuk upload S3

  1. Di konsol AWS, buka IAM > Policies.
  2. Klik Buat kebijakan > tab JSON.
  3. Salin dan tempel kebijakan berikut.
  4. Policy JSON (ganti symantec-wss-logs jika Anda memasukkan nama bucket yang berbeda):

    {
      "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. Klik Berikutnya > Buat kebijakan.

  6. Buka IAM > Roles > Create role > AWS service > Lambda.

  7. Lampirkan kebijakan yang baru dibuat.

  8. Beri nama peran SymantecWssToS3Role, lalu klik Buat peran.

Buat fungsi Lambda

  1. Di Konsol AWS, buka Lambda > Functions > Create function.
  2. Klik Buat dari awal.
  3. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Nama symantec_wss_to_s3
    Runtime Python 3.13
    Arsitektur x86_64
    Peran eksekusi SymantecWssToS3Role
  4. Setelah fungsi dibuat, buka tab Code, hapus stub, dan tempelkan kode berikut (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. Buka Configuration > Environment variables.

  6. Klik Edit > Tambahkan variabel lingkungan baru.

  7. Masukkan variabel lingkungan yang diberikan dalam tabel berikut, ganti dengan nilai contoh menggunakan nilai Anda.

    Variabel lingkungan

    Kunci Nilai contoh
    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 (dari langkah 2)
    WSS_API_PASSWORD your-api-password (dari langkah 2)
    WSS_TOKEN_PARAM none
  8. Setelah fungsi dibuat, tetap buka halamannya (atau buka Lambda > Functions > your-function).

  9. Pilih tab Configuration

  10. Di panel Konfigurasi umum, klik Edit.

  11. Ubah Waktu Tunggu menjadi 5 menit (300 detik), lalu klik Simpan.

Membuat jadwal EventBridge

  1. Buka Amazon EventBridge > Scheduler > Create schedule.
  2. Berikan detail konfigurasi berikut:
    • Jadwal berulang: Tarif (1 hour).
    • Target: Fungsi Lambda Anda symantec_wss_to_s3.
    • Name: symantec-wss-1h.
  3. Klik Buat jadwal.

(Opsional) Buat pengguna dan kunci IAM hanya baca untuk Google SecOps

  1. Di AWS Console, buka IAM > Users.
  2. Klik Add users.
  3. Berikan detail konfigurasi berikut:
    • Pengguna: Masukkan secops-reader.
    • Jenis akses: Pilih Kunci akses – Akses terprogram.
  4. Klik Buat pengguna.
  5. Lampirkan kebijakan baca minimal (kustom): Pengguna > secops-reader > Izin > Tambahkan izin > Lampirkan kebijakan secara langsung > Buat kebijakan.
  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. Nama = secops-reader-policy.

  8. Klik Buat kebijakan > cari/pilih > Berikutnya > Tambahkan izin.

  9. Buat kunci akses untuk secops-reader: Kredensial keamanan > Kunci akses.

  10. Klik Create access key.

  11. Download CSV. (Anda akan menempelkan nilai ini ke feed).

Mengonfigurasi feed di Google SecOps untuk menyerap log Symantec WSS

  1. Buka Setelan SIEM > Feed.
  2. Klik + Tambahkan Feed Baru.
  3. Di kolom Nama feed, masukkan nama untuk feed (misalnya, Symantec WSS logs).
  4. Pilih Amazon S3 V2 sebagai Jenis sumber.
  5. Pilih Symantec WSS sebagai Jenis log.
  6. Klik Berikutnya.
  7. Tentukan nilai untuk parameter input berikut:
    • URI S3: s3://symantec-wss-logs/symantec/wss/
    • Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda.
    • Usia File Maksimum: Menyertakan file yang diubah dalam jumlah hari terakhir. Defaultnya adalah 180 hari.
    • ID Kunci Akses: Kunci akses pengguna dengan akses ke bucket S3.
    • Kunci Akses Rahasia: Kunci rahasia pengguna dengan akses ke bucket S3.
    • Namespace aset: Namespace aset.
    • Label penyerapan: Label yang diterapkan ke peristiwa dari feed ini.
  8. Klik Berikutnya.
  9. Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.

Tabel pemetaan UDM

Kolom log Pemetaan UDM Logika
category_id read_only_udm.metadata.product_event_type Jika category_id adalah 1, maka read_only_udm.metadata.product_event_type ditetapkan ke Security. Jika category_id adalah 5, maka read_only_udm.metadata.product_event_type ditetapkan ke Policy
collector_device_ip read_only_udm.principal.ip, read_only_udm.principal.asset.ip Nilai kolom collector_device_ip
connection.bytes_download read_only_udm.network.received_bytes Nilai kolom connection.bytes_download dikonversi menjadi bilangan bulat
connection.bytes_upload read_only_udm.network.sent_bytes Nilai kolom connection.bytes_upload dikonversi menjadi bilangan bulat
connection.dst_ip read_only_udm.target.ip Nilai kolom connection.dst_ip
connection.dst_location.country read_only_udm.target.location.country_or_region Nilai kolom connection.dst_location.country
connection.dst_name read_only_udm.target.hostname Nilai kolom connection.dst_name
connection.dst_port read_only_udm.target.port Nilai kolom connection.dst_port dikonversi menjadi bilangan bulat
connection.http_status read_only_udm.network.http.response_code Nilai kolom connection.http_status dikonversi menjadi bilangan bulat
connection.http_user_agent read_only_udm.network.http.user_agent Nilai kolom connection.http_user_agent
connection.src_ip read_only_udm.principal.ip, read_only_udm.src.ip Nilai kolom connection.src_ip. Jika src_ip atau collector_device_ip tidak kosong, maka akan dipetakan ke read_only_udm.src.ip
connection.tls.version read_only_udm.network.tls.version_protocol Nilai kolom connection.tls.version
connection.url.host read_only_udm.target.hostname Nilai kolom connection.url.host
connection.url.method read_only_udm.network.http.method Nilai kolom connection.url.method
connection.url.path read_only_udm.target.url Nilai kolom connection.url.path
connection.url.text read_only_udm.target.url Nilai kolom connection.url.text
cs_connection_negotiated_cipher read_only_udm.network.tls.cipher Nilai kolom cs_connection_negotiated_cipher
cs_icap_status read_only_udm.security_result.description Nilai kolom cs_icap_status
device_id read_only_udm.target.resource.id, read_only_udm.target.resource.product_object_id Nilai kolom device_id
device_ip read_only_udm.intermediary.ip, read_only_udm.intermediary.asset.ip Nilai kolom device_ip
device_time read_only_udm.metadata.collected_timestamp, read_only_udm.metadata.event_timestamp Nilai kolom device_time dikonversi menjadi string. Jika when kosong, maka dipetakan ke read_only_udm.metadata.event_timestamp
hostname read_only_udm.principal.hostname, read_only_udm.principal.asset.hostname Nilai kolom nama host
log_time read_only_udm.metadata.event_timestamp Nilai kolom log_time dikonversi menjadi stempel waktu. Jika when dan device_time kosong, maka akan dipetakan ke read_only_udm.metadata.event_timestamp
msg_desc read_only_udm.metadata.description Nilai kolom msg_desc
os_details read_only_udm.target.asset.platform_software.platform, read_only_udm.target.asset.platform_software.platform_version Nilai kolom os_details. Jika os_details tidak kosong, maka os_details akan diuraikan untuk mengekstrak os_name dan os_ver. Jika os_name berisi Windows, maka read_only_udm.target.asset.platform_software.platform disetel ke WINDOWS. os_ver dipetakan ke read_only_udm.target.asset.platform_software.platform_version
product_data.cs(Referer) read_only_udm.network.http.referral_url Nilai kolom product_data.cs(Referer)
product_data.r-supplier-country read_only_udm.principal.location.country_or_region Nilai kolom product_data.r-supplier-country
product_data.s-supplier-ip read_only_udm.intermediary.ip, read_only_udm.intermediary.asset.ip Nilai kolom product_data.s-supplier-ip
product_data.x-bluecoat-application-name read_only_udm.target.application Nilai kolom product_data.x-bluecoat-application-name
product_data.x-bluecoat-transaction-uuid read_only_udm.metadata.product_log_id Nilai kolom product_data.x-bluecoat-transaction-uuid
product_data.x-client-agent-sw read_only_udm.observer.platform_version Nilai kolom product_data.x-client-agent-sw
product_data.x-client-agent-type read_only_udm.observer.application Nilai kolom 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 Jika tidak kosong, read_only_udm.target.resource.type disetel ke DEVICE. Nilai kolom product_data.x-client-device-id dipetakan ke read_only_udm.target.resource.id dan 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 Nilai kolom product_data.x-client-device-name
product_data.x-cs-client-ip-country read_only_udm.target.location.country_or_region Nilai kolom product_data.x-cs-client-ip-country
product_data.x-cs-connection-negotiated-cipher read_only_udm.network.tls.cipher Nilai kolom product_data.x-cs-connection-negotiated-cipher
product_data.x-cs-connection-negotiated-ssl-version read_only_udm.network.tls.version_protocol Nilai kolom product_data.x-cs-connection-negotiated-ssl-version
product_data.x-exception-id read_only_udm.security_result.summary Nilai kolom product_data.x-exception-id
product_data.x-rs-certificate-hostname read_only_udm.network.tls.client.server_name Nilai kolom product_data.x-rs-certificate-hostname
product_data.x-rs-certificate-hostname-categories read_only_udm.security_result.category_details Nilai kolom product_data.x-rs-certificate-hostname-categories
product_data.x-rs-certificate-observed-errors read_only_udm.network.tls.server.certificate.issuer Nilai kolom product_data.x-rs-certificate-observed-errors
product_data.x-rs-certificate-validate-status read_only_udm.network.tls.server.certificate.subject Nilai kolom product_data.x-rs-certificate-validate-status
product_name read_only_udm.metadata.product_name Nilai kolom product_name
product_ver read_only_udm.metadata.product_version Nilai kolom product_ver
proxy_connection.src_ip read_only_udm.intermediary.ip, read_only_udm.intermediary.asset.ip Nilai kolom proxy_connection.src_ip
received_bytes read_only_udm.network.received_bytes Nilai kolom received_bytes dikonversi menjadi bilangan bulat
ref_uid read_only_udm.metadata.product_log_id Nilai kolom ref_uid
s_action read_only_udm.metadata.description Nilai kolom s_action
sent_bytes read_only_udm.network.sent_bytes Nilai kolom sent_bytes dikonversi menjadi bilangan bulat
severity_id read_only_udm.security_result.severity Jika severity_id adalah 1 atau 2, maka read_only_udm.security_result.severity disetel ke LOW. Jika severity_id adalah 3 atau 4, maka read_only_udm.security_result.severity disetel ke MEDIUM. Jika severity_id adalah 5 atau 6, maka read_only_udm.security_result.severity akan ditetapkan ke HIGH
supplier_country read_only_udm.principal.location.country_or_region Nilai kolom supplier_country
target_ip read_only_udm.target.ip, read_only_udm.target.asset.ip Nilai kolom target_ip
user.full_name read_only_udm.principal.user.user_display_name Nilai kolom user.full_name
user.name read_only_udm.principal.user.user_display_name Nilai kolom user.name
user_name read_only_udm.principal.user.user_display_name Nilai kolom user_name
uuid read_only_udm.metadata.product_log_id Nilai kolom uuid
kapan read_only_udm.metadata.event_timestamp Nilai kolom when dikonversi menjadi stempel waktu
read_only_udm.metadata.event_type Disetel ke NETWORK_UNCATEGORIZED jika hostname kosong dan connection.dst_ip tidak kosong. Tetapkan ke SCAN_NETWORK jika nama host tidak kosong. Tetapkan ke NETWORK_CONNECTION jika has_principal dan has_target adalah true. Tetapkan ke STATUS_UPDATE jika has_principal adalah true dan has_target adalah false. Tetapkan ke GENERIC_EVENT jika has_principal dan has_target adalah false
read_only_udm.metadata.log_type Selalu ditetapkan ke SYMANTEC_WSS
read_only_udm.metadata.vendor_name Selalu ditetapkan ke SYMANTEC
read_only_udm.security_result.action Tetapkan ke ALLOW jika product_data.sc-filter_result adalah OBSERVED atau PROXIED. Tetapkan ke BLOCK jika product_data.sc-filter_result adalah DENIED
read_only_udm.security_result.action_details Nilai kolom product_data.sc-filter_result
read_only_udm.target.resource.type Tetapkan ke DEVICE jika product_data.x-client-device-id tidak kosong

Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.