Mengumpulkan dataset inti Code42 Incydr
Dokumen ini menjelaskan cara menyerap set data inti Code42 Incydr (Pengguna, Sesi, Audit, Kasus, dan secara opsional Peristiwa File) ke Google Security Operations menggunakan Amazon S3.
Sebelum memulai
- Instance Google SecOps
- Akses istimewa ke Code42 Incydr
- Akses istimewa ke AWS (S3, IAM, Lambda, EventBridge)
Kumpulkan prasyarat sumber (ID, kunci API, ID organisasi, token)
- Login ke UI web Code42 Incydr.
- Buka Administrasi > Integrasi > Klien API.
- Buat Klien baru.
- Salin dan simpan detail berikut di lokasi yang aman:
- Client ID.
- Rahasia Klien.
- URL Dasar: (misalnya,
https://api.us.code42.com
,https://api.us2.code42.com
,https://api.ie.code42.com
,https://api.gov.code42.com
).
Mengonfigurasi bucket AWS S3 dan IAM untuk Google SecOps
- Buat bucket Amazon S3 dengan mengikuti panduan pengguna ini: Membuat bucket.
- Simpan Nama dan Region bucket untuk digunakan nanti.
- Buat pengguna dengan mengikuti panduan pengguna ini: Membuat pengguna IAM.
- Pilih Pengguna yang dibuat.
- Pilih tab Kredensial keamanan.
- Klik Create Access Key di bagian Access Keys.
- Pilih Layanan pihak ketiga sebagai Kasus penggunaan.
- Klik Berikutnya.
- Opsional: tambahkan tag deskripsi.
- Klik Create access key.
- Klik Download CSV file untuk menyimpan Access Key dan Secret Access Key untuk digunakan nanti.
- Klik Selesai.
- Pilih tab Izin.
- Klik Tambahkan izin di bagian Kebijakan izin.
- Pilih Tambahkan izin.
- Pilih Lampirkan kebijakan secara langsung
- Telusuri dan pilih kebijakan AmazonS3FullAccess.
- Klik Berikutnya.
- Klik Add permissions.
Menyiapkan AWS Lambda untuk melakukan polling Code42 Incydr (tanpa transformasi)
- Di Konsol AWS, buka Lambda > Functions > Create function.
- Klik Buat dari awal.
- Berikan detail konfigurasi berikut:
- Nama: Masukkan nama yang unik dan bermakna (misalnya,
code42-incydr-pull
) - Runtime: Pilih Python 3.13.
- Izin: Pilih peran dengan s3:PutObject dan Cloudwatch.
- Nama: Masukkan nama yang unik dan bermakna (misalnya,
- Klik Create function.
- Pilih Konfigurasi > Konfigurasi umum > Edit.
- Konfigurasi Timeout=5m dan Memory=1024 MB.
- Klik Simpan.
- Pilih Configuration > Environment variables > Edit > Add.
INCYDR_BASE_URL
=https://api.us.code42.com
INCYDR_CLIENT_ID
=<Client ID>
INCYDR_CLIENT_SECRET
=<Client Secret>
S3_BUCKET
=code42-incydr
S3_PREFIX
=code42/
PAGE_SIZE
=500
LOOKBACK_MINUTES
=60
STREAMS
=users,sessions,audit,cases
- Opsional:
FE_ADV_QUERY_JSON
= `` - Opsional:
FE_PAGE_SIZE
=1000
- Klik Simpan.
Pilih Code dan masukkan kode Python berikut:
import base64, json, os, time from datetime import datetime, timedelta, timezone from urllib.parse import urlencode from urllib.request import Request, urlopen import boto3 BASE = os.environ["INCYDR_BASE_URL"].rstrip("/") CID = os.environ["INCYDR_CLIENT_ID"] CSECRET = os.environ["INCYDR_CLIENT_SECRET"] BUCKET = os.environ["S3_BUCKET"] PREFIX_BASE = os.environ.get("S3_PREFIX", "code42/") PAGE_SIZE = int(os.environ.get("PAGE_SIZE", "500")) LOOKBACK_MINUTES = int(os.environ.get("LOOKBACK_MINUTES", "60")) STREAMS = [s.strip() for s in os.environ.get("STREAMS", "users").split(",") if s.strip()] FE_ADV_QUERY_JSON = os.environ.get("FE_ADV_QUERY_JSON", "").strip() FE_PAGE_SIZE = int(os.environ.get("FE_PAGE_SIZE", "1000")) s3 = boto3.client("s3") def now_utc(): return datetime.now(timezone.utc) def iso_minus(minutes: int): return (now_utc() - timedelta(minutes=minutes)).strftime("%Y-%m-%dT%H:%M:%SZ") def put_bytes(key: str, body: bytes): s3.put_object(Bucket=BUCKET, Key=key, Body=body) def put_json(prefix: str, page_label: str, data): ts = now_utc().strftime("%Y/%m/%d/%H%M%S") key = f"{PREFIX_BASE}{prefix}{ts}-{page_label}.json" put_bytes(key, json.dumps(data).encode("utf-8")) return key def auth_header(): auth = base64.b64encode(f"{CID}:{CSECRET}".encode()).decode() req = Request(f"{BASE}/v1/oauth", data=b"", method="POST") req.add_header("Authorization", f"Basic {auth}") req.add_header("Accept", "application/json") with urlopen(req, timeout=30) as r: data = json.loads(r.read().decode()) return {"Authorization": f"Bearer {data['access_token']}", "Accept": "application/json"} def http_get(path: str, params: dict | None = None, headers: dict | None = None): url = f"{BASE}{path}" if params: url += ("?" + urlencode(params)) req = Request(url, method="GET") for k, v in (headers or {}).items(): req.add_header(k, v) with urlopen(req, timeout=60) as r: return r.read() def http_post_json(path: str, body: dict, headers: dict | None = None): url = f"{BASE}{path}" req = Request(url, data=json.dumps(body).encode("utf-8"), method="POST") req.add_header("Content-Type", "application/json") for k, v in (headers or {}).items(): req.add_header(k, v) with urlopen(req, timeout=120) as r: return r.read() # USERS (/v1/users) def pull_users(hdrs): next_token = None pages = 0 while True: params = {"active": "true", "blocked": "false", "pageSize": PAGE_SIZE} if next_token: params["pgToken"] = next_token raw = http_get("/v1/users", params, hdrs) data = json.loads(raw.decode()) put_json("users/", f"users-page-{pages}", data) pages += 1 next_token = data.get("nextPgToken") or data.get("next_pg_token") if not next_token: break return pages # SESSIONS (/v1/sessions) — alerts live inside sessions def pull_sessions(hdrs): start_iso = iso_minus(LOOKBACK_MINUTES) next_token = None pages = 0 while True: params = { "hasAlerts": "true", "startTime": start_iso, "pgSize": PAGE_SIZE, } if next_token: params["pgToken"] = next_token raw = http_get("/v1/sessions", params, hdrs) data = json.loads(raw.decode()) put_json("sessions/", f"sessions-page-{pages}", data) pages += 1 next_token = data.get("nextPgToken") or data.get("next_page_token") if not next_token: break return pages # AUDIT LOG (/v1/audit) — CSV export or paged JSON; write as received def pull_audit(hdrs): start_iso = iso_minus(LOOKBACK_MINUTES) next_token = None pages = 0 while True: params = {"startTime": start_iso, "pgSize": PAGE_SIZE} if next_token: params["pgToken"] = next_token raw = http_get("/v1/audit", params, hdrs) try: data = json.loads(raw.decode()) put_json("audit/", f"audit-page-{pages}", data) next_token = data.get("nextPgToken") or data.get("next_page_token") pages += 1 if not next_token: break except Exception: ts = now_utc().strftime("%Y/%m/%d/%H%M%S") key = f"{PREFIX_BASE}audit/{ts}-audit-export.bin" put_bytes(key, raw) pages += 1 break return pages # CASES (/v1/cases) def pull_cases(hdrs): next_token = None pages = 0 while True: params = {"pgSize": PAGE_SIZE} if next_token: params["pgToken"] = next_token raw = http_get("/v1/cases", params, hdrs) data = json.loads(raw.decode()) put_json("cases/", f"cases-page-{pages}", data) pages += 1 next_token = data.get("nextPgToken") or data.get("next_page_token") if not next_token: break return pages # FILE EVENTS (/v2/file-events/search) — enabled only if you provide FE_ADV_QUERY_JSON def pull_file_events(hdrs): if not FE_ADV_QUERY_JSON: return 0 try: base_query = json.loads(FE_ADV_QUERY_JSON) except Exception: raise RuntimeError("FE_ADV_QUERY_JSON is not valid JSON") pages = 0 next_token = None while True: body = dict(base_query) body["pgSize"] = FE_PAGE_SIZE if next_token: body["pgToken"] = next_token raw = http_post_json("/v2/file-events/search", body, hdrs) data = json.loads(raw.decode()) put_json("file_events/", f"fileevents-page-{pages}", data) pages += 1 next_token = ( data.get("nextPgToken") or data.get("next_page_token") or (data.get("file_events") or {}).get("nextPgToken") ) if not next_token: break return pages def handler(event, context): hdrs = auth_header() report = {} if "users" in STREAMS: report["users_pages"] = pull_users(hdrs) if "sessions" in STREAMS: report["sessions_pages"] = pull_sessions(hdrs) if "audit" in STREAMS: report["audit_pages"] = pull_audit(hdrs) if "cases" in STREAMS: report["cases_pages"] = pull_cases(hdrs) if "file_events" in STREAMS: report["file_events_pages"] = pull_file_events(hdrs) return report def lambda_handler(event, context): return handler(event, context)
Klik Deploy.
Membuat jadwal EventBridge
- Di Konsol AWS, buka Amazon EventBridge > Rules.
- Klik Buat aturan.
- Berikan detail konfigurasi berikut:
- Pola jadwal: Pilih Tarif tetap
1
jam. - Nama: Masukkan nama yang unik dan bermakna (misalnya,
code42-incydr-hourly
). - Target: Pilih Lambda function dan pilih
code42-incydr-pull
.
- Pola jadwal: Pilih Tarif tetap
- Klik Buat aturan.
Opsional: Buat pengguna & kunci IAM hanya baca untuk Google SecOps
- Di Konsol AWS, buka IAM > Users, lalu klik Add users.
- Berikan detail konfigurasi berikut:
- Pengguna: Masukkan nama unik (misalnya,
secops-reader
) - Jenis akses: Pilih Kunci akses - Akses terprogram
- Klik Buat pengguna.
- Pengguna: Masukkan nama unik (misalnya,
- Lampirkan kebijakan baca minimal (kustom): Pengguna > pilih
secops-reader
> Izin > Tambahkan izin > Lampirkan kebijakan secara langsung > Buat kebijakan Di editor JSON, masukkan kebijakan berikut:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::<your-bucket>/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::<your-bucket>" } ] }
Tetapkan nama ke
secops-reader-policy
.Buka Buat kebijakan > telusuri/pilih > Berikutnya > Tambahkan izin.
Buka Kredensial keamanan > Kunci akses > Buat kunci akses.
Download CSV (nilai ini dimasukkan ke dalam feed).
Mengonfigurasi feed di Google SecOps untuk menyerap log Code42 Incydr
- Buka Setelan SIEM > Feed.
- Klik Tambahkan Feed Baru.
- Di kolom Nama feed, masukkan nama untuk feed (misalnya,
Code42 Incydr Datasets
). - Pilih Amazon S3 V2 sebagai Jenis sumber.
- Pilih Code42 Incydr sebagai Jenis log.
- Klik Berikutnya.
- Tentukan nilai untuk parameter input berikut:
- URI S3:
s3://code42-incydr/code42/
- Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda.
- Usia File Maksimum: Default 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 akan diterapkan ke peristiwa dari feed ini.
- URI S3:
- Klik Berikutnya.
- Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.