收集 Office 365 郵件追蹤記錄

支援的國家/地區:

本文說明如何使用多種擷取方法,將 Office 365 郵件追蹤記錄擷取至 Google Security Operations。擷取標籤會識別剖析器,該剖析器會將原始記錄資料正規化為具結構性的 UDM 格式。本文件中的資訊適用於具有 OFFICE_365_MESSAGETRACE 攝入標籤的剖析器。

Office 365 郵件追蹤是 Microsoft Exchange Online 的功能,可追蹤電子郵件訊息在 Exchange Online 郵件流程管道中的傳輸路徑。郵件追蹤記錄提供每封電子郵件訊息的詳細資訊,包括寄件者和收件者地址、主旨、傳送狀態、來源和目的地 IP 位址,以及郵件大小。這類資料對於排解郵件傳送問題、調查可疑電子郵件活動,以及監控電子郵件流量模式至關重要。

系統會使用 Exchange Online PowerShell 中的 Get-MessageTraceV2 cmdlet,以程式輔助方式擷取郵件追蹤資料。Exchange Online PowerShell 模組 (ExchangeOnlineManagement) 正式支援在 Windows、macOS 和 Linux 上使用 PowerShell 7.4.0 以上版本 (以及 Windows 上的 Windows PowerShell 5.1)。

事前準備

請確認您已完成下列事前準備事項:

  • Google SecOps 執行個體
  • 具備 Exchange Online 的 Microsoft 365 租戶
  • Microsoft 365 的全域管理員、Exchange 管理員或安全性讀取者角色
  • 存取 Google Cloud 控制台 (用於建立 API 金鑰、GCS 和 Webhook)
  • 在 Google SecOps 中建立及管理動態消息的權限
  • 專用的 Windows、macOS 或 Linux 伺服器/工作站,用於執行匯出指令碼:
    • Windows:Windows 10/11 或 Windows Server 2016 以上版本,並安裝 Windows PowerShell 5.1 (內建) 或 PowerShell 7.4.0 以上版本
    • macOS:macOS 13 Ventura 以上版本,且 PowerShell 7.4.0 以上版本
    • Linux:Debian 11 以上版本、Ubuntu 20.04 以上版本、RHEL 8 以上版本或 Fedora 36 以上版本,並安裝 PowerShell 7.4.0 以上版本
  • 從匯出電腦到 Microsoft 365 和 Google SecOps 擷取端點的網路連線

設定匯出環境

Office 365 郵件追蹤功能沒有內建的推送功能。您必須在專用的 Windows、macOS 或 Linux 伺服器/工作站上執行匯出指令碼,使用 PowerShell 從 Exchange Online 擷取郵件追蹤資料,然後傳送給 Google SecOps。

您可以使用 Exchange Online PowerShell 存取郵件追蹤資料,但須遵守下列保留期限:

  • Get-MessageTraceV2:傳回過去 10 天的資料。結果會立即顯示。
  • Start-HistoricalSearch:傳回10 到 90 天的資料。系統會將結果匯出為 CSV 報表供您下載,這可能需要數小時。

下列步驟會在電腦上安裝 PowerShell 和 Exchange Online PowerShell 模組。

安裝 PowerShell

Windows

Windows 10、Windows 11 和 Windows Server 2016 以上版本均內含 Windows PowerShell 5.1。不需要額外安裝。

  • 如要確認 PowerShell 版本,請開啟 PowerShell 並執行:

    $PSVersionTable.PSVersion
    
  • 如要安裝 PowerShell 7 以提升效能,請以管理員身分開啟「命令提示字元」或「PowerShell」,然後執行:

    winget install --id Microsoft.PowerShell --source winget
    

macOS

  1. 如果尚未安裝 Homebrew,請先完成這項程序。
  2. 開啟「終端機」並執行下列指令:

    brew install powershell/tap/powershell
    
  3. 執行下列指令,確認安裝成功:

    pwsh --version
    

    輸出內容應顯示 PowerShell 7.x.x 或更新版本。

Linux (Debian/Ubuntu)

  1. 開啟具有根層級或 sudo 權限的終端機。
  2. 執行下列指令:

    sudo apt-get update
    sudo apt-get install -y wget apt-transport-https software-properties-common
    source /etc/os-release
    wget -q "https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb"
    sudo dpkg -i packages-microsoft-prod.deb
    rm packages-microsoft-prod.deb
    sudo apt-get update
    sudo apt-get install -y powershell
    
  3. 執行下列指令,確認安裝成功:

    pwsh --version
    

Linux (RHEL/CentOS/Fedora)

  1. 開啟具有根層級或 sudo 權限的終端機。
  2. 註冊 Microsoft 存放區:

    curl "https://packages.microsoft.com/config/rhel/$(rpm -E %rhel)/prod.repo" | sudo tee /etc/yum.repos.d/microsoft.repo
    
  3. 安裝 PowerShell:

    sudo dnf install -y powershell
    
  4. 執行下列指令,確認安裝成功:

    pwsh --version
    

安裝 Exchange Online PowerShell 模組

安裝 PowerShell 後,請安裝 Exchange Online 管理模組。這個步驟在所有平台上都相同。

  1. 啟動 PowerShell:

    • Windows:以管理員身分開啟 PowerShellPowerShell 7
    • macOS 和 Linux:開啟終端機並執行 pwsh
  2. 執行下列指令:

    Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser -Force
    
  3. 如果系統提示您從不受信任的存放區 (PSGallery) 安裝,請輸入 Y 確認。

  4. 執行下列指令,確認安裝成功:

    Import-Module ExchangeOnlineManagement
    Get-Module ExchangeOnlineManagement | Select-Object Name, Version
    

輸出內容應會顯示模組名稱和版本號碼。

設定憑證式驗證 (排定的指令碼必須使用這項驗證方式)

Connect-ExchangeOnline -UserPrincipalName 方法需要互動式登入,因此無法用於排定的指令碼。如要無人值守執行,請使用 Azure AD (Microsoft Entra ID) 應用程式設定以憑證為準的驗證。

建立自行簽署的憑證

  • Windows (以管理員身分在 PowerShell 中執行):

    mkdir C:\Certs
    $cert = New-SelfSignedCertificate -Subject "CN=MessageTraceExport" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec KeyExchange -KeyLength 2048 -NotAfter (Get-Date).AddYears(2)
    $cert.Thumbprint
    Export-Certificate -Cert $cert -FilePath "C:\Certs\MessageTraceExport.cer"
    

    儲存指紋值,以供後續步驟使用。

  • macOS 和 Linux (在終端機中執行):

    mkdir -p /opt/certs
    openssl req -x509 -newkey rsa:2048 -keyout /opt/certs/messagetrace-key.pem -out /opt/certs/messagetrace-cert.pem -days 730 -nodes -subj "/CN=MessageTraceExport"
    openssl pkcs12 -export -out /opt/certs/messagetrace.pfx -inkey /opt/certs/messagetrace-key.pem -in /opt/certs/messagetrace-cert.pem -passout pass:
    chmod 644 /opt/certs/messagetrace.pfx
    
  • 取得憑證指紋:

    openssl x509 -in /opt/certs/messagetrace-cert.pem -noout -fingerprint -sha1 | sed 's/://g' | cut -d= -f2
    

    儲存指紋值,以供後續步驟使用。

在 Microsoft Entra ID 中註冊應用程式

  1. 登入 Microsoft Entra 系統管理中心
  2. 依序前往「身分識別」>「應用程式」>「應用程式註冊」
  3. 按一下 [新增註冊]
  4. 請提供下列設定詳細資料:
    • 「Name」(名稱):輸入 MessageTraceExport
    • 支援的帳戶類型:選取「僅限這個機構組織目錄中的帳戶」
  5. 按一下「註冊」
  6. 在應用程式總覽頁面中,複製「Application (client) ID」並儲存。
  7. 從總覽頁面複製並儲存「Directory (tenant) ID」

將憑證上傳至應用程式

  1. 在應用程式頁面中,依序前往「Certificates & secrets」(憑證和密鑰) >「Certificates」(憑證)
  2. 按一下「上傳憑證」
  3. 上傳憑證檔案:
    • Windows:上傳 C:\Certs\MessageTraceExport.cer
    • macOS 和 Linux:上傳 /opt/certs/messagetrace-cert.pem
  4. 按一下「新增」。

指派 API 權限

匯出指令碼會執行 Get-MessageTraceV2 cmdlet,這需要兩項 Office 365 Exchange Online 應用程式權限:Exchange.ManageAsApp (以應用程式身分驗證) 和 ReportingWebService.Read.All (讀取郵件追蹤資料)。如果缺少 ReportingWebService.Read.All,指令碼會失敗並顯示 403 The caller does not have permission 錯誤。

  1. 在應用程式頁面中,前往「API permissions」
  2. 按一下「新增權限」
  3. 選取「貴機構使用的 API」
  4. 搜尋並選取「Office 365 Exchange Online」
  5. 選取「應用程式權限」
  6. 新增下列兩項權限:
    • 展開「Exchange」,然後選取「Exchange.ManageAsApp」
    • 展開「ReportingWebService」,然後選取「ReportingWebService.Read.All」
  7. 按一下「Add permissions」。
  8. 按一下「Grant admin consent for <your organization>」,然後確認。

指派 Exchange 管理員角色

  1. 在 Microsoft Entra 系統管理中心,依序前往「身分識別」>「角色和管理員」>「所有角色」
  2. 搜尋並選取「Exchange 管理員」
  3. 按一下「新增作業」
  4. 按一下「尚未選取任何成員」,然後搜尋 MessageTraceExport 應用程式。
  5. 選取應用程式,然後按一下「下一步」
  6. 選取「有效」做為指派類型。
  7. 按一下「指派」

驗證無人值守連線

啟動 PowerShell 並執行:

  • Windows:

    Connect-ExchangeOnline -CertificateThumbprint "<CERTIFICATE_THUMBPRINT>" -AppId "<APPLICATION_ID>" -Organization "yourdomain.onmicrosoft.com"
    Get-MessageTraceV2 -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) -ResultSize 1
    Disconnect-ExchangeOnline -Confirm:$false
    
  • macOS 和 Linux (請先執行 pwsh):

    Connect-ExchangeOnline -CertificateFilePath "/opt/certs/messagetrace.pfx" -AppId "<APPLICATION_ID>" -Organization "yourdomain.onmicrosoft.com"
    Get-MessageTraceV2 -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) -ResultSize 1
    Disconnect-ExchangeOnline -Confirm:$false
    

    <CERTIFICATE_THUMBPRINT><APPLICATION_ID>yourdomain.onmicrosoft.com 替換為實際值。如果指令傳回郵件追蹤資料 (或沒有錯誤的空白結果集),表示驗證功能運作正常。

選擇擷取方法

Google SecOps 支援多種 Office 365 郵件追蹤記錄擷取方法。請選取最適合您環境的方法:

擷取方法 用途 延遲時間 設定複雜度
Webhook 從指令碼或應用程式即時推送
Google Cloud Storage V2 批次匯出至 GCS bucket 分鐘至小時

選項 1:透過 Webhook 擷取

如果您有可將含有訊息追蹤資料的 HTTP POST 要求傳送至 Google SecOps 的指令碼或應用程式,請使用這個方法。

在 Google SecOps 中建立 Webhook 動態饋給

建立動態饋給

  1. 依序前往「SIEM 設定」>「動態饋給」
  2. 按一下「新增動態消息」
  3. 在下一個頁面中,按一下「設定單一動態饋給」
  4. 在「動態饋給名稱」欄位中輸入動態饋給名稱 (例如 Office 365 Message Trace - Webhook)。
  5. 選取「Webhook」做為「來源類型」
  6. 選取「Office 365 Message Trace」做為「記錄類型」
  7. 點選「下一步」
  8. 指定下列輸入參數的值:
    • 分割分隔符號 (選用):輸入 \n,分割以換行符號分隔的 JSON 事件
    • 資產命名空間資產命名空間
    • 擷取標籤:要套用至這個動態饋給事件的標籤
  9. 點選「下一步」
  10. 在「Finalize」(完成) 畫面中檢查新的動態饋給設定,然後按一下「Submit」(提交)

產生並儲存密鑰

建立動態饋給後,您必須產生驗證用的密鑰:

  1. 在動態饋給詳細資料頁面中,按一下「產生密鑰」
  2. 對話方塊會顯示密鑰。
  3. 複製並妥善儲存密鑰。

取得動態消息端點網址

  1. 前往動態消息的「詳細資料」分頁。
  2. 在「端點資訊」部分,複製「動態消息端點網址」
  3. 網址格式為:

    https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate
    

    https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate
    
  4. 請儲存這個網址,以供後續步驟使用。

  5. 按一下 [完成]

建立 Google Cloud API 金鑰

Google SecOps 需要 API 金鑰才能進行驗證。在 Google Cloud 控制台中建立受限制的 API 金鑰。

建立 API 金鑰

  1. 前往 Google Cloud 控制台的「憑證」頁面
  2. 選取專案 (與 Google SecOps 執行個體相關聯的專案)。
  3. 依序按一下「建立憑證」>「API 金鑰」
  4. 系統會建立 API 金鑰,並顯示在對話方塊中。
  5. 按一下「編輯 API 金鑰」即可限制金鑰。

限制 API 金鑰

  1. 在「API 金鑰」設定頁面中:
    • 名稱:輸入描述性名稱 (例如 Google SecOps Webhook API Key - O365 Message Trace)
  2. 在「API 限制」下方:
    1. 選取「Restrict key」(限制金鑰)
    2. 在「選取 API」下拉式選單中,搜尋並選取「Google SecOps API」 (或「Chronicle API」)。
  3. 按一下 [儲存]
  4. 從頁面頂端的「API key」(API 金鑰) 欄位複製 API 金鑰值。
  5. 安全地儲存 API 金鑰。

建立 Webhook 匯出指令碼

在設定匯出環境的電腦上,建立下列 PowerShell 指令碼。這項指令碼會從 Exchange Online 擷取郵件追蹤資料,並傳送至 Google SecOps Webhook 端點。

Windows

  1. 建立指令碼目錄:

    mkdir C:\Scripts
    
  2. 建立名為 C:\Scripts\messagetrace-webhook.ps1 的檔案,並加入以下內容:

    # Configuration
    $endpointUrl = "https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate"
    $apiKey = "<API_KEY>"
    $secretKey = "<SECRET_KEY>"
    $certThumbprint = "<CERTIFICATE_THUMBPRINT>"
    $appId = "<APPLICATION_ID>"
    $organization = "yourdomain.onmicrosoft.com"
    
    # Log file
    $logFile = "C:\Logs\messagetrace-webhook.log"
    if (!(Test-Path "C:\Logs")) { New-Item -ItemType Directory -Path "C:\Logs" }
    
    try {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting message trace export"
    
        # Connect to Exchange Online using certificate-based authentication
        Connect-ExchangeOnline -CertificateThumbprint $certThumbprint -AppId $appId -Organization $organization -ShowBanner:$false
    
        # Retrieve message trace data for the last hour (up to 10 days available)
        $startDate = (Get-Date).AddHours(-1)
        $endDate = Get-Date
        $messages = Get-MessageTraceV2 -StartDate $startDate -EndDate $endDate -ResultSize 5000
    
        if ($messages.Count -eq 0) {
            Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - No messages found in the time range"
            Disconnect-ExchangeOnline -Confirm:$false
            exit 0
        }
    
        # Convert to NDJSON (one JSON object per line)
        $ndjson = ($messages | ForEach-Object { $_ | ConvertTo-Json -Compress }) -join "`n"
    
        # Send to Google SecOps webhook
        $headers = @{
            "X-goog-api-key"       = $apiKey
            "X-Webhook-Access-Key" = $secretKey
        }
    
        # Send raw UTF-8 bytes so PowerShell does not re-encode the NDJSON body
        $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes($ndjson)
        $response = Invoke-RestMethod -Uri $endpointUrl -Method Post -Headers $headers -Body $bodyBytes -ContentType "application/json"
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Successfully sent $($messages.Count) messages"
    }
    catch {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Error: $_"
    }
    finally {
        Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
    }
    
  3. 替換預留位置值:

    • <API_KEY>:Google Cloud API 金鑰
    • <SECRET_KEY>:Google SecOps Webhook 密鑰
    • <CERTIFICATE_THUMBPRINT>:驗證設定中的憑證指紋
    • <APPLICATION_ID>:Azure AD 應用程式 (用戶端) ID
    • yourdomain.onmicrosoft.com:您的 Microsoft 365 租戶網域

macOS 和 Linux

  1. 建立指令碼目錄:

    sudo mkdir -p /opt/scripts
    sudo mkdir -p /var/log/messagetrace
    
  2. 建立名為 /opt/scripts/messagetrace-webhook.ps1 的檔案,並加入以下內容:

    # Configuration
    $endpointUrl = "https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate"
    $apiKey = "<API_KEY>"
    $secretKey = "<SECRET_KEY>"
    $certFilePath = "/opt/certs/messagetrace.pfx"
    $appId = "<APPLICATION_ID>"
    $organization = "yourdomain.onmicrosoft.com"
    
    # Log file
    $logFile = "/var/log/messagetrace/messagetrace-webhook.log"
    
    try {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting message trace export"
    
        # Connect to Exchange Online using certificate-based authentication
        Connect-ExchangeOnline -CertificateFilePath $certFilePath -AppId $appId -Organization $organization -ShowBanner:$false
    
        # Retrieve message trace data for the last hour (up to 10 days available)
        $startDate = (Get-Date).AddHours(-1)
        $endDate = Get-Date
        $messages = Get-MessageTraceV2 -StartDate $startDate -EndDate $endDate -ResultSize 5000
    
        if ($messages.Count -eq 0) {
            Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - No messages found in the time range"
            Disconnect-ExchangeOnline -Confirm:$false
            exit 0
        }
    
        # Convert to NDJSON (one JSON object per line)
        $ndjson = ($messages | ForEach-Object { $_ | ConvertTo-Json -Compress }) -join "`n"
    
        # Send to Google SecOps webhook
        $headers = @{
            "X-goog-api-key"       = $apiKey
            "X-Webhook-Access-Key" = $secretKey
        }
    
        # Send raw UTF-8 bytes so PowerShell does not re-encode the NDJSON body
        $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes($ndjson)
        $response = Invoke-RestMethod -Uri $endpointUrl -Method Post -Headers $headers -Body $bodyBytes -ContentType "application/json"
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Successfully sent $($messages.Count) messages"
    }
    catch {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Error: $_"
    }
    finally {
        Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
    }
    
  3. 替換預留位置值:

    • <API_KEY>:Google Cloud API 金鑰
    • <SECRET_KEY>:Google SecOps Webhook 密鑰
    • <APPLICATION_ID>:Azure AD 應用程式 (用戶端) ID
    • yourdomain.onmicrosoft.com:您的 Microsoft 365 租戶網域
  4. 設定檔案權限:

    sudo chmod 700 /opt/scripts/messagetrace-webhook.ps1
    

排定匯出指令碼

將指令碼設定為定期自動執行 (例如每小時執行一次)。

Windows

  1. 開啟「工作排程器」:按下 Win+R 鍵,輸入 taskschd.msc,然後按下 Enter 鍵。
  2. 點選右側窗格中的「Create Task」
  3. 在「一般」分頁中:
    • 「Name」(名稱):輸入 MessageTrace Webhook Export
    • 選取「無論使用者是否登入,都執行」
    • 選取「以最高權限執行」
  4. 在「Triggers」分頁中:
    1. 點選「New」(新增)
    2. 將「Begin the task」設為「On a schedule」
    3. 選取「每日」,將「開始」時間設為 12:00:00 AM (午夜,因此會以整點重複執行),然後設定「每 1 天重複一次」
    4. 選取「每隔一段時間重複工作」1 hour「無限期」
    5. 選取 [已啟用]
    6. 按一下 [確定]
  5. 在「動作」分頁中:

    1. 點選「New」(新增)
    2. 將「動作」設為「啟動程式」
    3. 在「Program/script」(程式/指令碼) 欄位中輸入:

      powershell.exe
      
    4. 在「Add arguments」(新增引數) 欄位中輸入:

      -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\messagetrace-webhook.ps1"
      
    5. 按一下 [確定]

  6. 在「設定」分頁中:

    • 選取「允許工作隨選執行」
    • 取消勾選「如果工作執行時間超過」核取方塊
  7. 按一下「確定」,然後在系統提示時輸入服務帳戶憑證。

macOS

  1. ~/Library/LaunchAgents/com.chronicle.messagetrace-webhook.plist 建立 launchd plist 檔案:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.chronicle.messagetrace-webhook</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/pwsh</string>
            <string>-NoProfile</string>
            <string>-File</string>
            <string>/opt/scripts/messagetrace-webhook.ps1</string>
        </array>
        <key>StartInterval</key>
        <integer>3600</integer>
        <key>StandardOutPath</key>
        <string>/var/log/messagetrace/launchd-stdout.log</string>
        <key>StandardErrorPath</key>
        <string>/var/log/messagetrace/launchd-stderr.log</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
    </plist>
    
  2. 載入工作:

    launchctl load ~/Library/LaunchAgents/com.chronicle.messagetrace-webhook.plist
    
  3. 確認工作已載入:

    launchctl list | grep messagetrace
    

Linux

  1. 開啟 crontab 編輯器:

    crontab -e
    
  2. 新增下列程式碼,每小時執行一次指令碼:

    0 * * * * /usr/bin/pwsh -NoProfile -File /opt/scripts/messagetrace-webhook.ps1 >> /var/log/messagetrace/cron.log 2>&1
    
  3. 儲存並結束編輯器。

  4. 確認 Cron 工作已註冊:

    crontab -l
    

確認記錄擷取作業

  1. 手動執行指令碼進行測試:

    Windows:

    powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\messagetrace-webhook.ps1"
    

    macOS 和 Linux:

    pwsh -NoProfile -File /opt/scripts/messagetrace-webhook.ps1
    
  2. 檢查記錄檔是否有錯誤:

    Windows:

    Get-Content "C:\Logs\messagetrace-webhook.log" -Tail 10
    

    macOS 和 Linux:

    tail -10 /var/log/messagetrace/messagetrace-webhook.log
    
  3. 在 Google SecOps 中前往「搜尋」,確認是否顯示含有 metadata.log_type = "OFFICE_365_MESSAGETRACE" 的記錄。

選項 2:Google Cloud Storage V2 擷取

如果匯出指令碼會將郵件追蹤記錄寫入 Google Cloud Storage 值區,請使用這個方法。

建立 GCS bucket

  1. 前往 Google Cloud 控制台
  2. 選取專案或建立新專案。
  3. 在導覽選單中,依序前往「Cloud Storage」>「Bucket」
  4. 按一下「建立值區」
  5. 請提供下列設定詳細資料:

    設定
    為 bucket 命名 輸入全域不重複的名稱 (例如 office365-messagetrace-logs)
    位置類型 根據需求選擇 (區域、雙區域、多區域)
    位置 選取位置 (例如 us-central1)
    儲存空間級別 標準 (建議用於經常存取的記錄)
    存取控管 統一 (建議)
    保護工具 選用:啟用物件版本管理或資料保留政策
  6. 點選「建立」

安裝 Google Cloud CLI

在設定匯出環境的同一部電腦上安裝 Google Cloud CLI。gsutil 指令 (隨附於 Google Cloud CLI) 用於將檔案上傳至 GCS bucket。

Windows

  1. 下載 Google Cloud CLI 安裝程式 (GoogleCloudSDKInstaller.exe)。
  2. 執行 GoogleCloudSDKInstaller.exe。 在「安裝選項」畫面上,請保留預設選取項目。按一下「安裝」。安裝完成後,請保持選取「執行」gcloud init,然後按一下「完成」
  3. 開啟「命令提示字元」並執行下列指令,確認安裝成功:

    gcloud --version
    gsutil --version
    

macOS

  1. 開啟「終端機」並執行下列指令:

    brew install google-cloud-sdk
    
  2. 驗證安裝項目:

    gcloud --version
    gsutil --version
    

Linux (Debian/Ubuntu)

  1. 開啟具有根層級或 sudo 權限的終端機。
  2. 執行下列指令:

    sudo apt-get install -y apt-transport-https ca-certificates gnupg curl
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
    echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
    sudo apt-get update
    sudo apt-get install -y google-cloud-cli
    
  3. 驗證安裝項目:

    gcloud --version
    gsutil --version
    

Linux (RHEL/CentOS/Fedora)

  1. 開啟具有根層級或 sudo 權限的終端機。
  2. 建立存放區檔案:

    sudo tee /etc/yum.repos.d/google-cloud-sdk.repo << 'EOF'
    [google-cloud-cli]
    name=Google Cloud CLI
    baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el9-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=0
    gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    EOF
    
  3. 安裝 Google Cloud CLI:

    sudo dnf install -y google-cloud-cli
    
  4. 驗證安裝項目:

    gcloud --version
    gsutil --version
    

驗證 Google Cloud CLI

  1. 執行下列指令進行驗證:

    gcloud auth login
    
  2. 設定含有 GCS bucket 的專案:

    gcloud config set project <PROJECT_ID>
    

    <PROJECT_ID> 替換為您的 Google Cloud 專案 ID。

如要無人值守 (排程) 使用,請使用服務帳戶金鑰進行驗證。匯出指令碼會使用這個服務帳戶,將檔案上傳至 GCS bucket。這與用於從值區讀取資料的 Google SecOps 服務帳戶不同 (在後續步驟中設定)。

  1. 前往 Google Cloud 控制台,然後選取您的專案。
  2. 按一下「Create Service Account」(建立服務帳戶)
  3. 在「Service account name」(服務帳戶名稱) 欄位中輸入名稱 (例如 chronicle-gcs-export)。
  4. 按一下「建立並繼續」
  5. 在「將專案存取權授予這個服務帳戶」部分,選取「Storage Object Creator」(Storage 物件建立者) 角色。
  6. 按一下 [完成]
  7. 在服務帳戶清單中,按一下您建立的服務帳戶。
  8. 前往「金鑰」分頁標籤。
  9. 依序點選「新增金鑰」>「建立新的金鑰」
  10. 選擇「JSON」然後按下 [Create] (建立)
  11. 儲存下載的 JSON 金鑰檔案:
    • WindowsC:\Certs\gcs-service-account.json
    • macOS 和 Linux/opt/certs/gcs-service-account.json
  12. 啟用服務帳戶:

    gcloud auth activate-service-account --key-file=<PATH_TO_KEY_FILE>
    

建立 GCS 匯出指令碼

Windows

  1. 建立名為 C:\Scripts\messagetrace-gcs.ps1 的檔案,並加入以下內容:

    # Configuration
    $certThumbprint = "<CERTIFICATE_THUMBPRINT>"
    $appId = "<APPLICATION_ID>"
    $organization = "yourdomain.onmicrosoft.com"
    $gcsBucket = "gs://office365-messagetrace-logs/messagetrace/"
    $localLogDir = "C:\Logs\MessageTrace"
    
    # Log file
    $logFile = "C:\Logs\messagetrace-gcs.log"
    if (!(Test-Path $localLogDir)) { New-Item -ItemType Directory -Path $localLogDir }
    
    try {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting message trace export to GCS"
    
        # Connect to Exchange Online using certificate-based authentication
        Connect-ExchangeOnline -CertificateThumbprint $certThumbprint -AppId $appId -Organization $organization -ShowBanner:$false
    
        # Retrieve message trace data for the last hour (up to 10 days available)
        $startDate = (Get-Date).AddHours(-1)
        $endDate = Get-Date
        $messages = Get-MessageTraceV2 -StartDate $startDate -EndDate $endDate -ResultSize 5000
    
        if ($messages.Count -eq 0) {
            Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - No messages found in the time range"
            Disconnect-ExchangeOnline -Confirm:$false
            exit 0
        }
    
        # Convert to NDJSON (one JSON object per line)
        $ndjson = $messages | ForEach-Object { $_ | ConvertTo-Json -Compress }
        $fileName = "messagetrace_$(Get-Date -Format 'yyyyMMddHHmmss').json"
        $filePath = Join-Path $localLogDir $fileName
        $ndjson | Out-File -FilePath $filePath -Encoding UTF8
    
        # Upload to GCS
        gsutil cp $filePath $gcsBucket
    
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Uploaded $fileName with $($messages.Count) messages"
    
        # Remove local file after successful upload
        Remove-Item $filePath
    }
    catch {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Error: $_"
    }
    finally {
        Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
    }
    
  2. 替換預留位置值:

    • <CERTIFICATE_THUMBPRINT>:驗證設定中的憑證指紋
    • <APPLICATION_ID>:Azure AD 應用程式 (用戶端) ID
    • yourdomain.onmicrosoft.com:您的 Microsoft 365 租戶網域
    • office365-messagetrace-logs:您的 GCS bucket 名稱

macOS 和 Linux

  1. 建立名為 /opt/scripts/messagetrace-gcs.ps1 的檔案,並加入以下內容:

    # Configuration
    $certFilePath = "/opt/certs/messagetrace.pfx"
    $appId = "<APPLICATION_ID>"
    $organization = "yourdomain.onmicrosoft.com"
    $gcsBucket = "gs://office365-messagetrace-logs/messagetrace/"
    $localLogDir = "/var/log/messagetrace/export"
    
    # Log file
    $logFile = "/var/log/messagetrace/messagetrace-gcs.log"
    if (!(Test-Path $localLogDir)) { New-Item -ItemType Directory -Path $localLogDir }
    
    try {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting message trace export to GCS"
    
        # Connect to Exchange Online using certificate-based authentication
        Connect-ExchangeOnline -CertificateFilePath $certFilePath -AppId $appId -Organization $organization -ShowBanner:$false
    
        # Retrieve message trace data for the last hour (up to 10 days available)
        $startDate = (Get-Date).AddHours(-1)
        $endDate = Get-Date
        $messages = Get-MessageTraceV2 -StartDate $startDate -EndDate $endDate -ResultSize 5000
    
        if ($messages.Count -eq 0) {
            Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - No messages found in the time range"
            Disconnect-ExchangeOnline -Confirm:$false
            exit 0
        }
    
        # Convert to NDJSON (one JSON object per line)
        $ndjson = $messages | ForEach-Object { $_ | ConvertTo-Json -Compress }
        $fileName = "messagetrace_$(Get-Date -Format 'yyyyMMddHHmmss').json"
        $filePath = Join-Path $localLogDir $fileName
        $ndjson | Out-File -FilePath $filePath -Encoding UTF8
    
        # Upload to GCS
        gsutil cp $filePath $gcsBucket
    
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Uploaded $fileName with $($messages.Count) messages"
    
        # Remove local file after successful upload
        Remove-Item $filePath
    }
    catch {
        Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Error: $_"
    }
    finally {
        Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
    }
    
  2. 替換預留位置值:

    • <APPLICATION_ID>:Azure AD 應用程式 (用戶端) ID
    • yourdomain.onmicrosoft.com:您的 Microsoft 365 租戶網域
    • office365-messagetrace-logs:您的 GCS bucket 名稱
  3. 設定檔案權限:

    sudo chmod 700 /opt/scripts/messagetrace-gcs.ps1
    

排定 GCS 匯出指令碼

Windows

  1. 開啟「工作排程器」:按下 Win+R 鍵,輸入 taskschd.msc,然後按下 Enter 鍵。
  2. 點選右側窗格中的「Create Task」
  3. 在「一般」分頁中:
    • 「Name」(名稱):輸入 MessageTrace GCS Export
    • 選取「無論使用者是否登入,都執行」
    • 選取「以最高權限執行」
  4. 在「Triggers」分頁中:
    1. 點選「New」(新增)
    2. 將「Begin the task」設為「On a schedule」
    3. 選取「每日」,將「開始」時間設為 12:00:00 AM (午夜,因此會以整點重複執行),然後設定「每 1 天重複一次」
    4. 選取「每隔一段時間重複工作」1 hour「無限期」
    5. 選取 [已啟用]
    6. 按一下 [確定]
  5. 在「動作」分頁中:

    1. 點選「New」(新增)
    2. 將「動作」設為「啟動程式」
    3. 在「Program/script」(程式/指令碼) 欄位中輸入:

      powershell.exe
      
    4. 在「Add arguments」(新增引數) 欄位中輸入:

      -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\messagetrace-gcs.ps1"
      
    5. 按一下 [確定]

  6. 在「設定」分頁中:

    • 選取「允許工作隨選執行」
    • 取消勾選「如果工作執行時間超過」核取方塊
  7. 按一下「確定」,然後在系統提示時輸入服務帳戶憑證。

macOS

  1. ~/Library/LaunchAgents/com.chronicle.messagetrace-gcs.plist 建立 launchd plist 檔案:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.chronicle.messagetrace-gcs</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/pwsh</string>
            <string>-NoProfile</string>
            <string>-File</string>
            <string>/opt/scripts/messagetrace-gcs.ps1</string>
        </array>
        <key>StartInterval</key>
        <integer>3600</integer>
        <key>StandardOutPath</key>
        <string>/var/log/messagetrace/launchd-gcs-stdout.log</string>
        <key>StandardErrorPath</key>
        <string>/var/log/messagetrace/launchd-gcs-stderr.log</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
    </plist>
    
  2. 載入工作:

    launchctl load ~/Library/LaunchAgents/com.chronicle.messagetrace-gcs.plist
    
  3. 確認工作已載入:

    launchctl list | grep messagetrace
    

Linux

  1. 開啟 crontab 編輯器:

    crontab -e
    
  2. 新增下列程式碼,每小時執行一次指令碼:

    0 * * * * /usr/bin/pwsh -NoProfile -File /opt/scripts/messagetrace-gcs.ps1 >> /var/log/messagetrace/cron-gcs.log 2>&1
    
  3. 儲存並結束編輯器。

  4. 確認 Cron 工作已註冊:

    crontab -l
    

驗證 GCS 上傳作業

  1. 手動執行指令碼進行測試:

    Windows:

    powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\messagetrace-gcs.ps1"
    

    macOS 和 Linux:

    pwsh -NoProfile -File /opt/scripts/messagetrace-gcs.ps1
    
  2. 確認檔案已上傳至 GCS bucket:

    gsutil ls gs://office365-messagetrace-logs/messagetrace/
    
  3. 檢查記錄檔是否有錯誤:

    Windows:

    Get-Content "C:\Logs\messagetrace-gcs.log" -Tail 10
    

    macOS 和 Linux:

    tail -10 /var/log/messagetrace/messagetrace-gcs.log
    

取得 Google SecOps 服務帳戶

  1. 依序前往「SIEM 設定」>「動態饋給」
  2. 按一下「新增動態消息」
  3. 按一下「設定單一動態饋給」
  4. 在「動態饋給名稱」欄位中輸入動態饋給名稱 (例如 Office 365 Message Trace - GCS)。
  5. 選取「Google Cloud Storage V2」做為「來源類型」
  6. 選取「Office 365 Message Trace」做為「記錄類型」
  7. 按一下「取得服務帳戶」
  8. 系統會顯示專屬服務帳戶電子郵件地址,例如:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. 複製這個電子郵件地址,以便在下一步中使用。

授予 IAM 權限

  1. 依序前往「Cloud Storage」>「Buckets」
  2. 點按 bucket 名稱。
  3. 前往「權限」分頁標籤。
  4. 按一下「授予存取權」
  5. 請提供下列設定詳細資料:
    • 新增主體:貼上 Google SecOps 服務帳戶電子郵件地址
    • 指派角色:選取「Storage 物件檢視者」
  6. 按一下 [儲存]

為 GCS 設定 Google SecOps 資訊提供

  1. 從動態消息建立頁面繼續操作 (或依序前往「SIEM 設定」>「動態消息」>「新增動態消息」)。
  2. 點選「下一步」
  3. 指定下列輸入參數的值:

    • 儲存空間 bucket URL:輸入 GCS bucket URI,並加上前置路徑:

      gs://office365-messagetrace-logs/messagetrace/
      
    • 來源刪除選項:根據偏好選取刪除選項:
      • 永不:永不刪除移轉後的任何檔案 (建議用於測試)
      • 刪除轉移的檔案:成功轉移檔案後刪除檔案
      • 刪除已轉移的檔案和空白目錄:成功轉移後刪除檔案和空白目錄
    • 檔案存在時間上限:包含在過去天數內修改的檔案 (預設為 180 天)
    • 資產命名空間資產命名空間
    • 擷取標籤:要套用至這個動態饋給事件的標籤
  4. 點選「下一步」

  5. 在「Finalize」(完成) 畫面中檢查新的動態饋給設定,然後按一下「Submit」(提交)

UDM 對應表

下表列出 OFFICE_365_MESSAGETRACE 記錄類型的記錄欄位,以及對應的 UDM 欄位。

記錄欄位 UDM 對應 邏輯
additional_AdditionalFields additional.fields 已合併
additional_DeliveryLocation additional.fields 已合併
additional_OrgLevelPolicy additional.fields 已合併
additional_connectors additional.fields 已合併
additional_delivery_action additional.fields 已合併
additional_fields_UrlLocation additional.fields 已合併
additional_orgLevelAction additional.fields 已合併
end_date_label additional.fields 已合併
index_label additional.fields 已合併
metadata_id_label additional.fields 已合併
operationName_label additional.fields 已合併
start_date_label additional.fields 已合併
tenant_label additional.fields 已合併
type_label additional.fields 已合併
properties.AuthenticationDetails extensions.auth.auth_details 直接對應
Received metadata.event_timestamp 已剖析為 UNIX_MS
time metadata.event_timestamp 已剖析為 ISO8601
tenantId metadata.product_deployment_id 直接對應
category metadata.product_event_type 直接對應
MessageTraceId metadata.product_log_id 直接對應
SenderAddress network.email.from 直接對應
properties.SenderFromAddress network.email.from 直接對應
MessageId network.email.mail_id 直接對應
Subject network.email.subject 已合併
properties.Subject network.email.subject 已合併
RecipientAddress network.email.to 已合併
properties.RecipientEmailAddress network.email.to 已合併
Size network.received_bytes 直接對應
Organization principal.administrative_domain 直接對應
properties.SenderFromDomain principal.administrative_domain 直接對應
FromIP principal.ip 已合併
properties.FileName principal.process.file.names 已合併
properties.SHA256 principal.process.file.sha256 直接對應
properties.FileSize principal.process.file.size 已重新命名/對應
additional_UserLevelAction principal.user.attribute.labels 已合併
additional_UserLevelPolicy principal.user.attribute.labels 已合併
sender_email_from_domain_label principal.user.attribute.labels 已合併
properties.SenderFromAddress principal.user.email_addresses 已合併
properties.SenderObjectId principal.user.product_object_id 直接對應
properties.SenderDisplayName principal.user.user_display_name 直接對應
action security_result.action 已合併
Status security_result.action_details 直接對應
security_result_category security_result.category 已合併
properties.ConfidenceLevel security_result.confidence_details 直接對應
detect_method security_result.detection_fields 已合併
detection_method security_result.rule_name 直接對應
properties.ThreatNames security_result.threat_name 直接對應
properties.UrlDomain target.asset.hostname 直接對應
ToIP target.asset.ip 已合併
properties.UrlDomain target.hostname 直接對應
ToIP target.ip 已合併
properties.Url target.url 直接對應
properties.RecipientEmailAddress target.user.email_addresses 已合併
properties.RecipientObjectId target.user.product_object_id 直接對應
不適用 metadata.event_type 常數:EMAIL_TRANSACTION
不適用 network.direction 常數:INBOUND
不適用 principal.process.file.file_type 常數:FILE_TYPE_PNG
不適用 security_result.confidence 常數:HIGH_CONFIDENCE
id event.idm.read_only_udm.metadata.product_log_id 從變更記錄對應
receivedDateTime event.idm.read_only_udm.metadata.event_timestamp 從變更記錄對應
fromIP event.idm.read_only_udm.principal.ipevent.idm.read_only_udm.principal.asset.ip 從變更記錄對應
toIP event.idm.read_only_udm.target.ipevent.idm.read_only_udm.target.asset.ip 從變更記錄對應
status event.idm.read_only_udm.security_result.action_details 從變更記錄對應
size event.idm.read_only_udm.network.received_bytes 從變更記錄對應
senderAddress event.idm.read_only_udm.network.email.from 從變更記錄對應
recipientAddress event.idm.read_only_udm.network.email.to 從變更記錄對應
subject event.idm.read_only_udm.network.email.subject 從變更記錄對應
messageId event.idm.read_only_udm.network.email.mail_id 從變更記錄對應
properties.SenderMailFromDomain", "properties.UserLevelAction", and "properties.UserLevelPolicy principal.user.attribute.labels 從變更記錄對應
properties.EmailDirection network.direction 從變更記錄對應
properties.DeliveryAction", "properties.DeliveryLocation", "properties.Connectors", "properties.OrgLevelAction", "properties.OrgLevelPolicy", "properties.AdditionalFields", and "properties.UrlLocation additional.fields 從變更記錄對應
operationName", "Tenant additional.fields 從變更記錄對應
properties.DetectionMethods security_result.detection_fields 從變更記錄對應

變更記錄

查看這個剖析器的變更記錄

還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。