Mengumpulkan log Oracle NetSuite - NetSuite Applications Suite
Dokumen ini menjelaskan cara menyerap log Oracle NetSuite - NetSuite Applications Suite ke Google Security Operations menggunakan Google Cloud Storage V2.
Oracle NetSuite adalah platform perencanaan sumber daya perusahaan (ERP) berbasis cloud yang menyediakan kemampuan pengelolaan bisnis yang komprehensif, termasuk pengelolaan keuangan, pengelolaan hubungan pelanggan (CRM), e-commerce, dan pengelolaan inventaris. NetSuite menghasilkan log audit ekstensif, termasuk jejak login pengguna, catatan sistem yang melacak perubahan catatan, dan log akses API yang dapat diambil melalui SuiteQL REST API untuk tujuan pemantauan keamanan dan kepatuhan.
Sebelum memulai
Pastikan Anda memiliki prasyarat berikut:
- Instance Google SecOps
- Project GCP dengan Cloud Storage, Cloud Run, Pub/Sub, dan Cloud Scheduler API yang diaktifkan
- Izin untuk membuat dan mengelola bucket GCS
- Izin untuk mengelola kebijakan IAM di bucket GCS
- Izin untuk membuat layanan Cloud Run, topik Pub/Sub, dan tugas Cloud Scheduler
- Akun NetSuite dengan akses Administrator
- Layanan Web REST NetSuite diaktifkan
- Izin untuk membuat data integrasi dan token akses di NetSuite
Mengonfigurasi akses NetSuite API
Untuk mengaktifkan pengumpulan log melalui SuiteQL REST API, Anda harus mengaktifkan REST Web Services, membuat data integrasi, dan membuat kredensial Token-Based Authentication (TBA) di NetSuite.
Mengaktifkan fitur NetSuite yang diperlukan
- Login ke akun NetSuite Anda sebagai Administrator.
- Buka Penyiapan > Perusahaan > Aktifkan Fitur.
- Klik tab SuiteCloud.
- Di bagian SuiteScript, centang kotak berikut:
- Client SuiteScript
- Server SuiteScript
- Di bagian SuiteTalk (Web Services), centang kotak berikut:
- REST Web Services
- Di bagian Manage Authentication, centang kotak Token-Based Authentication.
- Klik I Agree di halaman SuiteCloud Terms of Service.
- Klik Simpan.
Membuat data integrasi
- Di NetSuite, buka Setup > Integration > Manage Integrations > New.
- Di kolom Name, masukkan
Google SecOps Integration. - Di kolom Description, masukkan
Integration for Google Security Operations log collection. - Di kolom State, biarkan opsi default Enabled dipilih.
- Klik tab Authentication.
- Di bagian Autentikasi Berbasis Token, centang kotak Autentikasi Berbasis Token.
- Jangan centang kotak TBA: Authorization Flow.
- Centang kotak TBA: ISSUETOKEN ENDPOINT.
- Klik Simpan.
Di halaman konfirmasi, salin dan simpan kunci pengguna/Client ID dan Consumer Secret/rahasia klien.
Membuat peran khusus untuk akses API
- Buka Setup > Users/Roles > Manage Roles > New.
- Di kolom Name, masukkan
Google SecOps API Role. - Di kolom ID, masukkan
google_secops_api_role. - Klik subtab Izin.
- Klik subtab Penyiapan.
- Tambahkan izin berikut dengan tingkat akses Penuh:
- Login menggunakan Token Akses
- Token Akses Pengguna
- Layanan Web REST
- Klik subtab Laporan.
- Tambahkan izin berikut dengan tingkat akses Lihat:
- Workbook SuiteAnalytics
- Klik subtab Daftar.
- Tambahkan izin berikut dengan tingkat akses Lihat:
- Jejak Audit Login
- Klik Simpan.
Menetapkan peran kepada pengguna
- Buka Lists > Employees > Employees.
- Pilih akun pengguna yang akan digunakan untuk integrasi (atau buat pengguna integrasi khusus baru).
- Klik Edit.
- Klik tab Akses.
- Di bagian Roles, klik Add.
- Pilih Google SecOps API Role dari menu dropdown.
- Klik Simpan.
Membuat token akses
- Login ke NetSuite sebagai pengguna yang diberi Peran Google SecOps API.
- Buka Penyiapan > Pengguna/Peran > Token Akses > Baru.
- Di halaman Access Token:
- Di menu drop-down Application Name, pilih Google SecOps Integration.
- Di menu dropdown User, pilih akun pengguna yang diberi Peran Google SecOps API.
- Di menu dropdown Role, pilih Google SecOps API Role.
- Kolom Nama Token akan otomatis terisi. Anda dapat mengubahnya jika diinginkan.
- Klik Simpan.
Di halaman konfirmasi, salin dan simpan ID token dan Token Secret.
Menemukan ID Akun NetSuite Anda
- Di NetSuite, buka Setup > Perusahaan > Informasi Perusahaan.
- Temukan kolom ID Akun (ditampilkan di bawah setelan Zona Waktu).
- Salin dan simpan ID Akun Anda (misalnya,
1234567atau1234567_SB1untuk akun sandbox).
Memverifikasi izin
Untuk memverifikasi bahwa akun memiliki izin yang diperlukan:
- Login ke NetSuite dengan pengguna yang diberi Peran Google SecOps API.
- Buka Setup > Users/Roles > View Login Audit Trail.
- Jika Anda dapat melihat halaman Jejak Audit Login, berarti akun tersebut memiliki izin yang diperlukan.
- Jika Anda tidak dapat melihat opsi ini, hubungi administrator NetSuite Anda untuk memberikan izin Login Audit Trail di subtab Lists.
Menguji akses API
Uji kredensial Anda sebelum melanjutkan integrasi:
# Replace with your actual values ACCOUNT_ID="your-account-id" # Replace underscores with hyphens in the account ID for the URL # For example: 1234567_SB1 becomes 1234567-sb1 URL_ACCOUNT_ID=$(echo "$ACCOUNT_ID" | tr '_' '-' | tr '[:upper:]' '[:lower:]') CONSUMER_KEY="your-consumer-key" CONSUMER_SECRET="your-consumer-secret" TOKEN_ID="your-token-id" TOKEN_SECRET="your-token-secret" # Test SuiteQL API access using OAuth 1.0 TBA # Note: This example requires the oauth1 CLI tool or Postman. # Use the following endpoint and headers to verify connectivity: # POST https://${URL_ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql?limit=5 # Headers: # Authorization: OAuth (with consumer key, token, HMAC-SHA256 signature) # Content-Type: application/json # Prefer: transient # Body: {"q": "SELECT id, date, status, user, emailaddress FROM LoginAudit ORDER BY date DESC"}
Respons yang berhasil akan menampilkan objek JSON yang berisi catatan LoginAudit.
Buat bucket Google Cloud Storage
- Buka Konsol Google Cloud.
- Pilih project Anda atau buat project baru.
- Di menu navigasi, buka Cloud Storage > Buckets.
- Klik Create bucket.
Berikan detail konfigurasi berikut:
Setelan Nilai Beri nama bucket Anda Masukkan nama yang unik secara global (misalnya, netsuite-audit-logs)Location type Pilih sesuai kebutuhan Anda (Region, Dual-region, Multi-region) Location Pilih lokasi (misalnya, us-central1)Kelas penyimpanan Standard (direkomendasikan untuk log yang sering diakses) Kontrol akses Seragam (direkomendasikan) Alat perlindungan Opsional: Aktifkan pembuatan versi objek atau kebijakan retensi Klik Create.
Buat akun layanan untuk fungsi Cloud Run
Fungsi Cloud Run memerlukan akun layanan dengan izin untuk menulis ke bucket GCS dan dipanggil oleh Pub/Sub.
Membuat akun layanan
- Di Konsol GCP, buka IAM & Admin > Service Accounts.
- Klik Create Service Account.
- Berikan detail konfigurasi berikut:
- Nama akun layanan: Masukkan
netsuite-audit-collector-sa - Deskripsi akun layanan: Masukkan
Service account for Cloud Run function to collect NetSuite audit logs
- Nama akun layanan: Masukkan
- Klik Create and Continue.
- Di bagian Grant this service account access to project, tambahkan peran berikut:
- Klik Pilih peran.
- Telusuri dan pilih Storage Object Admin.
- Klik + Add another role.
- Telusuri dan pilih Cloud Run Invoker.
- Klik + Add another role.
- Telusuri dan pilih Cloud Functions Invoker.
- Klik Lanjutkan.
- Klik Done.
Peran ini diperlukan untuk:
- Storage Object Admin: Menulis log ke bucket GCS dan mengelola file status
- Cloud Run Invoker: Izinkan Pub/Sub memanggil fungsi
- Cloud Functions Invoker: Mengizinkan pemanggilan fungsi
Memberikan izin IAM pada bucket GCS
- Buka Cloud Storage > Buckets.
- Klik nama bucket Anda (
netsuite-audit-logs). - Buka tab Izin.
- Klik Grant access.
- Berikan detail konfigurasi berikut:
- Add principals: Masukkan email akun layanan (
netsuite-audit-collector-sa@PROJECT_ID.iam.gserviceaccount.com) - Menetapkan peran: Pilih Storage Object Admin
- Add principals: Masukkan email akun layanan (
- Klik Simpan.
Membuat topik Pub/Sub
- Di Konsol GCP, buka Pub/Sub > Topics.
- Klik Create topic.
- Berikan detail konfigurasi berikut:
- ID Topik: Masukkan
netsuite-audit-trigger - Biarkan setelan lainnya sesuai default
- ID Topik: Masukkan
- Klik Create.
Membuat fungsi Cloud Run untuk mengumpulkan log
Fungsi Cloud Run akan dipicu oleh pesan Pub/Sub dari Cloud Scheduler untuk mengambil log dari NetSuite SuiteQL REST API dan menuliskannya ke GCS.
- Di Konsol GCP, buka Cloud Run.
- Klik Create service.
- Pilih Function (gunakan editor inline untuk membuat fungsi).
Di bagian Konfigurasi, berikan detail konfigurasi berikut:
Setelan Nilai Nama layanan netsuite-audit-collectorRegion Pilih region yang cocok dengan bucket GCS Anda (misalnya, us-central1)Runtime Pilih Python 3.12 atau yang lebih baru Di bagian Pemicu (opsional):
- Klik + Tambahkan pemicu.
- Pilih Cloud Pub/Sub.
- Di Select a Cloud Pub/Sub topic, pilih
netsuite-audit-trigger. - Klik Simpan.
Di bagian Authentication:
- Pilih Wajibkan autentikasi.
- Periksa Identity and Access Management (IAM).
Scroll ke bawah dan luaskan Containers, Networking, Security.
Buka tab Security:
- Akun layanan: Pilih
netsuite-audit-collector-sa
- Akun layanan: Pilih
Buka tab Containers:
- Klik Variables & Secrets.
- Klik + Tambahkan variabel untuk setiap variabel lingkungan:
Nama Variabel Nilai Contoh Deskripsi GCS_BUCKETnetsuite-audit-logsNama bucket GCS GCS_PREFIXnetsuite-auditAwalan untuk file log STATE_KEYnetsuite-audit/state.jsonJalur file status NS_ACCOUNT_ID1234567ID Akun NetSuite NS_CONSUMER_KEYyour-consumer-keyKunci Konsumen dari catatan integrasi NS_CONSUMER_SECRETyour-consumer-secretRahasia Konsumen dari data integrasi NS_TOKEN_IDyour-token-idID token dari token akses NS_TOKEN_SECRETyour-token-secretSecret Token dari token akses MAX_RECORDS10000Jumlah data maks per proses PAGE_SIZE1000Kumpulan data per halaman SuiteQL LOOKBACK_HOURS24Periode lihat balik awal Di bagian Variables & Secrets, scroll ke bawah ke Requests:
- Request timeout: Masukkan
600detik (10 menit)
- Request timeout: Masukkan
Buka tab Setelan:
- Di bagian Referensi:
- Memori: Pilih 512 MiB atau lebih tinggi
- CPU: Pilih 1
- Di bagian Referensi:
Di bagian Penskalaan revisi:
- Minimum number of instances: Masukkan
0 - Maximum number of instances: Masukkan
100
- Minimum number of instances: Masukkan
Klik Create.
Tunggu hingga layanan dibuat (1-2 menit).
Setelah layanan dibuat, editor kode inline akan terbuka secara otomatis.
Menambahkan kode fungsi
- Masukkan main di kolom Entry point.
Di editor kode inline, buat dua file:
- main.py:
import functions_framework from google.cloud import storage import json import os import urllib3 import hashlib import hmac import base64 import time import secrets import urllib.parse from datetime import datetime, timezone, timedelta # Initialize HTTP client with timeouts http = urllib3.PoolManager( timeout=urllib3.Timeout(connect=10.0, read=60.0), retries=False, ) # Initialize Storage client storage_client = storage.Client() # Environment variables GCS_BUCKET = os.environ.get('GCS_BUCKET') GCS_PREFIX = os.environ.get('GCS_PREFIX', 'netsuite-audit') STATE_KEY = os.environ.get('STATE_KEY', 'netsuite-audit/state.json') NS_ACCOUNT_ID = os.environ.get('NS_ACCOUNT_ID') NS_CONSUMER_KEY = os.environ.get('NS_CONSUMER_KEY') NS_CONSUMER_SECRET = os.environ.get('NS_CONSUMER_SECRET') NS_TOKEN_ID = os.environ.get('NS_TOKEN_ID') NS_TOKEN_SECRET = os.environ.get('NS_TOKEN_SECRET') MAX_RECORDS = int(os.environ.get('MAX_RECORDS', '10000')) PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '1000')) LOOKBACK_HOURS = int(os.environ.get('LOOKBACK_HOURS', '24')) def get_netsuite_base_url(account_id): """Build the NetSuite REST API base URL from the account ID.""" url_account = account_id.replace('_', '-').lower() return f"https://{url_account}.suitetalk.api.netsuite.com" def generate_oauth_header(method, url, account_id, consumer_key, consumer_secret, token_id, token_secret): """Generate OAuth 1.0 Authorization header using HMAC-SHA256.""" timestamp = str(int(time.time())) nonce = secrets.token_hex(16) # Parse URL to separate base URL and query parameters parsed = urllib.parse.urlparse(url) base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}" query_params = urllib.parse.parse_qs(parsed.query, keep_blank_values=True) # Build parameter string (OAuth params + query params) params = { 'oauth_consumer_key': consumer_key, 'oauth_token': token_id, 'oauth_nonce': nonce, 'oauth_timestamp': timestamp, 'oauth_signature_method': 'HMAC-SHA256', 'oauth_version': '1.0', } for key, values in query_params.items(): params[key] = values[0] # Sort parameters and create parameter string sorted_params = sorted(params.items()) param_string = '&'.join( f"{urllib.parse.quote(k, safe='')}={urllib.parse.quote(v, safe='')}" for k, v in sorted_params ) # Create signature base string signature_base = ( f"{method.upper()}&" f"{urllib.parse.quote(base_url, safe='')}&" f"{urllib.parse.quote(param_string, safe='')}" ) # Create signing key signing_key = ( f"{urllib.parse.quote(consumer_secret, safe='')}&" f"{urllib.parse.quote(token_secret, safe='')}" ) # Generate HMAC-SHA256 signature signature = base64.b64encode( hmac.new( signing_key.encode('utf-8'), signature_base.encode('utf-8'), hashlib.sha256 ).digest() ).decode('utf-8') # Build realm from account ID realm = account_id.replace('-', '_').upper() # Build Authorization header auth_header = ( f'OAuth realm="{realm}",' f'oauth_consumer_key="{consumer_key}",' f'oauth_token="{token_id}",' f'oauth_nonce="{nonce}",' f'oauth_timestamp="{timestamp}",' f'oauth_signature_method="HMAC-SHA256",' f'oauth_version="1.0",' f'oauth_signature="{urllib.parse.quote(signature, safe="")}"' ) return auth_header @functions_framework.cloud_event def main(cloud_event): """ Cloud Run function triggered by Pub/Sub to fetch NetSuite LoginAudit logs via SuiteQL and write to GCS. """ if not all([GCS_BUCKET, NS_ACCOUNT_ID, NS_CONSUMER_KEY, NS_CONSUMER_SECRET, NS_TOKEN_ID, NS_TOKEN_SECRET]): print('Error: Missing required environment variables') return try: bucket = storage_client.bucket(GCS_BUCKET) state = load_state(bucket) now = datetime.now(timezone.utc) if isinstance(state, dict) and state.get('last_event_time'): try: last_val = state['last_event_time'] if last_val.endswith('Z'): last_val = last_val[:-1] + '+00:00' last_time = datetime.fromisoformat(last_val) last_time = last_time - timedelta(minutes=2) except Exception as e: print(f"Warning: Could not parse last_event_time: {e}") last_time = now - timedelta(hours=LOOKBACK_HOURS) else: last_time = now - timedelta(hours=LOOKBACK_HOURS) print(f"Fetching logs from {last_time.isoformat()} to {now.isoformat()}") records, newest_time = fetch_login_audit(last_time, now) if not records: print("No new log records found.") save_state(bucket, now.isoformat()) return timestamp = now.strftime('%Y%m%d_%H%M%S') object_key = f"{GCS_PREFIX}/netsuite_audit_{timestamp}.ndjson" blob = bucket.blob(object_key) ndjson = '\n'.join( [json.dumps(r, ensure_ascii=False, default=str) for r in records] ) + '\n' blob.upload_from_string(ndjson, content_type='application/x-ndjson') print(f"Wrote {len(records)} records to gs://{GCS_BUCKET}/{object_key}") if newest_time: save_state(bucket, newest_time) else: save_state(bucket, now.isoformat()) print(f"Successfully processed {len(records)} records") except Exception as e: print(f'Error processing logs: {str(e)}') raise def fetch_login_audit(start_time, end_time): """ Fetch LoginAudit records from NetSuite SuiteQL API with pagination. Returns: Tuple of (records list, newest_event_time ISO string) """ base_url = get_netsuite_base_url(NS_ACCOUNT_ID) suiteql_endpoint = f"{base_url}/services/rest/query/v1/suiteql" start_str = start_time.strftime('%Y-%m-%d %H:%M:%S') end_str = end_time.strftime('%Y-%m-%d %H:%M:%S') query = ( "SELECT id, date, status, user, role, emailaddress, " "ipaddress, useragent, detail, requesturi, " "oauthaccesstokenname, oauthappname " "FROM LoginAudit " f"WHERE date BETWEEN TO_DATE('{start_str}', 'YYYY-MM-DD HH24:MI:SS') " f"AND TO_DATE('{end_str}', 'YYYY-MM-DD HH24:MI:SS') " "ORDER BY date ASC" ) records = [] newest_time = None offset = 0 backoff = 1.0 while True: if len(records) >= MAX_RECORDS: print(f"Reached max_records limit ({MAX_RECORDS})") break remaining = min(PAGE_SIZE, MAX_RECORDS - len(records)) url = f"{suiteql_endpoint}?limit={remaining}&offset={offset}" auth_header = generate_oauth_header( 'POST', url, NS_ACCOUNT_ID, NS_CONSUMER_KEY, NS_CONSUMER_SECRET, NS_TOKEN_ID, NS_TOKEN_SECRET ) headers = { 'Authorization': auth_header, 'Content-Type': 'application/json', 'Prefer': 'transient', 'User-Agent': 'GoogleSecOps-NetSuiteCollector/1.0', } body = json.dumps({'q': query}).encode('utf-8') try: response = http.request('POST', url, headers=headers, body=body) if response.status == 429: retry_after = int( response.headers.get('Retry-After', str(int(backoff))) ) print(f"Rate limited (429). Retrying after {retry_after}s...") time.sleep(retry_after) backoff = min(backoff * 2, 60.0) continue backoff = 1.0 if response.status != 200: print(f"HTTP Error: {response.status}") response_text = response.data.decode('utf-8') print(f"Response body: {response_text}") return records, newest_time data = json.loads(response.data.decode('utf-8')) page_results = data.get('items', []) if not page_results: print("No more results (empty page)") break page_num = (offset // PAGE_SIZE) + 1 print(f"Page {page_num}: Retrieved {len(page_results)} records") records.extend(page_results) for event in page_results: try: event_time = event.get('date') if event_time: if newest_time is None or event_time > newest_time: newest_time = event_time except Exception as e: print(f"Warning: Could not parse event time: {e}") has_more = data.get('hasMore', False) if not has_more: print("Reached last page (hasMore=false)") break offset += len(page_results) except Exception as e: print(f"Error fetching logs: {e}") return records, newest_time print(f"Retrieved {len(records)} total records") return records, newest_time def load_state(bucket): """Load state from GCS.""" try: blob = bucket.blob(STATE_KEY) if blob.exists(): return json.loads(blob.download_as_text()) except Exception as e: print(f"Warning: Could not load state: {e}") return {} def save_state(bucket, last_event_time_iso): """Save the last event timestamp to GCS state file.""" try: state = { 'last_event_time': last_event_time_iso, 'last_run': datetime.now(timezone.utc).isoformat() } blob = bucket.blob(STATE_KEY) blob.upload_from_string( json.dumps(state, indent=2), content_type='application/json' ) print(f"Saved state: last_event_time={last_event_time_iso}") except Exception as e: print(f"Warning: Could not save state: {e}")- requirements.txt:
functions-framework==3.* google-cloud-storage==2.* urllib3>=2.0.0Klik Deploy untuk menyimpan dan men-deploy fungsi.
Tunggu hingga deployment selesai (2-3 menit).
Buat tugas Cloud Scheduler
Cloud Scheduler akan memublikasikan pesan ke topik Pub/Sub secara berkala, sehingga memicu fungsi Cloud Run.
- Di Konsol GCP, buka Cloud Scheduler.
- Klik Create Job.
Berikan detail konfigurasi berikut:
Setelan Nilai Nama netsuite-audit-collector-hourlyRegion Pilih region yang sama dengan fungsi Cloud Run Frekuensi 0 * * * *(setiap jam, tepat pada jamnya)Zona Waktu Pilih zona waktu (UTC direkomendasikan) Jenis target Pub/Sub Topik Pilih netsuite-audit-triggerIsi pesan {}(objek JSON kosong)Klik Create.
Opsi frekuensi jadwal
Pilih frekuensi berdasarkan volume log dan persyaratan latensi:
| Frekuensi | Ekspresi Cron | Kasus Penggunaan |
|---|---|---|
| Setiap 5 menit | */5 * * * * |
Volume tinggi, latensi rendah |
| Setiap 15 menit | */15 * * * * |
Volume sedang |
| Setiap jam | 0 * * * * |
Standar (direkomendasikan) |
| Setiap 6 jam | 0 */6 * * * |
Volume rendah, batch processing |
| Harian | 0 0 * * * |
Pengumpulan data historis |
Menguji integrasi
- Di konsol Cloud Scheduler, temukan tugas Anda (
netsuite-audit-collector-hourly). - Klik Force run untuk memicu tugas secara manual.
- Tunggu beberapa detik.
- Buka Cloud Run > Services.
- Klik
netsuite-audit-collector. - Klik tab Logs.
Pastikan fungsi berhasil dieksekusi. Cari:
Fetching logs from YYYY-MM-DDTHH:MM:SS+00:00 to YYYY-MM-DDTHH:MM:SS+00:00 Page 1: Retrieved X records Wrote X records to gs://netsuite-audit-logs/netsuite-audit/netsuite_audit_YYYYMMDD_HHMMSS.ndjson Successfully processed X recordsBuka Cloud Storage > Buckets.
Klik
netsuite-audit-logs.Buka folder
netsuite-audit/.Pastikan file
.ndjsonbaru dibuat dengan stempel waktu saat ini.
Jika Anda melihat error di log:
- HTTP 401: Pastikan kredensial OAuth (
NS_CONSUMER_KEY,NS_CONSUMER_SECRET,NS_TOKEN_ID,NS_TOKEN_SECRET) dan variabel lingkunganNS_ACCOUNT_IDsudah benar - HTTP 403: Verifikasi bahwa peran NetSuite memiliki izin yang diperlukan (REST Web Services, Login Audit Trail, SuiteAnalytics Workbook)
- HTTP 429: Pembatasan kapasitas — fungsi akan otomatis mencoba ulang dengan backoff eksponensial
- Variabel lingkungan tidak ada: Pastikan semua variabel yang diperlukan ditetapkan dalam konfigurasi fungsi Cloud Run
Mengambil akun layanan Google SecOps
- Buka Setelan SIEM > Feed.
- Klik Tambahkan Feed Baru.
- Klik Konfigurasi satu feed.
- Di kolom Nama feed, masukkan nama untuk feed (misalnya,
NetSuite Audit Logs). - Pilih Google Cloud Storage V2 sebagai Source type.
- Pilih Oracle NetSuite - NetSuite Applications Suite sebagai Log type.
Klik Get Service Account. Email akun layanan yang unik akan ditampilkan. Contoh:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comSalin alamat email ini untuk digunakan di langkah berikutnya.
Klik Berikutnya.
Tentukan nilai untuk parameter input berikut:
URL bucket penyimpanan: Masukkan URI bucket GCS dengan jalur awalan:
gs://netsuite-audit-logs/netsuite-audit/
- Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda:
- Jangan pernah: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian).
- Hapus file yang ditransfer: Menghapus file setelah transfer berhasil.
- Delete transferred files and empty directories: Menghapus file dan direktori kosong setelah transfer berhasil.
- Maximum File Age: Sertakan file yang diubah dalam jumlah hari terakhir (defaultnya adalah 180 hari)
- Namespace aset: Namespace aset
- Label penyerapan: Label yang akan diterapkan ke peristiwa dari feed ini
Klik Berikutnya.
Tinjau konfigurasi feed berita baru Anda di layar Finalize, lalu klik Submit.
Memberikan izin IAM ke akun layanan Google SecOps
Akun layanan Google SecOps memerlukan peran Storage Object Viewer di bucket GCS Anda.
- Buka Cloud Storage > Buckets.
- Klik
netsuite-audit-logs. - Buka tab Izin.
- Klik Grant access.
- Berikan detail konfigurasi berikut:
- Add principals: Tempel email akun layanan Google SecOps
- Tetapkan peran: Pilih Storage Object Viewer
Klik Simpan.
Batas kapasitas API NetSuite
NetSuite API memiliki batas konkurensi dan pembatasan kapasitas berikut:
| Jenis Batas | Nilai Default | Catatan |
|---|---|---|
| Permintaan serentak | 15 permintaan | Berlaku untuk gabungan permintaan SOAP dan REST API per akun |
| Hasil kueri SuiteQL | Maksimum 100.000 baris | Jumlah maksimum baris yang ditampilkan per kueri SuiteQL |
| Objek per permintaan | Maksimum 1.000 objek | Jumlah maksimum objek yang ditampilkan per permintaan API |
Fungsi Cloud Run otomatis menangani pembatasan kapasitas dengan backoff eksponensial. Jika Anda mengalami error pembatasan kapasitas yang terus-menerus (HTTP 429), hubungi dukungan NetSuite untuk meningkatkan batas API atau menyesuaikan frekuensi Cloud Scheduler.
Tabel pemetaan UDM
| Kolom Log | Pemetaan UDM | Logika |
|---|---|---|
| pengguna | extensions.auth.type | Jenis mekanisme autentikasi yang digunakan |
| tanggal | metadata.event_timestamp | Stempel waktu saat peristiwa terjadi |
| event_type | metadata.event_type | Jenis peristiwa (misalnya, USER_LOGIN, NETWORK_CONNECTION) |
| security_result | security_result | Detail tentang hasil keamanan acara |
| oauthaccesstokenname | security_result.about.resource.attribute.labels | Label key-value yang mendeskripsikan atribut resource yang terlibat dalam hasil keamanan |
| secchallenge | security_result.about.resource.attribute.labels | |
| status | security_result.summary | Deskripsi ringkasan hasil keamanan |
| oauthappname | target.application | Nama aplikasi target |
| useragent | target.application | |
| ipaddress | target.ip | Alamat IP target |
| requesturi | target.url | URL resource target |
| emailaddress | target.user.email_addresses | Alamat email yang terkait dengan pengguna target |
| peran | target.user.role_name | Nama peran yang ditetapkan kepada pengguna target |
| pengguna | target.user.userid | ID unik untuk pengguna target |
Log Perubahan
Melihat Log Perubahan untuk parser ini
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.