Collect Darktrace logs
This document explains how to ingest Darktrace logs to Google Security Operations using a Bindplane agent. This parser first extracts common fields from syslog messages, then uses conditional logic to handle both CEF and JSON formatted Darktrace logs. It maps extracted fields to the Unified Data Model (UDM) schema, enriching the data with security context and standardizing event categorization for downstream analysis.
Before you begin
Ensure that you have the following prerequisites:
- Google SecOps instance
- Windows 2016 or later or Linux host with systemd
- If running behind a proxy, firewall ports are open
- Privileged access to Darktrace
Get Google SecOps ingestion authentication file
- Sign in to the Google SecOps console.
- Go to SIEM Settings > Collection Agents.
- Download the Ingestion Authentication File. Save the file securely on the system where Bindplane will be installed.
Get Google SecOps customer ID
- Sign in to the Google SecOps console.
- Go to SIEM Settings > Profile.
- Copy and save the Customer IDfrom the Organization Detailssection.
Install the Bindplane agent
Windows installation
- Open the Command Promptor PowerShellas an administrator.
-
Run the following command:
msiexec / i ` https : // github . com / observIQ / bindplane - agent / releases / latest / download / observiq - otel - collector . msi ` / quiet
Linux installation
- Open a terminal with root or sudo privileges.
-
Run the following command:
sudo sh -c ` $( curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh ) ` install_unix.sh
Additional installation resources
For additional installation options, consult the installation guide .
Configure the Bindplane agent to ingest Syslog and send to Google SecOps
- Access the Configuration File:
- Locate the
config.yaml
file. Typically, it's in the/etc/bindplane-agent/
directory on Linux or in the installation directory on Windows. - Open the file using a text editor (for example,
nano
,vi
, or Notepad).
- Locate the
-
Edit the
config.yaml
file as follows:receivers : tcplog : # Replace the port and IP address as required listen_address : ` 0.0.0.0:10282` exporters : chronicle/chronicle_w_labels : compression : gzip # Adjust the path to the credentials file you downloaded in Step 1 creds : '/path/to/ingestion-authentication-file.json' # Replace with your actual customer ID from Step 2 customer_id : < customer_id > endpoint : malachiteingestion-pa.googleapis.com # Add optional ingestion labels for better organization ingestion_labels : log_type : DARKTRACE raw_log_field : body service : pipelines : logs/source0__chronicle_w_labels-0 : receivers : - tcplog exporters : - chronicle/chronicle_w_labels
-
Replace the port and IP address as required in your infrastructure.
-
Replace
<customer_id>
with the actual customer ID. -
Update
/path/to/ingestion-authentication-file.json
to the path where the authentication file was saved in the Get Google SecOps ingestion authentication file section.
Restart the Bindlane agent to apply the changes
-
To restart the Bindplane agent in Linux, run the following command:
sudo systemctl restart bindplane-agent
-
To restart the Bindplane agent in Windows, you can either use the Servicesconsole or enter the following command:
net stop BindPlaneAgent && net start BindPlaneAgent
Configure Syslog on Darktrace
- Sign in to the Darktraceweb UI.
- Go to Admin > System Config.
- Click Verify Alert Settings.
- Provide the following configuration details:
- CEF Syslog Alerts: Select True.
- CEF Syslog Server: Enter the Bindplane IP Address.
- CEF Syslog Server Port: Enter the Bindplane port number (for example,
10282
). - CEF Syslog TCP Alert: Select True.
- Click Save.
UDM mapping table
Log field | UDM mapping | Logic |
---|---|---|
darktraceUrl
|
security_result.url_back_to_product | The value is taken from the darktraceUrl
field. |
darktrace_host
|
observer.hostname | The value is taken from the darktrace_host
field if it is not an IP address. |
darktrace_ip
|
observer.ip | The value is taken from the darktrace_ip
field. |
darktrace_user
|
observer.user.userid | The value is taken from the darktrace_user
field. |
description
|
security_result.summary, metadata.description | The value is taken from the description
field. |
device.customFields.DT-AUTO.macaddress
|
principal.mac | The value is taken from the device.customFields.DT-AUTO.macaddress
field. |
device.did
|
principal.asset.asset_id | The value is taken from the device.did
field, converted to a string, and prefixed with Device ID:
. |
device.firstSeen
|
principal.asset.first_seen_time | The value is taken from the device.firstSeen
field, converted to a string, and parsed as a UNIX timestamp in milliseconds. |
device.hostname
|
principal.hostname, principal.asset.hostname | The value is taken from the device.hostname
field. |
device.ip
|
principal.ip, principal.asset.ip | The value is taken from the device.ip
field if it matches the IP address format. |
device.ips.0.subnet
|
additional.fields.subnet | The value is taken from the device.ips.0.subnet
field and prefixed with subnet
. |
device.ips.ip
|
principal.ip, principal.asset.ip | The value is taken from the device.ips.ip
field for each IP address in the list. |
device.lastSeen
|
principal.asset.last_discover_time | The value is taken from the device.lastSeen
field, converted to a string, and parsed as a UNIX timestamp in milliseconds. |
device.macaddress
|
principal.mac | The value is taken from the device.macaddress
field. |
device.objecttype
|
principal.asset.type | If the value is device
, the UDM field is set to WORKSTATION
. |
device.sid
|
principal.resource.attribute.labels.sid | The value is taken from the device.sid
field and converted to a string. |
device.typelabel
|
principal.resource.attribute.labels.typelabel | The value is taken from the device.typelabel
field. |
device.typename
|
principal.resource.attribute.labels.typename | The value is taken from the device.typename
field. |
dst
|
target.ip, target.asset.ip | The value is taken from the dst
field. |
dpt
|
target.port | The value is taken from the dpt
field and converted to an integer. |
dvc
|
principal.ip, principal.asset.ip | If the value of dvc
is an IP address, it is added to the UDM field. |
dvchost
|
principal.hostname, principal.asset.hostname | The value is taken from the dvchost
field. |
endpoint
|
target.url | The value is taken from the endpoint
field. |
event_time
|
metadata.event_timestamp | The value is taken from the event_time
field and parsed as an ISO8601 timestamp. |
externalId
|
metadata.product_log_id | The value is taken from the externalId
field. |
incidentEventUrl
|
principal.url | The value is taken from the incidentEventUrl
field. |
ip
|
principal.ip, principal.asset.ip | The value is taken from the ip
field if it matches the IP address format. |
issue_msg
|
security_result.summary | The value is taken from the issue_msg
field. |
message
|
security_result.description | The value is taken from the message
field. |
method
|
network.http.method | The value is taken from the method
field. |
model.description
|
metadata.description | The value is taken from the model.description
field. |
model.name
|
metadata.product_event_type | The value is taken from the model.name
field. |
model.now.category
|
security_result.severity | If the value is critical
, the UDM field is set to CRITICAL
. If the value is Informational
, the UDM field is set to INFORMATIONAL
. If the value is Suspicious
, the UDM field is set to HIGH
and the category is set to NETWORK_SUSPICIOUS
. |
model.now.description
|
metadata.description | The value is taken from the model.now.description
field. |
model.now.message
|
security_result.description | The value is taken from the model.now.message
field. |
model.now.name
|
metadata.product_event_type | The value is taken from the model.now.name
field. |
model.now.pid
|
principal.process.pid | The value is taken from the model.now.pid
field and converted to a string. |
model.now.uuid
|
principal.user.userid | The value is taken from the model.now.uuid
field and the event type is set to USER_UNCATEGORIZED
. |
model.pid
|
principal.process.pid | The value is taken from the model.pid
field and converted to a string. |
model.then.description
|
principal.resource.attribute.labels.Model Then Description | The value is taken from the model.then.description
field. |
model.then.name
|
principal.resource.attribute.labels.Model Then Name | The value is taken from the model.then.name
field. |
model.then.pid
|
principal.resource.attribute.labels.Model Then Pid | The value is taken from the model.then.pid
field and converted to a string. |
model.then.uuid
|
principal.resource.attribute.labels.Model Then UUID | The value is taken from the model.then.uuid
field. |
model.uuid
|
principal.user.userid | The value is taken from the model.uuid
field and the event type is set to USER_UNCATEGORIZED
. |
relatedBreaches.0.modelName
|
security_result.description | The value is taken from the relatedBreaches.0.modelName
field. |
score
|
security_result.priority, security_result.priority_details | If the value is between 0.8 and 1, the priority is set to HIGH_PRIORITY
. If the value is between 0.5 and 0.79, the priority is set to MEDIUM_PRIORITY
. If the value is between 0 and 0.49, the priority is set to LOW_PRIORITY
. The priority details are set to Score :
followed by the value of score
converted to a string. |
severity
|
security_result.severity | If the value is 2, the UDM field is set to MEDIUM
. If the value is greater than 2, the UDM field is set to HIGH
. |
shost
|
principal.hostname, principal.asset.hostname | The value is taken from the shost
field. |
smac
|
principal.mac | The value is taken from the smac
field. |
src
|
principal.ip, principal.asset.ip | The value is taken from the src
field. |
status
|
network.http.response_code | The value is taken from the status
field and converted to a string. |
summary
|
metadata.description | The value is taken from the summary
field. |
time
|
The value is taken from the time
field, converted to a string, and parsed as a UNIX timestamp in milliseconds. |
|
timestamp
|
The value is taken from the timestamp
field and parsed as either an ISO8601 timestamp or a UNIX timestamp in milliseconds. |
|
title
|
security_result.summary | The value is taken from the title
field. |
triggeredComponents.ip
|
intermediary.ip | The value is taken from the triggeredComponents.ip
field if it matches the IP address format. |
triggeredComponents.port
|
intermediary.port | The value is taken from the triggeredComponents.port
field and converted to an integer. |
username
|
principal.user.userid | The value is taken from the username
field. |
|
metadata.vendor_name | Set to DARKTRACE
. |
|
metadata.product_name | Set to DCIP
. |
|
metadata.log_type | Set to DARKTRACE
. |
|
network.ip_protocol | Set to TCP
if issue_msg
doesn't contain UDP
. Otherwise set to UDP
. |
|
security_result.action | Set to BLOCK
if status
is 401
, otherwise set to ALLOW
. |
|
security_result.severity | Set to INFORMATIONAL
. |
|
network.application_protocol | Set to HTTP
if method
is not empty. |
|
metadata.event_type | Set to NETWORK_HTTP
if method
is not empty. Set to USER_LOGIN
if description
contains logged into \\\\S+ over ssh
. Set to NETWORK_CONNECTION
if target_ip
is not empty. Otherwise, set to STATUS_UPDATE
. |
|
extensions.auth.type | Set to MACHINE
if description
contains logged into \\\\S+ over ssh
. |
|
security_result.category | Set to DATA_EXFILTRATION
if issue_msg
contains Exfiltration
. Set to NETWORK_MALICIOUS
if issue_msg
contains Compromise
. Otherwise, set to NETWORK_SUSPICIOUS
. |
Need more help? Get answers from Community members and Google SecOps professionals.