收集 IBM MaaS360 記錄
本文說明如何使用 Google Cloud Storage V2,將 IBM MaaS360 記錄檔擷取至 Google Security Operations。
IBM MaaS360 是一體式端點管理 (UEM) 平台,提供行動裝置管理服務、應用程式安全性和威脅管理功能。這項服務會產生安全性事件,包括管理員登入記錄、管理員變更稽核、法規遵循規則事件、裝置註冊事件、動作記錄事件,以及安全威脅事件,例如簡訊和電子郵件網路釣魚和惡意軟體偵測。
事前準備
請確認您已完成下列事前準備事項:
- Google SecOps 執行個體
- 已啟用 Cloud Storage、Cloud Run、Pub/Sub 和 Cloud Scheduler API 的 GCP 專案
- 建立及管理 GCS bucket 的權限
- 管理 Google Cloud Storage 值區 IAM 政策的權限
- 建立 Cloud Run 服務、Pub/Sub 主題和 Cloud Scheduler 工作的權限
- 使用管理員帳戶登入 IBM MaaS360 入口網站的特殊存取權
- IBM MaaS360 帳戶已啟用 API 存取權 (必須由 IBM 支援團隊啟用這項功能)
- 已指派「Web Service - Access Keys」角色的管理員帳戶
為 IBM MaaS360 帳戶啟用 API 存取權
您必須先為 MaaS360 帳戶啟用 API 存取權,才能產生 API 憑證。向 IBM MaaS360 支援團隊提出要求,為您的帳戶啟用 Web Services API 功能。啟用後,MaaS360 入口網站的「設定」選單下方會顯示「Web Services API」選項。
建立 Web Services API 角色
如要存取 API,管理員帳戶必須具備「Web Service - Access Keys」權限。如果您的帳戶尚未具備這個角色,請建立一個:
- 登入 IBM MaaS360 入口網站。
- 依序前往「設定」>「入口網站管理」>「角色」。
- 按一下「新增角色」。
- 在「基本資訊」部分,提供下列資訊:
- 角色名稱:輸入描述性名稱 (例如
Web Service API)。 - 角色說明:輸入
Permissions to access the Web Service API。
- 角色名稱:輸入描述性名稱 (例如
- 在「Select Mode of Creation」中,選取「Create New」,然後按一下「Next」。
- 從可用的存取權中,選取「Web Service - Access Keys」(Web 服務 - 存取金鑰)。
- 按一下 [儲存]。
將 API 角色指派給管理員帳戶
- 登入 IBM MaaS360 入口網站。
- 依序前往「設定」>「入口網站管理」>「管理員」。
- 按一下要用於 API 整合的管理員帳戶旁邊的「編輯」,或建立新的管理員帳戶。
- 將「Web Service API」角色新增至帳戶。
- 按一下「繼續」。
- 登出後再重新登入更新後的管理員帳戶,角色變更才會生效。
產生應用程式存取金鑰
- 使用具備「Web Service API」角色的管理員帳戶,登入 IBM MaaS360 入口網站。
- 依序前往「設定」>「Web Services API」>「管理存取金鑰」。
- 按一下「產生存取金鑰」。
- 選取「MaaS360 Web Services」做為金鑰類型。
- 在「Key Name」(金鑰名稱) 欄位中,輸入描述性名稱 (例如
Chronicle Integration)。 - 點按「生成」。
- 系統提示時,請使用管理員密碼進行驗證。
記錄金鑰產生後顯示的下列憑證:
- 應用程式 ID
- 應用程式版本
- 平台 ID
- 應用程式存取金鑰
找出帳單 ID
- 登入 IBM MaaS360 入口網站。
- 將游標懸停在入口網站右上角的個人資料選單上。
複製「帳戶 ID」值,這就是您的帳單 ID。
判斷 API 基準網址
API 基準網址取決於 MaaS360 執行個體。您的執行個體取決於帳單 ID 的第一個數字:
| 帳單 ID 開頭為 | 執行個體 | API 基礎網址 |
|---|---|---|
| 1 | M1 | https://services.fiberlink.com |
| 2 | M2 | https://services.m2.maas360.com |
| 3 | M3 | https://services.m3.maas360.com |
| 4 | M4 | https://services.m4.maas360.com |
測試 API 存取權
請先測試憑證,再繼續進行整合:
# Replace with your actual values API_BASE="https://services.m3.maas360.com" BILLING_ID="your-billing-id" USERNAME="your-admin-username" PASSWORD="your-admin-password" APP_ID="your-app-id" APP_VERSION="your-app-version" PLATFORM_ID="3" APP_ACCESS_KEY="your-app-access-key" # Test authentication curl -v -X POST "${API_BASE}/auth-apis/auth/1.0/authenticate/${BILLING_ID}" \ -H "Content-Type: application/xml" \ -H "Accept: application/json" \ -d "<authRequest><maaS360AdminAuth><billingID>${BILLING_ID}</billingID><platformID>${PLATFORM_ID}</platformID><appID>${APP_ID}</appID><appVersion>${APP_VERSION}</appVersion><appAccessKey>${APP_ACCESS_KEY}</appAccessKey><userName>${USERNAME}</userName><password>${PASSWORD}</password></maaS360AdminAuth></authRequest>"
成功的回應會傳回包含 authToken 的 JSON 物件。
建立 Google Cloud Storage bucket
- 前往 Google Cloud 控制台。
- 選取專案或建立新專案。
- 在導覽選單中,依序前往「Cloud Storage」>「Bucket」。
- 按一下「建立值區」。
請提供下列設定詳細資料:
設定 值 為 bucket 命名 輸入全域不重複的名稱 (例如 maas360-device-logs)位置類型 根據需求選擇 (區域、雙區域、多區域) 位置 選取位置 (例如 us-central1)儲存空間級別 標準 (建議用於經常存取的記錄) 存取控管 統一 (建議) 保護工具 選用:啟用物件版本管理或資料保留政策 點選「建立」。
為 Cloud Run 函式建立服務帳戶
Cloud Run 函式需要具備 GCS bucket 寫入權限,且可由 Pub/Sub 叫用的服務帳戶。
建立服務帳戶
- 在 GCP 控制台中,依序前往「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)。
- 按一下「Create Service Account」(建立服務帳戶)。
- 請提供下列設定詳細資料:
- 服務帳戶名稱:輸入
maas360-logs-collector-sa - 服務帳戶說明:輸入
Service account for Cloud Run function to collect IBM MaaS360 logs
- 服務帳戶名稱:輸入
- 按一下「建立並繼續」。
- 在「將專案存取權授予這個服務帳戶」部分,新增下列角色:
- 按一下「選擇角色」。
- 搜尋並選取「Storage 物件管理員」。
- 點選「+ 新增其他角色」。
- 搜尋並選取「Cloud Run Invoker」。
- 點選「+ 新增其他角色」。
- 搜尋並選取「Cloud Functions Invoker」(Cloud Functions 叫用者)。
- 按一下「繼續」。
- 按一下 [完成]。
這些角色適用於:
- Storage 物件管理員:將記錄檔寫入 GCS bucket,並管理狀態檔案
- Cloud Run 叫用者:允許 Pub/Sub 叫用函式
- Cloud Functions 叫用者:允許函式叫用
授予 GCS 值區的 IAM 權限
將 GCS bucket 的寫入權限授予服務帳戶:
- 依序前往「Cloud Storage」>「Buckets」。
- 按一下 bucket 名稱 (
maas360-device-logs)。 - 前往「權限」分頁標籤。
- 按一下「授予存取權」。
- 請提供下列設定詳細資料:
- 新增主體:輸入服務帳戶電子郵件地址 (
maas360-logs-collector-sa@PROJECT_ID.iam.gserviceaccount.com) - 指派角色:選取「Storage 物件管理員」
- 新增主體:輸入服務帳戶電子郵件地址 (
- 按一下 [儲存]。
建立 Pub/Sub 主題
建立 Pub/Sub 主題,Cloud Scheduler 會將訊息發布至該主題,而 Cloud Run 函式會訂閱該主題。
- 在 GCP Console 中,前往「Pub/Sub」>「Topics」(主題)。
- 按一下「建立主題」。
- 請提供下列設定詳細資料:
- 主題 ID:輸入
maas360-logs-trigger - 其他設定保留預設值
- 主題 ID:輸入
- 點選「建立」。
建立 Cloud Run 函式來收集記錄
Cloud Run 函式會由 Cloud Scheduler 傳送的 Pub/Sub 訊息觸發,從 IBM MaaS360 API 擷取記錄,並將記錄寫入 GCS。
如要建立 Cloud Run 函式來收集記錄,請按照下列步驟操作:
- 前往 GCP Console 的「Cloud Run」。
- 按一下「Create service」(建立服務)。
- 選取「函式」 (使用內嵌編輯器建立函式)。
在「設定」部分,提供下列設定詳細資料:
設定 值 服務名稱 maas360-logs-collector區域 選取與 GCS bucket 相符的區域 (例如 us-central1)執行階段 選取 Python 3.12 以上版本 在「Trigger (optional)」(觸發條件 (選用)) 專區:
- 按一下「+ 新增觸發條件」。
- 選取「Cloud Pub/Sub」。
- 在「Select a Cloud Pub/Sub topic」(選取 Cloud Pub/Sub 主題) 中,選擇
maas360-logs-trigger。 - 按一下 [儲存]。
在「Authentication」(驗證) 部分:
- 選取「需要驗證」。
- 檢查 Identity and Access Management (IAM)。
向下捲動並展開「容器」、「網路」和「安全性」。
前往「安全性」分頁:
- 服務帳戶:選取
maas360-logs-collector-sa
- 服務帳戶:選取
前往「容器」分頁:
- 按一下「變數與密鑰」。
針對每個環境變數,按一下「+ 新增變數」:
變數名稱 範例值 說明 GCS_BUCKETmaas360-device-logsGCS bucket 名稱 GCS_PREFIXmaas360-logs記錄檔的前置字串 STATE_KEYmaas360-logs/state.json狀態檔案路徑 API_BASEhttps://services.m3.maas360.com您執行個體的 MaaS360 API 基準網址 BILLING_IDyour-billing-idMaaS360 帳戶 ID (帳單 ID) USERNAMEyour-admin-username管理員使用者名稱 PASSWORDyour-admin-password管理員密碼 APP_IDyour-app-id產生的存取金鑰中的應用程式 ID APP_VERSION1.0從產生的存取金鑰取得應用程式版本 PLATFORM_IDyour-platform-id從產生的存取金鑰取得平台 ID APP_ACCESS_KEYyour-app-access-key從產生的存取金鑰取得應用程式存取金鑰 PAGE_SIZE250每頁記錄數 (25、50、100、200、250) MAX_PAGES100每次執行要擷取的頁數上限 LOOKBACK_HOURS24初始回溯期
在「變數與密鑰」部分,向下捲動至「要求」:
- 要求逾時:輸入
600秒 (10 分鐘)
- 要求逾時:輸入
前往「設定」分頁:
- 在「資源」部分:
- 記憶體:選取 512 MiB 以上
- CPU:選取 1
- 在「修訂版本資源調度」部分:
- 執行個體數量下限:輸入
0 - 執行個體數量上限:輸入
100
- 執行個體數量下限:輸入
- 在「資源」部分:
點選「建立」。
等待服務建立完成 (1 到 2 分鐘)。
服務建立完成後,系統會自動開啟內嵌程式碼編輯器。
新增函式程式碼
- 在「進入點」欄位中輸入「main」。
在內嵌程式碼編輯器中建立兩個檔案:
main.py:
import functions_framework from google.cloud import storage import json import os import urllib3 from datetime import datetime, timezone, timedelta import xml.etree.ElementTree as ET # 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', 'maas360-logs') STATE_KEY = os.environ.get('STATE_KEY', 'maas360-logs/state.json') API_BASE = os.environ.get('API_BASE', '').rstrip('/') BILLING_ID = os.environ.get('BILLING_ID') USERNAME = os.environ.get('USERNAME') PASSWORD = os.environ.get('PASSWORD') APP_ID = os.environ.get('APP_ID') APP_VERSION = os.environ.get('APP_VERSION', '1.0') PLATFORM_ID = os.environ.get('PLATFORM_ID', '3') APP_ACCESS_KEY = os.environ.get('APP_ACCESS_KEY') PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '250')) MAX_PAGES = int(os.environ.get('MAX_PAGES', '100')) LOOKBACK_HOURS = int(os.environ.get('LOOKBACK_HOURS', '24')) def authenticate(): """Authenticate to MaaS360 API and return auth token.""" url = f"{API_BASE}/auth-apis/auth/1.0/authenticate/{BILLING_ID}" auth_xml = ( '<authRequest>' '<maaS360AdminAuth>' f'<billingID>{BILLING_ID}</billingID>' f'<platformID>{PLATFORM_ID}</platformID>' f'<appID>{APP_ID}</appID>' f'<appVersion>{APP_VERSION}</appVersion>' f'<appAccessKey>{APP_ACCESS_KEY}</appAccessKey>' f'<userName>{USERNAME}</userName>' f'<password>{PASSWORD}</password>' '</maaS360AdminAuth>' '</authRequest>' ) response = http.request( 'POST', url, body=auth_xml.encode('utf-8'), headers={ 'Content-Type': 'application/xml', 'Accept': 'application/json', } ) if response.status != 200: raise Exception( f"Authentication failed with status {response.status}: " f"{response.data.decode('utf-8')}" ) data = json.loads(response.data.decode('utf-8')) auth_token = data.get('authResponse', {}).get('authToken') if not auth_token: raise Exception( f"No authToken in response: {response.data.decode('utf-8')}" ) print("Successfully obtained MaaS360 auth token") return auth_token def fetch_devices(auth_token, last_reported_epoch_ms=None): """ Fetch device records from MaaS360 Device Search API. Args: auth_token: Authentication token last_reported_epoch_ms: Filter for devices reported after this epoch (ms) Returns: List of device records as dicts """ url = f"{API_BASE}/device-apis/devices/2.0/search/customer/{BILLING_ID}" headers = { 'Authorization': f'MaaS token="{auth_token}"', 'Accept': 'application/json', } all_devices = [] page_number = 1 while page_number <= MAX_PAGES: params = { 'pageSize': str(PAGE_SIZE), 'pageNumber': str(page_number), 'sortAttribute': 'lastReported', 'sortOrder': 'asc', } if last_reported_epoch_ms: params['match'] = 'lastReportedSince' params['lastReportedInEpochms'] = str(last_reported_epoch_ms) query_string = '&'.join( [f"{k}={v}" for k, v in params.items()] ) request_url = f"{url}?{query_string}" try: response = http.request('GET', request_url, headers=headers) if response.status == 429: print("Rate limited (429). Stopping pagination.") break if response.status == 401: print("Auth token expired (401). Re-authenticating...") auth_token = authenticate() headers['Authorization'] = f'MaaS token="{auth_token}"' continue if response.status != 200: print( f"HTTP Error: {response.status} - " f"{response.data.decode('utf-8')}" ) break data = json.loads(response.data.decode('utf-8')) devices = data.get('devices', {}).get('device', []) if isinstance(devices, dict): devices = [devices] if not devices: print(f"No more devices at page {page_number}") break all_devices.extend(devices) print( f"Page {page_number}: Retrieved {len(devices)} devices " f"(total: {len(all_devices)})" ) if len(devices) < PAGE_SIZE: break page_number += 1 except Exception as e: print(f"Error fetching devices page {page_number}: {e}") break print(f"Retrieved {len(all_devices)} total device records") return all_devices, auth_token def fetch_action_history(auth_token, last_reported_epoch_ms=None): """ Fetch action history events from MaaS360. Args: auth_token: Authentication token last_reported_epoch_ms: Filter for events after this epoch (ms) Returns: List of action history records as dicts """ url = ( f"{API_BASE}/device-apis/devices/1.0/" f"searchActionHistory/{BILLING_ID}" ) headers = { 'Authorization': f'MaaS token="{auth_token}"', 'Accept': 'application/json', } all_actions = [] page_number = 1 while page_number <= MAX_PAGES: params = { 'pageSize': str(PAGE_SIZE), 'pageNumber': str(page_number), } query_string = '&'.join( [f"{k}={v}" for k, v in params.items()] ) request_url = f"{url}?{query_string}" try: response = http.request('GET', request_url, headers=headers) if response.status == 429: print("Rate limited (429). Stopping pagination.") break if response.status == 401: print("Auth token expired (401). Re-authenticating...") auth_token = authenticate() headers['Authorization'] = f'MaaS token="{auth_token}"' continue if response.status != 200: print( f"HTTP Error: {response.status} - " f"{response.data.decode('utf-8')}" ) break data = json.loads(response.data.decode('utf-8')) actions = data.get('actionHistory', {}).get('action', []) if isinstance(actions, dict): actions = [actions] if not actions: print( f"No more action history at page {page_number}" ) break all_actions.extend(actions) print( f"Action history page {page_number}: " f"{len(actions)} records " f"(total: {len(all_actions)})" ) if len(actions) < PAGE_SIZE: break page_number += 1 except Exception as e: print( f"Error fetching action history " f"page {page_number}: {e}" ) break print(f"Retrieved {len(all_actions)} action history records") return all_actions, auth_token @functions_framework.cloud_event def main(cloud_event): """ Cloud Run function triggered by Pub/Sub to fetch IBM MaaS360 device and action history logs and write to GCS. """ required_vars = [ GCS_BUCKET, API_BASE, BILLING_ID, USERNAME, PASSWORD, APP_ID, APP_ACCESS_KEY, ] if not all(required_vars): print('Error: Missing required environment variables') return try: bucket = storage_client.bucket(GCS_BUCKET) state = load_state(bucket) now = datetime.now(timezone.utc) last_reported_epoch_ms = None if isinstance(state, dict) and state.get('last_reported_epoch_ms'): last_reported_epoch_ms = int( state['last_reported_epoch_ms'] ) overlap_ms = 2 * 60 * 1000 last_reported_epoch_ms = last_reported_epoch_ms - overlap_ms else: lookback = now - timedelta(hours=LOOKBACK_HOURS) last_reported_epoch_ms = int( lookback.timestamp() * 1000 ) print( f"Fetching logs since epoch ms: {last_reported_epoch_ms} " f"({datetime.fromtimestamp(last_reported_epoch_ms / 1000, tz=timezone.utc).isoformat()})" ) auth_token = authenticate() devices, auth_token = fetch_devices( auth_token, last_reported_epoch_ms ) actions, auth_token = fetch_action_history( auth_token, last_reported_epoch_ms ) all_records = [] newest_epoch_ms = last_reported_epoch_ms for device in devices: device['_maas360_record_type'] = 'device' all_records.append(device) epoch_ms = device.get('lastReportedInEpochms') if epoch_ms: try: epoch_val = int(epoch_ms) if epoch_val > newest_epoch_ms: newest_epoch_ms = epoch_val except (ValueError, TypeError): pass for action in actions: action['_maas360_record_type'] = 'action_history' all_records.append(action) if not all_records: print("No new records found.") save_state( bucket, int(now.timestamp() * 1000), ) return timestamp = now.strftime('%Y%m%d_%H%M%S') object_key = ( f"{GCS_PREFIX}/maas360_logs_{timestamp}.ndjson" ) blob = bucket.blob(object_key) ndjson = '\n'.join( [ json.dumps(r, ensure_ascii=False, default=str) for r in all_records ] ) + '\n' blob.upload_from_string( ndjson, content_type='application/x-ndjson' ) print( f"Wrote {len(all_records)} records to " f"gs://{GCS_BUCKET}/{object_key}" ) save_state(bucket, newest_epoch_ms) print( f"Successfully processed {len(all_records)} records " f"(devices: {len(devices)}, " f"actions: {len(actions)})" ) except Exception as e: print(f'Error processing logs: {str(e)}') raise 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_reported_epoch_ms): """Save the last reported epoch timestamp to GCS state file.""" try: state = { 'last_reported_epoch_ms': last_reported_epoch_ms, '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_reported_epoch_ms=" f"{last_reported_epoch_ms}" ) except Exception as e: print(f"Warning: Could not save state: {e}")requirements.txt:
functions-framework==3.* google-cloud-storage==2.* urllib3>=2.0.0
點選「部署」即可儲存並部署函式。
等待部署作業完成 (2 到 3 分鐘)。
建立 Cloud Scheduler 工作
Cloud Scheduler 會定期將訊息發布至 Pub/Sub 主題,觸發 Cloud Run 函式。
- 前往 GCP 主控台的「Cloud Scheduler」。
- 點選「建立工作」。
請提供下列設定詳細資料:
設定 值 名稱 maas360-logs-collector-hourly區域 選取與 Cloud Run 函式相同的區域 頻率 0 * * * *(每小時整點)時區 選取時區 (建議使用世界標準時間) 目標類型 Pub/Sub 主題 選取「 maas360-logs-trigger」郵件內文 {}(空白 JSON 物件)點選「建立」。
排程頻率選項
根據記錄檔量和延遲時間要求選擇頻率:
| 頻率 | Cron 運算式 | 用途 |
|---|---|---|
| 每 15 分鐘 | */15 * * * * |
大量、低延遲 |
| 每小時 | 0 * * * * |
標準 (建議) |
| 每 6 小時 | 0 */6 * * * |
少量、批次處理 |
| 每日 | 0 0 * * * |
歷來資料集合 |
測試整合項目
- 在 Cloud Scheduler 控制台中,找出您的工作 (
maas360-logs-collector-hourly)。 - 按一下「強制執行」即可手動觸發工作。
- 稍等幾秒鐘。
- 前往「Cloud Run」>「Services」。
- 按一下
maas360-logs-collector。 - 按一下 [Logs] (記錄) 分頁標籤。
確認函式是否已順利執行。請注意以下事項:
Fetching logs since epoch ms: XXXXXXXXXXXXX (YYYY-MM-DDTHH:MM:SS+00:00) Successfully obtained MaaS360 auth token Page 1: Retrieved X devices (total: X) Action history page 1: X records (total: X) Wrote X records to gs://maas360-device-logs/maas360-logs/maas360_logs_YYYYMMDD_HHMMSS.ndjson Successfully processed X records (devices: X, actions: X)依序前往「Cloud Storage」>「Buckets」。
按一下
maas360-device-logs。前往
maas360-logs/資料夾。確認是否已建立新的
.ndjson檔案,且檔案名稱包含目前的時間戳記。
如果記錄中顯示錯誤:
- HTTP 401:確認
USERNAME、PASSWORD、APP_ID和APP_ACCESS_KEY環境變數是否正確 - HTTP 403:確認管理員帳戶已獲派「Web Service - Access Keys」角色
- HTTP 429:頻率限制,函式會停止分頁,並在下次排定的執行時間繼續
- 缺少環境變數:確認 Cloud Run 函式設定中已設定所有必要變數
擷取 Google SecOps 服務帳戶
- 依序前往「SIEM 設定」>「動態饋給」。
- 按一下「新增動態消息」。
- 按一下「設定單一動態饋給」。
- 在「動態饋給名稱」欄位中輸入動態饋給名稱 (例如
IBM MaaS360 Device Logs)。 - 選取「Google Cloud Storage V2」做為「來源類型」。
- 選取「IBM MaaS360」做為「記錄類型」。
按一下「取得服務帳戶」,系統會顯示專屬服務帳戶電子郵件地址,例如:
secops-12345678@secops-gcp-prod.iam.gserviceaccount.com複製這個電子郵件地址,以便在下一步中使用。
點選「下一步」。
指定下列輸入參數的值:
儲存空間 bucket URL:輸入 GCS bucket URI,並加上前置路徑:
gs://maas360-device-logs/maas360-logs/來源刪除選項:根據偏好設定選取刪除選項:
- 永不:移轉後一律不刪除任何檔案 (建議用於測試)。
- 刪除已轉移的檔案:成功轉移檔案後刪除檔案。
- 刪除已轉移的檔案和空白目錄:成功轉移後刪除檔案和空白目錄。
檔案存在時間上限:包含在過去天數內修改的檔案 (預設為 180 天)
資產命名空間:資產命名空間
擷取標籤:要套用至這個動態饋給事件的標籤
點選「下一步」。
在「Finalize」(完成) 畫面中檢查新的動態饋給設定,然後按一下「Submit」(提交)。
將 IAM 權限授予 Google SecOps 服務帳戶
Google SecOps 服務帳戶需要 GCS bucket 的「Storage 物件檢視者」角色。
如要將 IAM 權限授予 Google SecOps 服務帳戶,請按照下列步驟操作:
- 依序前往「Cloud Storage」>「Buckets」。
- 按一下
maas360-device-logs。 - 前往「權限」分頁標籤。
- 按一下「授予存取權」。
- 請提供下列設定詳細資料:
- 新增主體:貼上 Google SecOps 服務帳戶電子郵件地址
- 指派角色:選取「Storage 物件檢視者」
- 按一下 [儲存]。
UDM 對應表
| 記錄欄位 | UDM 對應 | 邏輯 |
|---|---|---|
| firstRegisteredInEpochms | additional.fields | 轉換為字串,並從 firstRegisteredInEpochms、lastRegisteredInEpochms、lastMdmRegisteredInEpochms、lastReportedInEpochms、isSupervisedDevice、testDevice、maas360ManagedStatus、itunesStoreAccountEnabled、installedDateInEpochms、sourceID、imeiEsn、installedDate、mailboxDeviceId、mailboxManaged、mailboxLastReportedInEpochms、mailboxLastReported、lastReported、policyComplianceState、userDomain、maas360Environment、encryptionStatus、enrollmentMode、deviceStatus、appComplianceState、ruleComplianceState、selectiveWipeStatus、jailbreakStatus、platformName、deviceOwner、ownership、customAssetNumber、deviceName、modelId、passcodeCompliance、mdmMailboxDeviceId、mdmPolicy、appVersion 合併為鍵/值組合 |
| lastRegisteredInEpochms | additional.fields | |
| lastMdmRegisteredInEpochms | additional.fields | |
| lastReportedInEpochms | additional.fields | |
| isSupervisedDevice | additional.fields | |
| testDevice | additional.fields | |
| maas360ManagedStatus | additional.fields | |
| itunesStoreAccountEnabled | additional.fields | |
| installedDateInEpochms | additional.fields | |
| sourceID | additional.fields | |
| imeiEsn | additional.fields | |
| installedDate | additional.fields | |
| mailboxDeviceId | additional.fields | |
| mailboxManaged | additional.fields | |
| mailboxLastReportedInEpochms | additional.fields | |
| mailboxLastReported | additional.fields | |
| lastReported | additional.fields | |
| policyComplianceState | additional.fields | |
| userDomain | additional.fields | |
| maas360Environment | additional.fields | |
| encryptionStatus | additional.fields | |
| enrollmentMode | additional.fields | |
| deviceStatus | additional.fields | |
| appComplianceState | additional.fields | |
| ruleComplianceState | additional.fields | |
| selectiveWipeStatus | additional.fields | |
| jailbreakStatus | additional.fields | |
| platformName | additional.fields | |
| deviceOwner | additional.fields | |
| 擁有權 | additional.fields | |
| customAssetNumber | additional.fields | |
| deviceName | additional.fields | |
| modelId | additional.fields | |
| passcodeCompliance | additional.fields | |
| mdmMailboxDeviceId | additional.fields | |
| mdmPolicy | additional.fields | |
| appVersion | additional.fields | |
| deviceName | entity.entity.asset.asset_id | 直接複製值 |
| deviceStatus | entity.entity.asset.deployment_status | 如果 deviceStatus ==「Active」,則設為「ACTIVE」 |
| installedDate | entity.entity.asset.first_discover_time | 使用日期篩選器轉換,格式為 yyyy-MM-ddTHH:mm:ss |
| 製造商 | entity.entity.asset.hardware.manufacturer | 直接複製值 |
| 模型 | entity.entity.asset.hardware.model | 直接複製值 |
| platformSerialNumber | entity.entity.asset.hardware.serial_number | 直接複製值 |
| maas360DeviceID | entity.entity.asset.hostname | 直接複製值 |
| 擁有權 | entity.entity.asset.labels | 從各個欄位合併的鍵/值組合 |
| deviceOwner | entity.entity.asset.labels | |
| imeiEsn | entity.entity.asset.labels | |
| maas360Environment | entity.entity.asset.labels | |
| installLocation | entity.entity.asset.labels | |
| maas360ManagedStatus | entity.entity.asset.labels | |
| udid | entity.entity.asset.labels | |
| mailboxDeviceId | entity.entity.asset.labels | |
| mailboxManaged | entity.entity.asset.labels | |
| phoneNumber | entity.entity.asset.labels | |
| sourceID | entity.entity.asset.labels | |
| itunesStoreAccountEnabled | entity.entity.asset.labels | |
| unifiedTravelerDeviceId | entity.entity.asset.labels | |
| enrollmentMode | entity.entity.asset.labels | |
| platformName | entity.entity.asset.labels | |
| deviceType | entity.entity.asset.labels | |
| modelId | entity.entity.asset.labels | |
| mdmPolicy | entity.entity.asset.labels | |
| policyComplianceState | entity.entity.asset.labels | |
| appComplianceState | entity.entity.asset.labels | |
| ruleComplianceState | entity.entity.asset.labels | |
| selectiveWipeStatus | entity.entity.asset.labels | |
| jailbreakStatus | entity.entity.asset.labels | |
| encryptionStatus | entity.entity.asset.labels | |
| passcodeCompliance | entity.entity.asset.labels | |
| mdmMailboxDeviceId | entity.entity.asset.labels | |
| isSupervisedDevice | entity.entity.asset.labels | |
| testDevice | entity.entity.asset.labels | |
| lastReported | entity.entity.asset.last_discover_time | 使用日期篩選器轉換,格式為 yyyy-MM-ddTHH:mm:ss |
| wifiMacAddress | entity.entity.asset.mac | 從 wifiMacAddress 合併 |
| userDomain | entity.entity.asset.network_domain | 直接複製值 |
| osVersion | entity.entity.asset.platform_software.platform_patch_level | 直接複製值 |
| osName | entity.entity.asset.platform_software.platform_version | 直接複製值 |
| deviceType | entity.entity.asset.type | 如果 deviceType ==「Smartphone」,則設為「MOBILE」 |
| maas360DeviceID | entity.metadata.entity_type | 如果 maas360DeviceID 不為空白,請設為「ASSET」 |
| maas360DeviceID | entity.metadata.product_entity_id | 直接複製值 |
| entity.metadata.product_name | entity.metadata.product_name | 設為「IBM MaaS360」 |
| entity.metadata.vendor_name | entity.metadata.vendor_name | 設為「IBM」 |
| 使用者名稱 | entity.relations.entity_type | 如果使用者名稱或電子郵件地址不為空白,請設為「USER」 |
| emailAddress | entity.relations.entity_type | |
| emailAddress | entity.relations.entity.user.email_addresses | 從 emailAddress 合併 |
| 使用者名稱 | entity.relations.entity.user.userid | 直接複製值 |
| 使用者名稱 | entity.relations.relationship | 如果 username 或 emailAddress 不為空白,請設為「OWNS」 |
| emailAddress | entity.relations.relationship | |
| maas360DeviceID | metadata.event_type | 如果 maas360DeviceID 不為空白,則設為 STATUS_UPDATE,否則設為 GENERIC_EVENT |
| logType | metadata.product_event_type | 直接複製值 |
| appVersion | metadata.product_version | 直接複製值 |
| 製造商 | principal.asset.hardware.manufacturer | 直接複製值 |
| 模型 | principal.asset.hardware.model | 直接複製值 |
| platformSerialNumber | principal.asset.hardware.serial_number | 直接複製值 |
| maas360DeviceID | principal.asset.hostname | 直接複製值 |
| maas360DeviceID | principal.hostname | 直接複製值 |
| wifiMacAddress | principal.mac | 如果不是空白或「不適用」,則會合併 |
| osName | principal.platform | 如果符合 (?i)windows,則設為 WINDOWS;如果符合 (?i)Mac,則設為 MAC |
| osVersion | principal.platform_version | 直接複製值 |
| deviceType | principal.resource.name | 直接複製值 |
| unifiedTravelerDeviceId | principal.resource.product_object_id | 直接複製值 |
| emailAddress | principal.user.email_addresses | 從 emailAddress 合併 |
| 使用者名稱 | principal.user.user_display_name | 直接複製值 |
| udid | principal.user.userid | 直接複製值 |
| metadata.product_name | metadata.product_name | 設為「IBM MaaS360」 |
| metadata.vendor_name | metadata.vendor_name | 設為「IBM」 |
變更記錄
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。