Initial AI Audit of existing docs against codebase

This commit is contained in:
Brandon Hopkins
2026-08-19 11:18:01 -07:00
parent b1629b1d11
commit 767f10d0eb
11 changed files with 937 additions and 407 deletions

View File

@@ -368,7 +368,7 @@ export const docsNavigation = [
href: '/manage/activity/traffic-events-logging',
},
{
title: 'Stream Activity Events',
title: 'Event Streaming',
href: '/manage/activity/event-streaming',
isOpen: false,
links: [
@@ -381,20 +381,23 @@ export const docsNavigation = [
href: '/manage/activity/event-streaming/amazon-s3',
},
{
title: 'Amazon Firehose',
title: 'Amazon Data Firehose',
href: '/manage/activity/event-streaming/amazon-firehose',
},
{
title: 'SentinelOne Data Lake',
href: '/manage/activity/event-streaming/sentinelone-data-lake',
},
{
title: 'Generic HTTP',
href: '/manage/activity/event-streaming/generic-http',
},
{
title: 'Wazuh',
href: '/manage/activity/event-streaming/wazuh',
isOpen: false,
links: [
{
title: 'SentinelOne Data Lake',
href: '/manage/activity/event-streaming/sentinelone-data-lake',
},
{
title: 'Wazuh',
href: '/manage/activity/event-streaming/wazuh',
},
],
},
],
},

View File

@@ -57,6 +57,7 @@ To clear all saved service parameters (including env vars), run `sudo netbird se
| `NB_DISABLE_CONNTRACK` | All | Turn off the stateful connection tracker in the userspace packet filter. With conntrack enabled (default), inbound rules for return traffic sent by management are ignored because conntrack handles them automatically. Disabling conntrack means those inbound rules will be applied explicitly instead. |
| `NB_DISABLE_USERSPACE_ROUTING` | All | Prevent the userspace packet filter from forwarding packets between interfaces. Routing rules from the management server will be ignored when this is set. |
| `NB_DISABLE_MSS_CLAMPING` | All | Stop the userspace filter from rewriting TCP SYN/SYN-ACK MSS options to fit the WireGuard MTU. May cause path-MTU black holes if disabled. |
| `NB_FORCE_USERSPACE_FIREWALL` | Linux | Force peer ACLs through the userspace packet filter even when a native nftables/iptables backend is available. Only takes effect when the WireGuard interface already runs in userspace, so pair it with `NB_WG_KERNEL_DISABLED=true`. Required if you want blocked-connection events and policy IDs in [Traffic Events Logging](/manage/activity/traffic-events-logging), which only the userspace filter reports. Costs extra CPU on high-throughput peers. |
| `NB_FORCE_USERSPACE_ROUTER` | All | Force packet forwarding through the userspace router even when a native firewall backend (nftables/iptables) is available. Normally, the presence of a native backend causes the client to delegate route forwarding to the kernel. This flag overrides that: the native backend still handles ACL rules, but routed packets are forwarded by the userspace filter instead. On macOS, Windows, and netstack mode the userspace router is always used regardless of this setting. |
| `NB_ENABLE_LOCAL_FORWARDING` | All | Allow the userspace filter to forward packets destined for local addresses (not just routed subnets). Off by default to prevent unexpected local service exposure. |
| `NB_ENABLE_NETSTACK_LOCAL_FORWARDING` | All | Same as `NB_ENABLE_LOCAL_FORWARDING` but applies only when running in netstack mode. Takes precedence over the general setting when both are set. |

View File

@@ -4,8 +4,15 @@
an other AWS services. You can use Amazon Data Firehose as a bridge between NetBird and other third-party providers that support Data Firehose
to ingest, transform and analyze your network activity events.
NetBird sends audit and traffic events to the Firehose stream in real-time once they occur. Because Firehose buffers and batches
records before delivering them, it is the more efficient option when your destination is Amazon S3. See the
[Amazon S3 integration](/manage/activity/event-streaming/amazon-s3) if you prefer writing one object per event instead.
<Note>
This feature is only available in the cloud version of NetBird.
Event streaming is a paid feature. On NetBird Cloud it is available on the **Business** plan and above, and during a trial.
On a self-hosted deployment it requires the [Enterprise Commercial License](/selfhosted/enterprise); the open source
Community Edition does not serve the event streaming API, so the tab stays locked. Self-hosted dashboards started showing
the Event Streaming tab in dashboard `v2.80.0`.
</Note>
## Prerequisites
@@ -13,19 +20,31 @@ to ingest, transform and analyze your network activity events.
Before you start creating and configuring an Amazon Data Firehose event streaming integration, ensure that you have the following:
- An AWS account with the permissions to create and manage Data Firehose delivery streams.
- Permissions to create and manage IAM users, roles and policies.
- A NetBird user with permission to manage integrations, such as an account owner or admin.
If you don't have the required permissions, ask your AWS administrator to grant them to you.
## Create a Data Firehose Stream
- Navigate to the [Data Firehose Dashboard](https://console.aws.amazon.com/firehose/home)
- Click `Create Firehose stream`
- As source select `Direct PUT` and the desired destination
- As `Source` select `Direct PUT`
- As `Destination` select the AWS service you want to push the events to
- Give it a descriptive name like `netbird-activity-events` and configure the stream to your needs
- Click `Create Firehose stream`
<Note>
Create the stream in one of the regions NetBird offers in the setup wizard. See [Supported regions](#supported-regions)
for the full list. AWS GovCloud and the China regions are not available.
</Note>
You can use the stream's transformation and format conversion settings to reshape the event messages before they reach the
destination.
## Create an IAM User
- Navigate to the [IAM Dashboard](https://console.aws.amazon.com/iam/home)
- Create an IAM User (for details see the [Amazon Docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html))
- Create a custom policy with the following permissions (replace the resource with the ARN of your delivery stream):
- Create a custom policy with the following permissions, scoped to the stream you created (replace `region`, `accountID`, and
the stream name with your own values):
```json
{
"Version": "2012-10-17",
@@ -36,7 +55,7 @@ If you don't have the required permissions, ask your AWS administrator to grant
"firehose:PutRecord",
"firehose:PutRecordBatch"
],
"Resource": "arn:aws:firehose:region:accountID:deliverystream/netbird-event-streaming"
"Resource": "arn:aws:firehose:region:accountID:deliverystream/netbird-activity-events"
}
]
}
@@ -48,22 +67,76 @@ If you don't have the required permissions, ask your AWS administrator to grant
- Give it a description
- Store `Access key` and `Secret access key` in a secure place. You will need these when configuring an integration in NetBird.
<Note>
`firehose:PutRecord` and `firehose:PutRecordBatch` are the only permissions NetBird needs. Do not grant read or management
permissions to this user.
</Note>
## Create an Integration in NetBird
- Navigate to the [Integrations &raquo; Event Streaming](https://preview.netbird.io/integrations) tab in the NetBird dashboard
- Navigate to the [Integrations &raquo; Event Streaming](https://app.netbird.io/integrations?tab=event-streaming) tab in the NetBird dashboard
<p>
<img src="/docs-static/img/manage/activity/event-streaming/event-streaming-integration.png" alt="event-streaming-integration" className="imagewrapper-big"/>
</p>
- Enable and configure the `Amazon Data Firehose` integration
- First select the region your Firehose stream is created in
- On the `Amazon Data Firehose` card, click `Connect Amazon Data Firehose` or turn the card's toggle on to open the
`Connect NetBird with Amazon Data Firehose` wizard. The wizard has three steps, and each step's button stays disabled until you
fill in the field on that step.
- Step 1, `Select your Amazon Data Firehose region`: pick the region your stream lives in and click `Continue`. The dropdown
defaults to `US East (N. Virginia)`, so change it if your stream is elsewhere.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-firehose/firehose-region-select.png" alt="firehose-region-select" className="imagewrapper" />
</p>
- Then enter the Firehose stream name you created in [Step 1](#step-1-create-a-data-firehose-stream) and click `Next`
- Step 2, `Create your Firehose Stream`: under `Enter your Firehose stream name`, enter the stream you created in
[Create a Data Firehose Stream](#create-a-data-firehose-stream) and click `Continue`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-firehose/firehose-stream-name.png" alt="firehose-stream-name" className="imagewrapper" />
</p>
- Enter the `Access key` and `Secret access key` you created in [Step 2](#step-2-create-an-iam-user-2) and click `Connect`
- Step 3, `Create IAM credential`: enter the access key under `Enter your Access-Key`, the secret under `Enter your Secret-Key`,
both created in [Create an IAM User](#create-an-iam-user), and click `Connect`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-firehose/firehose-iam-credentials.png" alt="firehose-iam-credentials" className="imagewrapper" />
</p>
</p>
All four values (region, stream name, access key, secret key) are required. Once you click `Connect`, the integration is created
and enabled in one step.
<Note>
Only one event streaming integration can be enabled at a time. If Datadog, Amazon S3, or the Generic HTTP integration is
already enabled, the `Amazon Data Firehose` card is greyed out until you disconnect the active one.
</Note>
### Supported regions
The region dropdown offers a fixed set of AWS regions:
- **US**: `us-east-1`, `us-east-2`, `us-west-1`, `us-west-2`
- **Europe**: `eu-central-1`, `eu-central-2`, `eu-west-1`, `eu-west-2`, `eu-west-3`, `eu-south-1`, `eu-south-2`, `eu-north-1`
- **Asia Pacific**: `ap-east-1`, `ap-south-1`, `ap-south-2`, `ap-northeast-1`, `ap-northeast-2`, `ap-northeast-3`, `ap-southeast-1`, `ap-southeast-2`, `ap-southeast-3`, `ap-southeast-4`
- **Canada**: `ca-central-1`, `ca-west-1`
- **Middle East**: `me-south-1`, `me-central-1`
- **Africa**: `af-south-1`
- **South America**: `sa-east-1`
- **Israel**: `il-central-1`
## Verify the Integration
To confirm the integration works, check the stream's monitoring metrics in the AWS console, or the destination itself, for
incoming records. As with the [Amazon S3 integration](/manage/activity/event-streaming/amazon-s3#verify-the-integration),
NetBird validates the credentials during setup and streams the first events right away, so you do not have to wait for new
network activity.
Delivery is not instant. Firehose applies the buffer interval and buffer size configured on the stream before writing to the
destination, so allow for that delay before concluding that events are missing.
## Change or Remove the Integration
The dashboard does not offer an edit form for a connected integration. To change the stream, the region, or the credentials,
disconnect the integration and run the setup wizard again.
To disconnect, turn the `Amazon Data Firehose` card's toggle off. NetBird asks you to confirm with a
`Disconnect Amazon Data Firehose?` dialog that warns "Disconnecting deletes the current configuration. You will need to start the
setup process again." Click `Disconnect` to delete the configuration, or `Cancel` to keep it. Records already delivered to your
stream's destination are not touched.
If you need to update a configuration in place rather than recreate it, use the
[event streaming API](/api/resources/event-streaming-integrations), which supports updating an existing integration.

View File

@@ -3,7 +3,7 @@
[Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) is a scalable, high-speed, web-based cloud storage service.
You can use Amazon S3 to store and analyze large amounts of data, including network activity events from NetBird.
NetBird integrates with Amazon S3 and sends activity events to an S3 bucket in real-time once they occur. For every event,
NetBird integrates with Amazon S3 and sends audit and traffic events to an S3 bucket in real-time once they occur. For every event,
NetBird creates a new object in the S3 bucket, which you can then analyze, filter, and query using Amazon tools.
Storing one event per object is not the most efficient way to save data in S3, therefore NetBird provides an
@@ -11,7 +11,10 @@ Storing one event per object is not the most efficient way to save data in S3, t
data ingestion.
<Note>
This feature is only available in the cloud version of NetBird.
Event streaming is a paid feature. On NetBird Cloud it is available on the **Business** plan and above, and during a trial.
On a self-hosted deployment it requires the [Enterprise Commercial License](/selfhosted/enterprise); the open source
Community Edition does not serve the event streaming API, so the tab stays locked. Self-hosted dashboards started showing
the Event Streaming tab in dashboard `v2.80.0`.
</Note>
## Prerequisites
@@ -19,6 +22,7 @@ data ingestion.
Before you start creating and configuring an Amazon S3 event streaming integration, ensure that you have the following:
- An AWS account with the permissions to create and manage S3 buckets.
- Permissions to create and manage IAM users, roles and policies.
- A NetBird user with permission to manage integrations, such as an account owner or admin.
If you don't have the required permissions, ask your AWS administrator to grant them to you.
@@ -30,10 +34,16 @@ If you don't have the required permissions, ask your AWS administrator to grant
- (Optional) Change bucket configurations to your needs
- Click `Create bucket`
<Note>
Create the bucket in one of the regions NetBird offers in the setup wizard. See [Supported regions](#supported-regions)
for the full list. AWS GovCloud and the China regions are not available.
</Note>
## Create an IAM User
- Navigate to the [IAM Dashboard](https://console.aws.amazon.com/iam/home)
- Create an IAM User (for details see the [Amazon Docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html))
- Create a custom policy with the following permissions:
- Create a custom policy with the following permissions, scoped to the bucket you created (replace `netbird-activity-events`
with your own bucket name):
```json
{
"Version": "2012-10-17",
@@ -56,26 +66,56 @@ If you don't have the required permissions, ask your AWS administrator to grant
- Give it a description
- Store `Access key` and `Secret access key` in a secure place. You will need these when configuring an integration in NetBird.
<Note>
`s3:PutObject` and `s3:PutObjectAcl` are the only permissions NetBird needs. Do not grant read or delete permissions to
this user.
</Note>
## Create an Integration in NetBird
- Navigate to the [Integrations &raquo; Event Streaming](https://preview.netbird.io/integrations) tab in the NetBird dashboard
- Navigate to the [Integrations &raquo; Event Streaming](https://app.netbird.io/integrations?tab=event-streaming) tab in the NetBird dashboard
<p>
<img src="/docs-static/img/manage/activity/event-streaming/event-streaming-integration.png" alt="event-streaming-integration" className="imagewrapper-big"/>
</p>
- Enable and configure the `Amazon S3` integration
- First select the region your S3 bucket is created in
- On the `Amazon S3` card, click `Connect Amazon S3` or turn the card's toggle on to open the `Connect NetBird with Amazon S3` wizard.
The wizard has three steps, and each step's button stays disabled until you fill in the field on that step.
- Step 1, `Select your Amazon S3 region`: pick the region your bucket lives in and click `Continue`. The dropdown defaults to
`US East (N. Virginia)`, so change it if your bucket is elsewhere.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-s3/s3-region-select.png" alt="s3-region-select" className="imagewrapper" />
</p>
- Then enter the S3 bucket name you created in [Step 1](#step-1-create-an-s3-bucket) and click `Next`
- Step 2, `Create your S3 Bucket`: under `Enter your S3 Bucket name`, enter the bucket you created in
[Create an S3 Bucket](#create-an-s3-bucket) and click `Continue`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-s3/s3-bucket-name.png" alt="s3-bucket-name" className="imagewrapper"/>
</p>
- Enter the `Access key` and `Secret access key` you created in [Step 2](#step-2-create-an-iam-user) and click `Connect`
- Step 3, `Create IAM credential`: enter the access key under `Enter your Access-Key`, the secret under `Enter your Secret-Key`,
both created in [Create an IAM User](#create-an-iam-user), and click `Connect`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/amazon-s3/s3-iam-credentials.png" alt="s3-iam-credentials" className="imagewrapper" />
</p>
All four values (region, bucket name, access key, secret key) are required. Once you click `Connect`, the integration is created
and enabled in one step.
<Note>
Only one event streaming integration can be enabled at a time. If Datadog, Amazon Data Firehose, or the Generic HTTP
integration is already enabled, the `Amazon S3` card is greyed out until you disconnect the active one.
</Note>
### Supported regions
The region dropdown offers a fixed set of AWS regions:
- **US**: `us-east-1`, `us-east-2`, `us-west-1`, `us-west-2`
- **Europe**: `eu-central-1`, `eu-central-2`, `eu-west-1`, `eu-west-2`, `eu-west-3`, `eu-south-1`, `eu-south-2`, `eu-north-1`
- **Asia Pacific**: `ap-east-1`, `ap-south-1`, `ap-south-2`, `ap-northeast-1`, `ap-northeast-2`, `ap-northeast-3`, `ap-southeast-1`, `ap-southeast-2`, `ap-southeast-3`, `ap-southeast-4`
- **Canada**: `ca-central-1`, `ca-west-1`
- **Middle East**: `me-south-1`, `me-central-1`
- **Africa**: `af-south-1`
- **South America**: `sa-east-1`
- **Israel**: `il-central-1`
## Verify the Integration
After configuring the integration in NetBird, you can verify that the integration is working correctly by checking
@@ -116,4 +156,16 @@ containing the following events:
The integration test event is sent to validate whether the provided credentials are correct and NetBird can stream events.
The integration created event is sent when the integration is successfully created.
The integration is now set up and ready to stream network activity events to Amazon S3.
The integration is now set up and ready to stream network activity events to Amazon S3.
## Change or Remove the Integration
The dashboard does not offer an edit form for a connected integration. To change the bucket, the region, or the credentials,
disconnect the integration and run the setup wizard again.
To disconnect, turn the `Amazon S3` card's toggle off. NetBird asks you to confirm with a `Disconnect S3?` dialog that warns
"Disconnecting deletes the current configuration. You will need to start the setup process again." Click `Disconnect` to
delete the configuration, or `Cancel` to keep it. Existing objects already written to your bucket are not touched.
If you need to update a configuration in place rather than recreate it, use the
[event streaming API](/api/resources/event-streaming-integrations), which supports updating an existing integration.

View File

@@ -1,51 +1,97 @@
# Stream Network Activity to Datadog Cloud SIEM
export const description = 'Stream NetBird audit and traffic events to Datadog using the Datadog Log Collection HTTP API, including the supported Datadog sites and the connect, verify, and disconnect flow.'
Datadog is a monitoring and analytics platform for cloud-scale applications. Datadog Cloud SIEM provides real-time threat
detection and security monitoring for cloud environments. By using the NetBird-Datadog integration, you can stream [network activity](/manage/activity/traffic-events-logging) to Datadog Cloud SIEM for real-time monitoring
and threat detection across your private network.
# Stream Activity Events to Datadog
Datadog is a monitoring and analytics platform for cloud-scale applications, and Datadog Cloud SIEM adds real-time threat
detection and security monitoring on top of the logs you send it. With the NetBird Datadog integration you can stream your
NetBird [audit events](/manage/activity) and [traffic events](/manage/activity/traffic-events-logging) to Datadog for
real-time monitoring and threat detection across your private network.
NetBird integrates with Datadog using the [Datadog Log Collection HTTP API](https://docs.datadoghq.com/api/latest/logs/#send-logs)
and sends activity events to Datadog in real-time once they occur. The events appear in the [Datadog Log Explorer](https://docs.datadoghq.com/logs/explorer/), where you can
search, filter, and analyze them right away.
and sends activity events to Datadog in real-time once they occur. The events appear in the
[Datadog Log Explorer](https://docs.datadoghq.com/logs/explorer/) under the `netbird` service, where you can search, filter,
and analyze them right away.
<Note>
This feature is only available in the cloud version of NetBird.
Event Streaming is available in NetBird Cloud under the [Business plan](https://netbird.io/pricing) and in licensed
self-hosted deployments. The open-source management server does not serve the event streaming API, so the cards on the
`Event Streaming` tab stay locked there.
</Note>
## Prerequisites
Before you start creating and configuring a Datadog event streaming integration, ensure that you have the following:
- A Datadog account with permissions to create and manage API keys. If you don't have the required permissions,
ask your Datadog administrator to grant them to you.
- A NetBird role that is allowed to manage event streaming integrations. Without it, the `Datadog` card is read-only.
- No other event streaming integration enabled on the account. Only one integration can be active at a time, and while
another one is enabled the `Datadog` card is greyed out.
## Create a Datdog API Key
- Navigate to the [API Keys](https://app.datadoghq.eu/organization-settings/api-keys) page
## Supported Datadog Regions
The setup wizard asks for your Datadog region and derives the log intake endpoint from it. NetBird supports the following
Datadog sites:
| Region in NetBird | Datadog site | Log intake endpoint |
| --- | --- | --- |
| `Europe (EU)` | `app.datadoghq.eu` | `https://http-intake.logs.datadoghq.eu/api/v2/logs` |
| `United States (US1)` | `app.datadoghq.com` | `https://http-intake.logs.datadoghq.com/api/v2/logs` |
| `United States (US3)` | `us3.datadoghq.com` | `https://http-intake.logs.us3.datadoghq.com/api/v2/logs` |
| `United States (US5)` | `us5.datadoghq.com` | `https://http-intake.logs.us5.datadoghq.com/api/v2/logs` |
| `United States (US1-FED)` | `app.ddog-gov.com` | `https://http-intake.logs.ddog-gov.com/api/v2/logs` |
| `Japan (AP1)` | `ap1.datadoghq.com` | `https://http-intake.logs.ap1.datadoghq.com/api/v2/logs` |
`Europe (EU)` is preselected in the dropdown. If you are not sure which site your account uses, check the
[Datadog site documentation](https://docs.datadoghq.com/getting_started/site/).
<Note>
Datadog sites that are not listed above, such as `AP2`, cannot be selected on the `Datadog` card. To reach one of those,
use the [Generic HTTP](/manage/activity/event-streaming/generic-http) integration and point it at that site's log
intake endpoint.
</Note>
## Create a Datadog API Key
- Navigate to the API Keys page for your Datadog site, for example
[app.datadoghq.eu/organization-settings/api-keys](https://app.datadoghq.eu/organization-settings/api-keys) on
`Europe (EU)`. The NetBird setup wizard also has an `API Keys` button that opens this page for the region you selected.
- Click `+ New Key` at the top
- Give it a descriptive name like `NetBird Event Streaming`
- Give it a descriptive name like `NetBird Activity Events`
- Click `Create Key`
- Copy the key. You will need this key when configuring an integration in NetBird.
- Copy the key. You will need it when configuring the integration in NetBird.
<Note>
A newly created Datadog API key can take up to 5 minutes to become usable. If the connection fails immediately after
you create the key, wait a few minutes and try again.
</Note>
## Create an Integration in NetBird
- Navigate to the [Integrations &raquo; Event Streaming](https://preview.netbird.io/integrations) tab in the NetBird Dashboard
- Navigate to the `Integrations` &raquo; `Event Streaming` tab in the [NetBird Dashboard](https://app.netbird.io/integrations?tab=event-streaming)
<p>
<img src="/docs-static/img/manage/activity/event-streaming/event-streaming-integration.png" alt="event-streaming-integration" className="imagewrapper-big"/>
</p>
- Enable and configure the Datadog integration
- First select the region of your Datadog account (for more details see [Datadog Documentation](https://docs.datadoghq.com/getting_started/site/))
- On the `Datadog` card, click `Connect Datadog` or switch the card's toggle on. Either one opens the
`Connect NetBird with Datadog` wizard.
- Under `Select your Datadog region`, choose your site from the dropdown and click `Continue`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/datadog/datadog-region-select.png" alt="datadog-region-select" className="imagewrapper" />
</p>
- Then enter the API key you created in [Step 1](#step-1-create-a-datdog-api-key) and click `Connect`
- Under `Get your Datadog API Key`, paste the API key you created above into the input field and click `Connect`
<p>
<img src="/docs-static/img/manage/activity/event-streaming/datadog/datadog-api-key.png" alt="datadog-api-key" className="imagewrapper" />
</p>
The API key is the only value you type in. `Connect` stays disabled until the field is filled, and NetBird does not check
the key format, so a mistyped key shows up as a failed connection rather than a validation error.
## Verify the Integration
After configuring the Datadog integration in NetBird, you can verify that the integration is working correctly by checking
the Datadog Log Explorer for incoming events. If the integration is successful, you should see two events from the netbird service
in the Log Explorer:
the Datadog Log Explorer for incoming events. If the integration is successful, you should see two events from the `netbird`
service in the Log Explorer:
- `integration test`
- `integration created`
@@ -54,6 +100,29 @@ in the Log Explorer:
</p>
The `integration test` event is sent to validate whether the provided credentials are correct and NetBird can stream events.
The `integration created` event is sent when the integration is successfully created.
The `integration created` event is an audit event, so it reaches Datadog through the integration you just created.
The integration is now set up and ready to stream network activity events to Datadog.
The integration is now set up and ready to stream audit and traffic events to Datadog.
<Note>
Traffic events logging is disabled by default. If only audit events arrive in Datadog, turn on
[traffic events logging](/manage/activity/traffic-events-logging) in your NetBird account settings.
</Note>
## Change or Remove the Integration
The `Datadog` card has no edit dialog. To change the region or rotate the API key, disconnect the integration and set it up
again with the new values.
Switching the card's toggle off asks you to confirm with `Disconnect Datadog?` and the warning
`Disconnecting deletes the current configuration. You will need to start the setup process again.` Click `Disconnect` to
remove the integration or `Cancel` to keep it.
<Warning>
Disconnecting deletes the stored configuration, including the API key. NetBird masks stored credentials as `****` when
the configuration is read back, so keep your own copy of the Datadog API key if you plan to reuse it.
</Warning>
You can also manage the integration programmatically. See the
[Event Streaming Integrations API reference](/api/resources/event-streaming-integrations). The Datadog configuration uses
the `api_key` and `api_url` keys, where `api_url` is the log intake endpoint from the table above.

View File

@@ -1,102 +1,178 @@
# Stream Network Activity to a Generic HTTP Endpoint
The Generic HTTP integration allows you to stream your NetBird network activity events to any custom HTTP/S endpoint. This provides a flexible way to connect NetBird with a wide range of third-party systems, including custom SIEMs, log management tools like Grafana Loki, or any service that can receive POST requests.
The Generic HTTP integration streams your NetBird audit and traffic events to any HTTP or HTTPS endpoint you control. It is the most flexible of the event streaming options, and it is the foundation the [SentinelOne Data Lake](/manage/activity/event-streaming/sentinelone-data-lake) and [Wazuh](/manage/activity/event-streaming/wazuh) guides build on. Use it for custom SIEMs, log management tools like Grafana Loki, or any service that accepts POST requests.
For every event, NetBird will send a POST request to your configured endpoint. You have full control over the request's body format and headers, allowing for seamless integration with various APIs.
For every event, NetBird sends a POST request to the endpoint you configure. You control the request headers and, optionally, the shape of the body.
<Note>
This feature is only available in the cloud version of NetBird.
Event streaming is available in NetBird Cloud under the [Business plan](https://www.netbird.io/pricing?utm_source=docs&utm_content=event-streaming) and in licensed self-hosted Enterprise deployments. The open-source management server does not serve the event streaming API, so the integration cards stay locked there.
</Note>
## Prerequisites
Before you start, ensure you have an HTTP/S endpoint that is publicly accessible and ready to receive POST requests from NetBird. You will also need any necessary authentication details, such as an API key or credentials for Basic Authentication.
- An HTTP or HTTPS endpoint that accepts POST requests and is reachable from NetBird. On NetBird Cloud that means it has to be publicly reachable. The dashboard's URL field accepts `localhost` and private IPv4 addresses, but NetBird Cloud cannot deliver to them.
- Any credentials your endpoint requires, such as an API key, a bearer token, or a username and password.
- An account role that grants the `event_streaming` permission. Without it, the Generic HTTP card is read-only.
<Note>
Only one event streaming integration can be enabled at a time. If Datadog, Amazon S3, or Amazon Data Firehose is already enabled, the Generic HTTP card is dimmed and cannot be turned on until you disable the other one.
</Note>
## Create an Integration in NetBird
1. Navigate to the **Integrations** tab in the NetBird dashboard and select **Event Streaming**.
2. Find the **Generic HTTP** option and click **Connect**.
3. A configuration panel will open with several tabs: **General**, **Headers**, **Body Template**, and **Danger Zone**.
1. Open the **Integrations** page in the NetBird dashboard and select the **Event Streaming** tab.
2. Find the **Generic HTTP** card and click **Connect Generic HTTP**.
3. The setup modal opens on the **General** tab. A new integration walks through **General**, **Headers**, and **Body Template**, with a **Continue** button between each step. The **Danger Zone** tab only appears once the integration exists.
### General Configuration
This tab is for the essential endpoint details.
This tab holds the endpoint address and the authentication method.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/generic-http/general-config.png" alt="Generic HTTP General Configuration" className="imagewrapper-big"/>
</p>
- **Endpoint URL**: Enter the full HTTPS or HTTP URL where NetBird should send the events. This field is mandatory.
- **Authentication**: Select the authentication method required by your endpoint.
- **No Authentication**: Sends requests without an `Authorization` header.
- **Bearer Token**: Adds an `Authorization: Bearer <your-token>` header to each request. You will need to provide your API key or token.
- **Basic Auth**: Adds an `Authorization: Basic <credentials>` header. You must provide the credentials in the format `username:password`.
- **Custom Authentication**: Allows you to specify a custom HTTP header for authentication. You will need to provide both the header name (e.g., `X-API-Key`) and its value.
- **Enter your Endpoint URL**: the full HTTP or HTTPS URL that receives the POST requests. This field is required. The label reads `Endpoint URL` when you reopen an existing integration. Invalid input shows `Please enter a valid url, e.g., https://api.example.com/webhook`. The validator accepts hostnames, IPv4 addresses, and `localhost`, with or without a scheme, but it rejects bracketed IPv6 literals. Always enter a complete `https://` URL.
- **Authentication**: pick the method your endpoint requires. The dropdown offers exactly four options, in this order:
- `No Authentication`: no `Authorization` header is added.
- `Basic Auth`: two separate fields, `Username` and `Password`. NetBird base64-encodes them and sends `Authorization: Basic <credentials>`. Do not enter them as a single `username:password` string.
- `Bearer Token`: one field for the token. NetBird sends `Authorization: Bearer <your-token>`.
- `Custom Authentication`: under `HTTP Header Name & Value`, provide a header name (for example `X-API-Key`) and its value. NetBird sends that header verbatim.
<Note>
After saving the integration, the configured authentication details will be converted into an HTTP header and will appear in the **Headers** tab.
Authentication is stored as an HTTP header, and how it reappears when you reopen the integration depends on the method. `Basic Auth` and `Bearer Token` are restored into the **Authentication** selector, and Basic Auth shows `****` in both fields. Leave those masked fields untouched to keep the stored credentials, or retype both to change them. `Custom Authentication` has no dedicated storage, so it comes back as an ordinary row on the **Headers** tab and the selector resets to `No Authentication`. That is expected, and the header is still being sent.
</Note>
### HTTP Headers (Optional)
You can add custom HTTP headers to every outgoing request in the **Headers** tab. This is useful for passing static tokens, setting a custom `Content-Type`, or other API requirements. By default, the `Content-Type` is `application/json`.
The **Headers** tab adds custom headers to every outgoing request. Click **Add Header**, then fill in the `Name` and `Value` fields. Each row needs both: filling in only one blocks you from continuing.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/generic-http/headers-config.png" alt="Generic HTTP Headers Configuration" className="imagewrapper-big"/>
</p>
The default request body is JSON. If your endpoint expects something else, for example because you built a plain-text body template, set `Content-Type` here.
<Warning>
Do not add an `Authorization` header here while `Basic Auth` or `Bearer Token` is selected on the **General** tab. The dashboard shows a warning that the header will override the authentication from the previous step and blocks saving until you remove it. Use one or the other, not both.
</Warning>
### Custom Body Template (Optional)
The **Body Template** tab gives you powerful control over the structure of the JSON payload sent to your endpoint.
The **Body Template** tab controls the structure of the payload NetBird posts.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/generic-http/body-template-config.png" alt="Generic HTTP Body Template Configuration" className="imagewrapper-big"/>
</p>
If this option is disabled, NetBird sends a default JSON object for each event. When enabled, you can define your own payload structure using Go's `text/template` templating engine.
Leave `Custom Body Template (optional)` off and NetBird sends its default JSON object for each event, described in [What NetBird sends](#what-netbird-sends). Turn it on and a text area appears, prefilled with this starting point:
This is especially useful for integrating with services that expect a specific format, like Grafana Loki.
```json
{
"id": "{{.ID}}",
"timestamp": "{{.Timestamp.Format "2006-01-02T15:04:05.999Z07:00"}}",
"message": "{{.Message}}",
"initiator_id": "{{.InitiatorID}}",
"target_id": "{{.TargetID}}",
"meta": "{{.Meta}}"
}
```
Templates use Go template syntax. This is useful for services that expect a specific envelope, such as Grafana Loki or a Splunk-style HTTP Event Collector.
#### Available Template Variables
You can use the following variables from the `StreamEvent` object in your template:
The variables below are the Go field names of the event object. Note that they are not identical to the JSON keys of the default payload.
| Variable | Type | Description | Example Usage |
|---------------|----------------------|--------------------------------------------------------------------------------------|-----------------------------------|
| `.ID` | `any` | The unique ID of the event. | `{"event_id": "{{.ID}}"}` |
| `.Timestamp` | `time.Time` | The timestamp of when the event occurred. Can be formatted. | `{{.Timestamp.UnixNano}}` / `{{.Timestamp.Format "2006-01-02T15:04:05.999Z07:00"}}` |
| `.Message` | `string` | A human-readable message describing the event. | `{"text": "{{.Message}}"}` |
| `.InitiatorID`| `string` | The ID of the object that initiated the event (e.g., a user or peer ID). | `{"user": "{{.InitiatorID}}"}` |
| `.TargetID` | `string` | The ID of the object that was affected by the event (e.g., a peer or group ID). | `{"resource": "{{.TargetID}}"}` |
| `.Meta` | `map[string]any` | A map containing additional metadata about the event. | `{"source": "{{.Meta.source}}"}` |
| `.Reference` | `string` | A URL to the event in the NetBird activity log for easy cross-referencing. | `{"ref": "{{.Reference}}"}` |
| Variable | Type | Description | Example Usage |
|---------------|----------------------|---------------------------------------------------------------------------------|-----------------------------------|
| `.ID` | `any` | Unique ID of the event. A number for audit events, a string for some others. | `{"event_id": "{{.ID}}"}` |
| `.Timestamp` | `time.Time` | When the event occurred. Can be formatted. | `{{.Timestamp.UnixNano}}` / `{{.Timestamp.Format "2006-01-02T15:04:05.999Z07:00"}}` |
| `.Message` | `string` | Human-readable description of the event, for example `peer added`. | `{"text": "{{.Message}}"}` |
| `.InitiatorID`| `string` | ID of the object that initiated the event, such as a user or peer ID. | `{"user": "{{.InitiatorID}}"}` |
| `.TargetID` | `string` | ID of the object the event acted on, such as a peer or group ID. | `{"resource": "{{.TargetID}}"}` |
| `.Meta` | `map[string]any` | Additional metadata. The keys depend on the event type. | `{"source": "{{.Meta.source}}"}` |
| `.Reference` | `string` | URL of the event in the NetBird activity log, for cross-referencing. | `{"ref": "{{.Reference}}"}` |
### Danger Zone
<Warning>
Two limitations are worth knowing before you commit to a custom template. String values are HTML-escaped on render, so a `+` in a timestamp or URL comes out as `&#43;`. And `{{.Meta}}` renders Go's map formatting, such as `map[platform:generic_http]`, rather than JSON, which is why the default template wraps it in quotes as a string. If your receiver needs clean JSON, leave the custom template off and parse the default payload.
</Warning>
This tab allows you to delete the integration. This action is irreversible and will immediately stop events from being sent to your endpoint.
## What NetBird sends
Audit events and [traffic events](/manage/activity/traffic-events-logging) both flow through the same integration, but they do not have the same shape. Traffic events only appear if Traffic Events Logging is enabled for at least one group.
An audit event looks like this:
```json
{
"ID": 22456950,
"Timestamp": "2026-05-08T12:57:57.00483949Z",
"Message": "integration created",
"InitiatorID": "oauth2|<idp>|<user-uuid>",
"target_id": "event_streaming:1172",
"meta": { "platform": "generic_http" },
"reference": "https://app.netbird.io/activity?id=22456950"
}
```
A traffic event uses the same keys, but leaves the identity fields empty and carries the detail in `meta`:
```json
{
"ID": "<flow uuid>",
"Timestamp": "2026-05-08T10:33:41.723079Z",
"Message": "TYPE_START",
"InitiatorID": "",
"target_id": "",
"reference": "",
"meta": {
"flow_id": "<uuid>",
"direction": "EGRESS",
"source_addr": "100.121.42.206:0",
"source_name": "example-laptop.local",
"source_type": "PEER",
"destination_addr": "100.121.255.254:0",
"destination_name": "",
"destination_type": "PEER",
"protocol": 6,
"tx_bytes": 56, "tx_packets": 1,
"rx_bytes": 0, "rx_packets": 0,
"policy_name": "",
"reporter_id": "<peer-id-of-reporter>",
"user_id": "oauth2|<idp>|<user-uuid>"
}
}
```
<Warning>
Key casing is mixed on the wire. `ID`, `Timestamp`, `Message`, and `InitiatorID` are PascalCase, while `target_id`, `meta`, and `reference` are snake_case. Match the exact form above when you write parsers, index mappings, or detection rules.
</Warning>
A few things to plan for:
- `Message` is the most stable field to key rules on. Audit events carry a plain English phrase such as `peer added` or `policy created`. Traffic events carry a flow lifecycle type such as `TYPE_START`, `TYPE_END`, or `TYPE_DROP`.
- `meta` is event-type specific. Peer events carry `meta.name`, setup-key events carry `meta.type`, integration events carry `meta.platform`. Treat unknown keys as opaque.
- `protocol` in traffic events is an IANA protocol number: `1` for ICMP, `6` for TCP, `17` for UDP, `58` for ICMPv6.
- One flow can emit both a `TYPE_START` and a `TYPE_END` event sharing `meta.flow_id`. Filter on one of them to avoid double-counting.
- Traffic event volume is an order of magnitude higher than audit event volume on a busy network. Size your ingestion, retention, and rate limits accordingly.
## Save and Verify
On a new integration, click **Connect** on the **Body Template** step. When you reopen an existing integration the footer shows **Cancel** and **Save Changes** on every tab instead.
When you save, NetBird POSTs a test event to your endpoint. If the endpoint does not answer with a `2xx` status, the save is rejected and the integration is not created, so a failing save usually means a wrong URL, a firewall in the way, or bad credentials.
Check the logs of your receiving service for the incoming POST. A successful save also writes an `integration created` audit event, and because the integration is now live, that event streams straight back to your endpoint. Later edits produce `integration updated` the same way. Seeing that event arrive is the quickest confirmation that the pipeline works end to end.
## Manage the Integration
Once the integration exists, the Generic HTTP card changes: the **Connect Generic HTTP** button is replaced by a **Configuration** button, and the toggle on the card becomes active.
- **Enable or disable**: flip the toggle on the card. Disabling stops the stream but keeps the configuration, so you can turn it back on without re-entering anything.
- **Edit**: click **Configuration** to reopen the modal, change any tab, and click **Save Changes**.
- **Delete**: open **Configuration**, go to the **Danger Zone** tab, and click **Delete Integration**. A confirmation dialog appears, and the deletion is irreversible. You will have to set the integration up again from scratch.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/generic-http/danger-zone.png" alt="Generic HTTP Danger Zone" className="imagewrapper-big"/>
</p>
After configuring all settings, click **Save Changes**.
## Verify the Integration
Once you save the integration, NetBird sends a test event to your endpoint to confirm that the connection and authentication are successful.
Check the logs of your receiving service for a new POST request. You should find a JSON payload similar to this (if custom template wasn't set up):
```json
{
"ID": "test-event-1685635200",
"Timestamp": "2025-06-01T16:00:00Z",
"Message": "integration test event for generic http endpoint",
"InitiatorID": "netbird-test-system",
"TargetID": "target-id",
"Meta": {
"purpose": "configuration-test",
"source": "netbird-test"
},
"Reference": "netbird:test:generichttp"
}

View File

@@ -1,26 +1,107 @@
# Stream Network Activity to Third-Party SIEM Platforms
# Stream Audit and Traffic Events to Third-Party Services
<p>
<img src="/docs-static/img/manage/activity/event-streaming/event-streaming-integration.png" alt="event-streaming-integration" className="imagewrapper-big"/>
</p>
Event Streaming forwards your NetBird activity to an external destination as the events occur. Destinations include SIEM
platforms such as [Datadog](https://www.datadoghq.com/dg/security/siem-solution/), object storage such as
[Amazon S3](https://aws.amazon.com/s3/), streaming pipelines such as
[Amazon Data Firehose](https://aws.amazon.com/firehose/), and any other service you can reach over HTTP through the
Generic HTTP integration.
Security Information and Event Management (SIEM) systems play a critical role in network security by monitoring,
detecting, and responding to security threats in real-time. By aggregating and analyzing activity across the network,
SIEMs help identify anomalous patterns and potential breaches, providing a centralized view of security events.
NetBird provides an event streaming feature that allows you to stream network [activity events](/manage/activity/traffic-events-logging)
to third-party SIEM systems, such as [Datadog](https://www.datadoghq.com/dg/security/siem-solution/), [Amazon S3](https://aws.amazon.com/s3/), [Amazon Data Firehose](https://aws.amazon.com/firehose/), and others through a generic HTTP integration.
SIEMs help identify anomalous patterns and potential breaches, providing a centralized view of security events. Streaming
NetBird events into one of them puts your network activity alongside the rest of your security telemetry.
<Note>
This feature is only available in the cloud version of NetBird.
Event Streaming is available in NetBird Cloud under the [Business plan](https://www.netbird.io/pricing?utm_source=docs&utm_content=event-streaming)
and in licensed self-hosted deployments. It is not served by the open-source management server.
</Note>
This documentation provides step-by-step guides and best practices for integrating NetBird activity event streaming with
supported third-party platforms. To get started, select one of the following integrations:
## What Gets Streamed
- [Datadog](/manage/activity/event-streaming/datadog)
- [Amazon S3](/manage/activity/event-streaming/amazon-s3)
- [Amazon Data Firehose](/manage/activity/event-streaming/amazon-firehose)
- [SentinelOne Data Lake](/manage/activity/event-streaming/sentinelone-data-lake)
- [Generic HTTP](/manage/activity/event-streaming/generic-http)
- [Wazuh](/manage/activity/event-streaming/wazuh)
A single integration carries both classes of NetBird activity. The dashboard describes the feature as
`Event Streaming allows you to stream NetBirds audit & traffic events to different third-party services.`
- **[Audit events](/manage/activity)** record changes to your network, such as a peer joining, a policy being modified,
or a setup key being revoked. Audit events are enabled by default for every NetBird account, so they start streaming as
soon as you connect an integration.
- **[Traffic events](/manage/activity/traffic-events-logging)** record connection flows between peers and resources.
Traffic events logging is **disabled by default**. Turn it on under `Settings` > `Networks` in the Experimental section
before you expect traffic events to reach your destination. If you have scoped traffic events to specific groups, only
peers in those groups report flows.
Both event types travel through whichever integration is enabled, in the same stream. There is no per-integration filter
that separates them.
## Where to Find It
Open the NetBird dashboard and navigate to `Integrations` > `Event Streaming`. Configuring an integration requires an
account role with event streaming permissions, so if the tab is missing or the cards are read-only, ask an administrator
of your account.
## Available Integrations
NetBird ships four integrations as cards on the `Event Streaming` tab:
| Integration | Card description in the dashboard | Guide |
| --- | --- | --- |
| `Datadog` | Datadog is a monitoring service for cloud-scale applications. | [Datadog](/manage/activity/event-streaming/datadog) |
| `Amazon S3` | Amazon S3 is a scalable storage in the cloud. | [Amazon S3](/manage/activity/event-streaming/amazon-s3) |
| `Amazon Data Firehose` | Firehose delivers real-time data streaming to destinations such as Amazon S3, Amazon Redshift & more. | [Amazon Data Firehose](/manage/activity/event-streaming/amazon-firehose) |
| `Generic HTTP` | Provide your custom HTTP endpoint to stream audit & traffic events. | [Generic HTTP](/manage/activity/event-streaming/generic-http) |
### Recipes Built on Generic HTTP
There is no dedicated card for every platform. `Generic HTTP` posts each event to any HTTPS endpoint you choose, with
your own authentication headers and an optional body template, which makes it the building block for destinations NetBird
does not integrate with natively. The following guides are configurations of the `Generic HTTP` card rather than separate
integrations, so read the [Generic HTTP](/manage/activity/event-streaming/generic-http) page first:
- [SentinelOne Data Lake](/manage/activity/event-streaming/sentinelone-data-lake) uses the SentinelOne HTTP Event
Collector endpoint with a custom body template.
- [Wazuh](/manage/activity/event-streaming/wazuh) posts to a webhook receiver in front of a Wazuh manager using a custom
authentication header.
## One Integration at a Time
Only one event streaming integration can be enabled per account. While an integration is enabled, the remaining cards on
the `Event Streaming` tab are greyed out and cannot be connected. To switch destinations, disconnect the active
integration first, then connect the new one.
Turning off `Datadog`, `Amazon S3`, or `Amazon Data Firehose` deletes the integration rather than pausing it. The
dashboard asks you to confirm with `Disconnecting deletes the current configuration. You will need to start the setup
process again.`, and you have to re-enter the credentials to connect that destination again.
`Generic HTTP` behaves differently. Its toggle only enables or disables the integration and keeps the saved endpoint,
headers, and body template, so you can switch it back on without reconfiguring. Deleting it is a separate action in the
`Danger Zone` tab of its configuration panel.
## Connection Test
When you connect an integration, NetBird sends a synthetic `integration test` event to validate that the credentials and
endpoint work, followed by an `integration created` audit event once the integration is saved. Looking for those two
events at the destination is the quickest way to confirm the setup, and each guide shows where they appear.
Because `integration created` is itself an audit event, it streams out through the integration you just created. Later
configuration changes produce `integration updated` the same way.
## Credential Handling
Credentials you enter, such as API keys and secret access keys, are stored with the integration and masked as `****` when
the configuration is read back through the API.
<Warning>
NetBird does not display saved credentials again. Keep API keys and secret access keys in your own secret manager so
you can reconnect an integration after disconnecting it.
</Warning>
## Manage Integrations Through the API
Event streaming integrations can also be created, listed, updated, and deleted programmatically. See the
[Event Streaming Integrations API reference](/api/resources/event-streaming-integrations) for the available endpoints.
The API accepts the same four platform values as the dashboard: `datadog`, `s3`, `firehose`, and `generic_http`. The
`config` object is a free-form set of key-value pairs whose keys depend on the platform, so use the setup steps in each
guide to work out which values you need.

View File

@@ -1,18 +1,26 @@
# Stream Network Activity to SentinelOne Singularity Data Lake
# Stream Network Activity to SentinelOne Singularity Data Lake Using Generic HTTP
[SentinelOne Singularity Data Lake](https://www.sentinelone.com/platform/data-lake/) provides a centralized repository for storing and analyzing security data across your organization. By streaming NetBird network activity events to SentinelOne Data Lake, you can correlate network connectivity events with endpoint security data for comprehensive threat detection and investigation.
[SentinelOne Singularity Data Lake](https://www.sentinelone.com/platform/data-lake/) provides a centralized repository for storing and analyzing security data across your organization. By streaming NetBird network activity events to SentinelOne Data Lake, you can correlate network connectivity events with endpoint security data for comprehensive threat detection and investigation.
This integration leverages NetBird's Generic HTTP streaming capability with SentinelOne Singularity Data Lake-specific configurations to ensure seamless data ingestion into your Data Lake environment.
NetBird does not ship a SentinelOne card on the `Event Streaming` tab. The tab lists four integrations: `Datadog`, `Amazon S3`, `Amazon Data Firehose`, and `Generic HTTP`. This page is a recipe for the `Generic HTTP` card, pointed at a SentinelOne HTTP Event Collector (HEC) endpoint with a custom body template. Read [Generic HTTP](/manage/activity/event-streaming/generic-http) first, since it is the reference for every NetBird-side field used below.
<Note>
This feature is only available in the cloud version of NetBird.
Event Streaming is available in NetBird Cloud under the [Business plan](https://www.netbird.io/pricing?utm_source=docs&utm_content=event-streaming)
and in licensed self-hosted deployments. It is not served by the open-source management server.
</Note>
## Prerequisites
Before you start creating and configuring a SentinelOne Singularity Data Lake event streaming integration, ensure that you have the following:
Before you start configuring the `Generic HTTP` integration for SentinelOne Singularity Data Lake, ensure that you have the following:
- A SentinelOne account with Singularity Data Lake access and appropriate permissions
- Administrative access to create API keys in your SentinelOne console
- A NetBird user whose role grants event streaming permissions
- No other event streaming integration enabled. Only one integration can be active per account, and the remaining cards on the `Event Streaming` tab are greyed out while one is connected.
<Note>
The SentinelOne console steps on this page are maintained by SentinelOne, not by NetBird. Confirm the menu names and endpoint paths against the SentinelOne documentation for your tenant before you follow them.
</Note>
## Create a SentinelOne API Token
@@ -31,18 +39,20 @@ Before you start creating and configuring a SentinelOne Singularity Data Lake ev
Navigate to `https://<your-tenant>.sentinelone.net/docs/en/http-event-collector--hec-.html#http-event-collector--hec-` (replace `<your-tenant>` with your actual SentinelOne tenant)
to find and copy the HTTP Event Collector base URL from the documentation page. The URL format will be `https://ingest.<region>.sentinelone.net` where `<region>` is your deployment region.
## Create an Integration in NetBird
## Configure the Generic HTTP Integration in NetBird
- Navigate to the **Integrations** tab in the NetBird dashboard and select **Event Streaming**
- Find the **Generic HTTP** option and click **Connect Generic HTTP**
- Configure the endpoint URL by entering the full HEC endpoint URL: `https://ingest.<region>.sentinelone.net/services/collector/event`
- Select **Bearer Token** for authentication and provide the API token you created earlier
1. In the NetBird dashboard, open `Integrations` and select the `Event Streaming` tab.
2. Find the `Generic HTTP` card and click `Connect Generic HTTP`. If a Generic HTTP integration already exists, the card shows a `Configuration` button instead, which opens the same dialog in edit mode.
3. On the `General` tab, set `Enter your Endpoint URL` to the full HEC endpoint URL: `https://ingest.<region>.sentinelone.net/services/collector/event`
4. Under `Authentication`, select `Bearer Token` and paste the API token you created earlier. NetBird sends it as an `Authorization: Bearer <token>` request header. When you reopen the integration the token is restored into the `Authentication` selector rather than shown as a row on the `Headers` tab.
5. Click `Continue`.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/sentinelone-data-lake/general-settings.png" alt="General Settings Configuration" className="imagewrapper-big"/>
</p>
- Enable the custom body template and use the following template optimized for SentinelOne Singularity Data Lake:
6. Leave the `Headers` tab empty unless your tenant requires extra headers, then click `Continue`. Do not add your own `Authorization` header here, because it conflicts with the `Bearer Token` method selected on the previous tab and blocks the save.
7. On the `Body Template` tab, turn on `Custom Body Template (optional)` and replace the contents of the text area with the following template, which is shaped for the SentinelOne HTTP Event Collector:
```json
{
@@ -58,20 +68,30 @@ to find and copy the HTTP Event Collector base URL from the documentation page.
}
```
8. Click `Connect`. When you are editing an integration that already exists, the button reads `Save Changes` instead.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/sentinelone-data-lake/custom-template.png" alt="Custom Template Configuration" className="imagewrapper-big"/>
</p>
<Note>
Template variable names are not the same as the JSON keys NetBird puts on the wire. Inside a body template you address the Go field names, so `{{.TargetID}}` and `{{.Meta}}` are correct here even though the default payload serializes the same values as `target_id` and `meta`. See [Available Template Variables](/manage/activity/event-streaming/generic-http#available-template-variables) for the full list.
</Note>
<Warning>
Two rendering limitations affect this recipe. `{{.Meta}}` emits Go's map formatting rather than JSON, so `fields` arrives as an opaque quoted string such as `map[purpose:configuration-test source:netbird-test]` and Data Lake indexes it as one value instead of searchable subfields. String values are also HTML-escaped, so a `+` in a value comes out as `&#43;`. If you need individual metadata values as separate searchable fields, reference them one at a time, for example `{{.Meta.source}}`, instead of emitting the whole map.
</Warning>
## Verify the Integration
After configuring the SentinelOne Singularity Data Lake integration in NetBird, you can verify that the integration is working correctly by checking the SentinelOne Singularity Data Lake for incoming events. If the integration is successful, you should see test events from NetBird in your Data Lake.
Saving the integration makes NetBird post a synthetic test event to the endpoint, and it also writes an `integration created` audit event that streams straight back out through the integration you just connected. Both should land in Data Lake within a minute.
- Navigate to **Data Lake** > **Search** > **New Search** in your SentinelOne console
- Select to search **All Data** and filter for recent events with source **netbird**
- Verify the test events appear with the expected structure
- Look for an `integration test event for generic http endpoint` message followed by an `integration created` message, and confirm that the `id`, `initiator_id`, `target_id`, and `time` fields carry the values your template produced
<p>
<img src="/docs-static/img/manage/activity/event-streaming/sentinelone-data-lake/verify-integration.png" alt="Verify Integration" className="imagewrapper-big"/>
</p>
The integration is now set up and ready to stream network activity events to SentinelOne Singularity Data Lake.
The integration is now set up and ready to stream network activity events to SentinelOne Singularity Data Lake.

View File

@@ -1,39 +1,51 @@
# Stream Activity Events to Wazuh
# Stream Activity Events to Wazuh Using Generic HTTP
Wire NetBird's [Event Streaming → Generic HTTP](/manage/activity/event-streaming/generic-http) integration to a Wazuh manager so every [audit event](/manage/activity) and [traffic event](/manage/activity/traffic-events-logging) lands in Wazuh as a searchable alert.
NetBird does not ship a Wazuh card on the `Event Streaming` tab. The tab lists four integrations: `Datadog`, `Amazon S3`, `Amazon Data Firehose`, and `Generic HTTP`. This page is a recipe for the `Generic HTTP` card, pointed at a webhook receiver that feeds a Wazuh manager, so every [audit event](/manage/activity) and [traffic event](/manage/activity/traffic-events-logging) lands in Wazuh as a searchable alert. Read [Generic HTTP](/manage/activity/event-streaming/generic-http) first, since it is the reference for every NetBird-side field used below.
<Note>
Event Streaming is available in NetBird Cloud under the [Business plan](https://www.netbird.io/pricing?utm_source=docs&utm_content=event-streaming)
and in licensed self-hosted deployments. It is not served by the open-source management server.
</Note>
## Prerequisites
- A running Wazuh stack (4.14+) with a public, TLS-terminated webhook endpoint that NetBird Cloud can POST to. If you don't have one, see the [Wazuh receiver reference architecture](./wazuh-receiver) for a starter deployment built around `wazuh/wazuh-docker` + Caddy.
- The shared secret your receiver expects in the `X-API-Key` HTTP header. If you're deploying the receiver from scratch, you'll generate this as part of its `.env`. If a receiver is already running, use the value of `NB_WEBHOOK_SECRET` from its `.env`.
- The receiver writes each NetBird event as a single JSON line to a file the Wazuh manager tails via a `<localfile>` block with `<log_format>json</log_format>`, and ships with a starter ruleset under custom rule IDs `100100``100106` (audit) and `100200``100202` (traffic). The verification steps below assume that wiring.
- A NetBird user whose role grants event streaming permissions, and no other event streaming integration enabled. Only one integration can be active per account.
- A running Wazuh stack (4.14+). Wazuh has no built-in HTTP listener for this, so you also need a small webhook receiver in front of the manager: a public, TLS-terminated endpoint that NetBird can POST to, which authenticates the request and appends each event as a single JSON line to a file the manager tails through a `<localfile>` block with `<log_format>json</log_format>`.
- A shared secret that the receiver requires in the `X-API-Key` HTTP header.
- A Wazuh ruleset that matches the decoded NetBird fields. The examples on this page assume a starter ruleset using custom rule IDs `100100`-`100106` for audit events and `100200`-`100202` for traffic events, and a receiver that wraps each event in the envelope described under [Payload reference](#payload-reference). Adjust the rule IDs and field paths to match whatever you deploy.
## Step 1 — Configure NetBird's Generic HTTP integration
<Note>
The Wazuh manager, receiver, and ruleset details on this page are outside NetBird's control. Verify them against the Wazuh documentation and your own deployment. NetBird's responsibility ends at the POST request described in Step 1.
</Note>
In **https://app.netbird.io**:
## Step 1 - Configure NetBird's Generic HTTP integration
1. **Integrations → Event Streaming**, find **Generic HTTP**, click **Connect**.
2. Fill the **General** tab:
- **Endpoint URL**: `https://YOUR-HOSTNAME/events`
- **Authentication**: **Custom Authentication**
- **Header name**: `X-API-Key`
- **Header value**: the secret from the prerequisites
3. Leave **Headers** and **Body Template** at their defaults.
4. **Save Changes**.
1. In the NetBird dashboard, open `Integrations` and select the `Event Streaming` tab.
2. Find the `Generic HTTP` card and click `Connect Generic HTTP`. If a Generic HTTP integration already exists, the card shows a `Configuration` button instead, which opens the same dialog in edit mode.
3. On the `General` tab:
- Set `Enter your Endpoint URL` to `https://YOUR-HOSTNAME/events`. The label reads `Endpoint URL` when you reopen an existing integration.
- Under `Authentication`, select `Custom Authentication`.
- Under `HTTP Header Name & Value`, enter `X-API-Key` in the name field and the shared secret from the prerequisites in the value field.
4. Click `Continue`, leave the `Headers` tab as it is, click `Continue` again, and leave `Custom Body Template (optional)` switched off on the `Body Template` tab.
When you later reopen the integration, `X-API-Key` appears as an ordinary row on the `Headers` tab and `Authentication` resets to `No Authentication`. That is expected: unlike `Basic Auth` and `Bearer Token`, `Custom Authentication` has no dedicated storage, and the header is still being sent.
5. Click `Connect`. When you are editing an integration that already exists, the button reads `Save Changes` instead.
<p>
<img src="/docs-static/img/manage/activity/event-streaming/wazuh/netbird-generic-http-config.png" alt="NetBird Generic HTTP integration configuration" className="imagewrapper-big"/>
</p>
The screenshot above shows the dialog reopened on an existing integration, which is why the header reads `Generic HTTP Configuration`, the `Danger Zone` tab is present, and the footer offers `Save Changes`. A first-time setup reads `Connect NetBird with Generic HTTP` and steps through the tabs with `Continue` before ending on `Connect`.
<Note>
Don't use a custom body template. In testing, NetBird's body-template engine HTML-escapes string values (so `+` becomes `&#43;`, mangling ISO-8601 timestamps and URLs with special characters), and there's no JSON-encoding helper for `meta`. The default body is the right choice for Wazuh.
Do not turn on a custom body template for this recipe. NetBird's template engine HTML-escapes string values, so a `+` becomes `&#43;`, which mangles ISO-8601 timestamps and URLs containing special characters, and `{{.Meta}}` renders as a Go map string rather than JSON. The default body is already clean JSON, which is what Wazuh's JSON decoder needs. See the [custom body template limitations](/manage/activity/event-streaming/generic-http#custom-body-template-optional).
</Note>
On save NetBird POSTs a synthetic test event to your endpoint and rejects the save with a `412` if the receiver doesn't return `2xx` (observed in NetBird Cloud, May 2026). A successful save also generates an "integration created" audit event that streams *back* through the same integration; that's NetBird logging its own configuration change. Subsequent edits produce "integration updated" the same way.
When you save, NetBird POSTs a synthetic test event to your endpoint and rejects the save if the receiver does not answer with a `2xx` status (NetBird Cloud returned `412` for this in testing, May 2026). A successful save also generates an `integration created` audit event that streams back through the same integration; that is NetBird logging its own configuration change. Subsequent edits produce `integration updated` the same way.
## Step 2 Verify in the Wazuh dashboard
## Step 2 - Verify in the Wazuh dashboard
Open the Wazuh dashboard, log in, then ☰ → **Explore Discover**.
Open the Wazuh dashboard, log in, then go to Explore > Discover.
### Audit events
@@ -43,15 +55,15 @@ Set the index pattern to `wazuh-alerts-*` and run this KQL:
rule.groups : "netbird" and not data.nb.Message : TYPE_*
```
Set the time picker to **Last 15 minutes** and add these columns from the field selector: `rule.id`, `rule.level`, `rule.description`, `data.nb.InitiatorID`, `data.nb.target_id`.
Set the time picker to Last 15 minutes and add these columns from the field selector: `rule.id`, `rule.level`, `rule.description`, `data.nb.InitiatorID`, `data.nb.target_id`.
You should see one row per audit event (peer add/remove, policy change, group create, etc.) with `rule.description` reading like `NetBird group event: group created`.
You should see one row per audit event (peer add/remove, policy change, group create, and so on) with `rule.description` reading like `NetBird group event: group created`.
If `data.nb.*` doesn't appear in the field selector, the index pattern's field cache is stale. Go to ☰ → **Stack Management Index Patterns** → `wazuh-alerts-*` and click the **↻ Refresh fields** icon at the top right, then return to Discover; all `data.nb.*` fields will appear.
If `data.nb.*` does not appear in the field selector, the index pattern's field cache is stale. Go to Stack Management > Index Patterns > `wazuh-alerts-*` and refresh the fields, then return to Discover.
### Traffic events
If you've also enabled [Traffic Events Logging](/manage/activity/traffic-events-logging) for one or more groups, switch the KQL to:
If you have also enabled [Traffic Events Logging](/manage/activity/traffic-events-logging) for one or more groups, switch the KQL to:
```text
rule.groups : "traffic"
@@ -59,11 +71,13 @@ rule.groups : "traffic"
Useful columns: `rule.id`, `rule.level`, `rule.description`, `data.nb.meta.source_name`, `data.nb.meta.destination_addr`, `data.nb.meta.tx_bytes`.
`TYPE_DROP` events (rule `100202`) escalate to level 7 to make policy denials stand out from normal flow telemetry.
In the starter ruleset referenced in the prerequisites, `TYPE_DROP` events (rule `100202`) escalate to level 7 so that policy denials stand out from normal flow telemetry.
## Schema reference
## Payload reference
NetBird emits **two distinct event shapes** through the same integration. Both arrive wrapped in a small envelope so they don't collide with Wazuh's index template:
NetBird posts two distinct event shapes through the same integration, audit events and traffic events. The canonical description of both, including the mixed key casing and the per-event-type `meta` keys, lives on the [Generic HTTP](/manage/activity/event-streaming/generic-http#what-netbird-sends) page. This section covers only what changes on the way into Wazuh.
The receiver used for the examples on this page wraps each NetBird payload before writing it out, so it does not collide with Wazuh's index template:
```json
{
@@ -73,69 +87,21 @@ NetBird emits **two distinct event shapes** through the same integration. Both a
}
```
`received_at` is the receiver's local timestamp at the moment the POST was accepted. Compare it against `nb.Timestamp` (set by NetBird Cloud) to spot clock skew or buffering delays in the streaming path.
NetBird does not add this wrapper. `received_at` is the receiver's local timestamp at the moment the POST was accepted. Compare it against `nb.Timestamp`, which NetBird sets, to spot clock skew or buffering delays in the streaming path. Because the payload sits under `nb`, Wazuh indexes the NetBird fields as `data.nb.*`.
### Audit events
Things to know when you write KQL or Wazuh rules against those fields:
```json
{
"ID": 22456950,
"Timestamp": "2026-05-08T12:57:57.00483949Z",
"Message": "integration created",
"InitiatorID": "oauth2|azure-oauth2|<user-uuid>",
"target_id": "event_streaming:1172",
"meta": { "platform": "generic_http" },
"reference": "https://app.netbird.io/activity?id=22456950"
}
```
- **Casing is mixed on the wire**: `ID`, `Timestamp`, `Message`, `InitiatorID` are PascalCase; `target_id`, `meta`, `reference` are snake_case. KQL queries against the indexer are case-sensitive, so match the on-the-wire form exactly: `data.nb.Message`, `data.nb.target_id`, etc. The same applies to Wazuh rule `<field name="...">` references.
- **`ID` may be a number or a string** (test events use a string identifier; real audit events use a numeric ID). Wazuh normalises both to strings in the indexed `data.nb.ID`, so KQL queries don't need to handle the mixed type.
- **`Message`** is the most reliable field to pivot rules on; it's a stable English phrase like "peer added" or "policy created".
- **`reference`** is the canonical URL into NetBird's activity log; useful as a click-through pivot from a Wazuh alert back to the source event.
- **`meta` is event-type-specific.** Peer events carry `meta.name`, setup-key events carry `meta.type`, integration events carry `meta.platform`. Treat unknown keys as opaque.
### Traffic events
```json
{
"ID": "<flow uuid>",
"Timestamp": "2026-05-08T10:33:41.723079Z",
"Message": "TYPE_START",
"InitiatorID": "",
"target_id": "",
"reference": "",
"meta": {
"flow_id": "<uuid>",
"direction": "EGRESS",
"source_addr": "100.121.42.206:0",
"source_name": "Jacks-MacBook-Air.local",
"source_type": "PEER",
"destination_addr": "100.121.255.254:0",
"destination_name": "",
"destination_type": "PEER",
"protocol": 6,
"tx_bytes": 56, "tx_packets": 1,
"rx_bytes": 0, "rx_packets": 0,
"policy_name": "",
"reporter_id": "<peer-id-of-reporter>",
"user_id": "oauth2|azure-oauth2|<user-uuid>"
}
}
```
Traffic events keep the same envelope as audit events: `ID` and `Timestamp` are populated; `InitiatorID`, `target_id`, and `reference` are intentionally empty (the actor lives in `meta.user_id`, source/destination identity in `meta.source_*` / `meta.destination_*`).
- `destination_name` is usually empty; `destination_addr` (overlay IP) is always set.
- `protocol` is an IANA number (`1`=ICMP, `6`=TCP, `17`=UDP, `58`=ICMPv6).
- A single flow can produce both a `TYPE_START` and a `TYPE_END` event sharing `meta.flow_id`. Filter on `data.nb.Message : "TYPE_START"` to count distinct flow starts and avoid double-counting lifecycle pairs.
- Volume is an order of magnitude higher than audit events on a busy mesh; size your retention and rate limits accordingly.
- **Match the on-the-wire casing exactly.** In captured production payloads NetBird mixes PascalCase and snake_case in the same object: `ID`, `Timestamp`, `Message`, and `InitiatorID` are PascalCase, while `target_id`, `meta`, and `reference` are snake_case. KQL is case-sensitive, so query `data.nb.Message` and `data.nb.target_id`, not `data.nb.message`. The same applies to Wazuh rule `<field name="...">` references. Confirm the exact keys against your own receiver logs before you commit a decoder to production.
- **Do not copy Go template names into your rules.** `.TargetID`, `.Meta`, and `.Reference` are template variables for a [custom body template](/manage/activity/event-streaming/generic-http#custom-body-template-optional), not wire keys. This recipe leaves the template off, so the snake_case forms above are what Wazuh indexes.
- **`ID` may be a number or a string.** Test events use a string identifier and real audit events use a numeric ID. Wazuh normalises both to strings in the indexed `data.nb.ID`, so KQL queries do not need to handle the mixed type.
- **`Message` is the most reliable field to pivot rules on.** It is a stable English phrase such as `peer added` or `policy created` for audit events, and a flow lifecycle type such as `TYPE_START` for traffic events.
- **`reference` is the canonical URL into NetBird's activity log**, which makes a useful click-through pivot from a Wazuh alert back to the source event. It is empty on traffic events.
<Note>
Wazuh's JSON decoder strips empty-string and empty-object fields when it extracts events into `data.nb.*`. Fields shown as `""` or `{}` in the schema examples above (such as `destination_name`, `policy_name`, an empty `meta` on some audit events) won't appear in indexed alerts, so KQL queries like `data.nb.meta.destination_name : *` return zero hits. The original wire payload is preserved in `full_log` if you ever need the raw form; for queryable fields, filter on a populated one instead.
Wazuh's JSON decoder strips empty-string and empty-object fields when it extracts events into `data.nb.*`. Fields that NetBird sends as `""` or `{}`, such as `destination_name`, `policy_name`, or an empty `meta` on some audit events, will not appear in indexed alerts, so KQL queries like `data.nb.meta.destination_name : *` return zero hits. The original wire payload is preserved in `full_log` if you need the raw form; for queryable fields, filter on a populated one instead.
</Note>
## Next steps
- Build out a starter deployment with a webhook receiver, Caddy in front, and the rules referenced here: [Wazuh receiver reference architecture](./wazuh-receiver).
- Set up a freshness watchdog by pointing an external uptime monitor (UptimeRobot, Prometheus blackbox-exporter, etc.) at the receiver's `/healthz` endpoint. NetBird's retry behaviour on 5xx is undocumented, so external monitoring is the best way to catch a downed receiver quickly.
- Set up a freshness watchdog by pointing an external uptime monitor (UptimeRobot, Prometheus blackbox-exporter, or similar) at the receiver's health endpoint. NetBird's retry behaviour on 5xx responses is undocumented, so external monitoring is the fastest way to catch a downed receiver.
- Review [Traffic Events Logging](/manage/activity/traffic-events-logging) before you enable it. Traffic event volume is an order of magnitude higher than audit event volume on a busy network, so size the receiver, the Wazuh indexer, and your retention accordingly.

View File

@@ -12,121 +12,271 @@ To get started with event logging in NetBird, watch this introductory video:
## Access the Audit Events Logging View
The audit events logging feature is enabled by default for every NetBird network. You can access the activity log in the web UI under the [Audit Events tab](https://app.netbird.io/events/audit). This view provides a centralized log of network events. You can use the search bar to search by activity name, and apply filters for timeframes, event types, and users.
The audit events logging feature is enabled by default for every NetBird network, on NetBird Cloud and on self-hosted deployments alike.
In the dashboard, open `Activity` in the sidebar and select `Audit Events` ([app.netbird.io/events/audit](https://app.netbird.io/events/audit)).
This view provides a centralized log of network events.
<Note>
The audit events view moved from `/activity` to `/events/audit` when the `Activity` section was split into `Audit Events` and `Traffic Events`.
The old `/activity` URL still redirects to the new one, so existing bookmarks keep working.
</Note>
<p>
<img src="/docs-static/img/manage/activity/activity-monitoring.png" alt="activity-monitoring" className="imagewrapper-big"/>
</p>
The current version of NetBird tracks a wide range of network changes that occur in the Management server, such as modifications to peers, groups, system settings, setup keys, and access control policies.
Each entry in the feed shows who triggered the event (name and email address), when it happened, and a description of the change with the
affected objects highlighted. Events triggered by the system rather than by a person are attributed to `System`. An `External` badge is added
when the initiator belongs to a different account than the one you are viewing, which happens when a managed service provider or a NetBird
support engineer acts on your account.
You can work with the feed using the following controls:
- **Search.** The `Search by audit name, user, peer, meta...` field matches the event name, the activity code, the initiator email address,
and the event metadata, which includes peer names, group names, and the names and email addresses of affected users.
- **Time range.** The date picker defaults to `Last 14 Days` and offers the `All Time`, `Last Month`, `Last 14 Days`, `Yesterday`, and `Today`
presets, plus a custom start and end date. Your selection is remembered in the browser.
- **Filters.** The `Filters` button exposes a `Type` filter, which lets you select one or more event types grouped by category, and an `Initiator`
filter, which narrows the feed down to a single user. System generated events are listed as `NetBird` in the `Initiator` filter.
Active filters appear as chips above the feed.
- **Reset Filters & Search** clears the search term, the filters, and the time range.
- **Refresh** reloads the feed from the Management server.
### Who can see audit events
Reading audit events requires read access to the `Activity` area, which the `Owner`, `Admin`, `Network Admin`, and `Auditor` roles have.
The `Billing Admin` and `User` roles have no access and see a restricted access message instead of the feed.
See [User roles](/manage/team/user-roles) for the full matrix. The same check applies to service users and
[personal access tokens](/manage/public-api) calling the API.
### Tracked events
NetBird tracks changes that occur in the Management server, such as modifications to peers, users, groups, networks, DNS settings,
system settings, setup keys, and access control policies. Each event has a human readable name and a stable activity code.
The activity code is what you see in the [API response](/api/resources/events) and in
[streamed events](/manage/activity/event-streaming), so it is the safest value to build alerts and dashboards on.
The list below reflects the events defined in NetBird v0.77.0. Later releases may add more, and events for features you do not use
never appear in your feed.
<details>
<summary>Click here to view the full list of tracked events</summary>
- **Peer Management:**
- Peer added by user
- Peer added with setup key
- Peer removed by user
- Peer renamed
- Peer SSH server enabled
- Peer SSH server disabled
- Peer login expiration enabled
- Peer login expiration disabled
- **Peers:**
- Peer added (`peer.user.add`), when a user adds the peer
- Peer added (`peer.setupkey.add`), when the peer joins with a setup key
- Peer deleted (`user.peer.delete`)
- Peer renamed (`peer.rename`)
- Peer approved (`peer.approve`)
- Peer approval revoked (`peer.approval.revoke`)
- Peer IP updated (`peer.ip.update`)
- Peer SSH server enabled (`peer.ssh.enable`)
- Peer SSH server disabled (`peer.ssh.disable`)
- Peer login expiration enabled (`peer.login.expiration.enable`)
- Peer login expiration disabled (`peer.login.expiration.disable`)
- Peer login expired (`peer.login.expire`)
- Peer inactivity expiration enabled (`peer.inactivity.expiration.enable`)
- Peer inactivity expiration disabled (`peer.inactivity.expiration.disable`)
- User logged in peer (`user.peer.login`)
- User extended peer session (`user.peer.session.extend`), since v0.72.0
- Create Job for peer (`peer.job.create`), since v0.64.0
- **Remote Job Management:**
- Remote job created for peer
- **Users:**
- User joined (`user.join`)
- User created (`user.create`)
- User invited (`user.invite`)
- User approved (`user.approve`)
- User rejected (`user.reject`)
- User role updated (`user.role.update`)
- User blocked (`user.block`)
- User unblocked (`user.unblock`)
- User deleted (`user.delete`)
- User password changed (`user.password.change`), since v0.64.0
- User invite link created (`user.invite.link.create`), since v0.64.2
- User invite link accepted (`user.invite.link.accept`), since v0.64.2
- User invite link regenerated (`user.invite.link.regenerate`), since v0.64.2
- User invite link deleted (`user.invite.link.delete`), since v0.64.2
- Transferred owner role (`transferred.owner.role`)
- Dashboard login (`dashboard.login`)
- **User Management:**
- User joined
- User invited
- User role updated
- User blocked
- User unblocked
- User deleted
- **Groups:**
- Group created (`group.add`)
- Group updated (`group.update`)
- Group deleted (`group.delete`)
- Group added to peer (`peer.group.add`)
- Group removed from peer (`peer.group.delete`)
- Group added to user (`user.group.add`)
- Group removed from user (`user.group.delete`)
- Group added to setup key (`setupkey.group.add`)
- Group removed from user setup key (`setupkey.group.delete`)
- Resource added to group (`resource.group.add`)
- Resource removed from group (`resource.group.delete`)
- **Group Management:**
- Group created
- Group updated
- Group deleted
- Group added to peer
- Group removed from peer
- Group added to user
- Group removed from user
- Group added to setup key
- Group removed from setup key
- Group added to disabled management DNS setting
- Group removed from disabled management DNS setting
- **Access control:**
- Policy added (`policy.add`)
- Policy updated (`policy.update`)
- Policy deleted (`policy.delete`)
- Posture check created (`posture.check.create`)
- Posture check updated (`posture.check.update`)
- Posture check deleted (`posture.check.delete`)
- **Policy Management:**
- Policy added
- Policy updated
- Policy removed
- **Rules (legacy, replaced by policies):**
- Rule added (`rule.add`)
- Rule updated (`rule.update`)
- Rule deleted (`rule.delete`)
- **Rule Management:**
- Rule added
- Rule updated
- Rule removed
- **Setup keys:**
- Setup key created (`setupkey.add`)
- Setup key updated (`setupkey.update`)
- Setup key revoked (`setupkey.revoke`)
- Setup key deleted (`setupkey.delete`)
- Setup key overused (`setupkey.overuse`)
- **Setup Key Management:**
- Setup key created
- Setup key updated
- Setup key revoked
- Setup key overused
- **Networks:**
- Network created (`network.create`)
- Network updated (`network.update`)
- Network deleted (`network.delete`)
- Network resource created (`network.resource.create`)
- Network resource updated (`network.resource.update`)
- Network resource deleted (`network.resource.delete`)
- Network router created (`network.router.create`)
- Network router updated (`network.router.update`)
- Network router deleted (`network.router.delete`)
- **Route Management:**
- Route created
- Route removed
- Route updated
- **Network routes:**
- Route created (`route.add`)
- Route updated (`route.update`)
- Route deleted (`route.delete`)
- **Account Management:**
- Account created
- Account peer login expiration duration updated
- Account peer login expiration enabled
- Account peer login expiration disabled
- Account peer approval enabled
- Account peer approval disabled
- **DNS:**
- Nameserver group created (`nameserver.group.add`)
- Nameserver group updated (`nameserver.group.update`)
- Nameserver group deleted (`nameserver.group.delete`)
- Group added to disabled management DNS setting (`dns.setting.disabled.management.group.add`)
- Group removed from disabled management DNS setting (`dns.setting.disabled.management.group.delete`)
- DNS zone created (`dns.zone.create`), since v0.63.0
- DNS zone updated (`dns.zone.update`), since v0.63.0
- DNS zone deleted (`dns.zone.delete`), since v0.63.0
- DNS zone record created (`dns.zone.record.create`), since v0.63.0
- DNS zone record updated (`dns.zone.record.update`), since v0.63.0
- DNS zone record deleted (`dns.zone.record.delete`), since v0.63.0
- **Nameserver Group Management:**
- Nameserver group created
- Nameserver group deleted
- Nameserver group updated
- **Services and reverse proxy:**
- Service created (`service.create`), since v0.65.0
- Service updated (`service.update`), since v0.65.0
- Service deleted (`service.delete`), since v0.65.0
- Peer exposed service (`service.peer.expose`), since v0.66.0
- Peer unexposed service (`service.peer.unexpose`), since v0.66.0
- Peer exposed service expired (`service.peer.expose.expire`), since v0.66.0
- **Token Management:**
- Personal access token created
- Personal access token deleted
- **Custom domains:**
- Domain added (`domain.add`), since v0.66.3
- Domain deleted (`domain.delete`), since v0.66.3
- Domain validated (`domain.validate`), since v0.66.3
- **Service User Management:**
- Service user created
- Service user deleted
- **Account and settings:**
- Account created (`account.create`)
- Account deleted (`account.delete`)
- Account DNS domain updated (`account.dns.domain.update`)
- Account network range updated (`account.network.range.update`)
- Account peer login expiration enabled (`account.setting.peer.login.expiration.enable`)
- Account peer login expiration disabled (`account.setting.peer.login.expiration.disable`)
- Account peer login expiration duration updated (`account.setting.peer.login.expiration.update`)
- Account peer inactivity expiration enabled (`account.peer.inactivity.expiration.enable`)
- Account peer inactivity expiration disabled (`account.peer.inactivity.expiration.disable`)
- Account peer inactivity expiration duration updated (`account.peer.inactivity.expiration.update`)
- Account peer approval enabled (`account.setting.peer.approval.enable`)
- Account peer approval disabled (`account.setting.peer.approval.disable`)
- User group propagation enabled (`account.setting.group.propagation.enable`)
- User group propagation disabled (`account.setting.group.propagation.disable`)
- Account routing peer DNS resolution enabled (`account.setting.routing.peer.dns.resolution.enable`)
- Account routing peer DNS resolution disabled (`account.setting.routing.peer.dns.resolution.disable`)
- Account lazy connection enabled (`account.setting.lazy.connection.enable`)
- Account lazy connection disabled (`account.setting.lazy.connection.disable`)
- Account AutoUpdate Version updated (`account.settings.auto.version.update`), since v0.61.0
- Account auto-update always enabled (`account.setting.auto.update.always.enable`), since v0.67.0
- Account auto-update always disabled (`account.setting.auto.update.always.disable`), since v0.67.0
- Account peer expose enabled (`account.setting.peer.expose.enable`), since v0.66.0
- Account peer expose disabled (`account.setting.peer.expose.disable`), since v0.66.0
- Account IPv6 overlay enabled (`account.setting.ipv6.enable`), since v0.71.0
- Account IPv6 overlay disabled (`account.setting.ipv6.disable`), since v0.71.0
- Account local MFA enabled (`account.setting.local.mfa.enable`), since v0.71.0
- Account local MFA disabled (`account.setting.local.mfa.disable`), since v0.71.0
- Account metrics push enabled (`account.setting.metrics.push.enable`), since v0.74.0
- Account metrics push disabled (`account.setting.metrics.push.disable`), since v0.74.0
- **Integration Management:**
- Integration created
- Integration updated
- Integration deleted
- **Tokens and service users:**
- Personal access token created (`personal.access.token.create`)
- Personal access token deleted (`personal.access.token.delete`)
- Service user created (`service.user.create`)
- Service user deleted (`service.user.delete`)
- **Other Events:**
- Transferred owner role
- Posture check created
- Posture check updated
- Posture check deleted
- User logged in peer
- Peer login expired
- Dashboard login
- **Integrations and identity providers:**
- Integration created (`integration.create`)
- Integration updated (`integration.update`)
- Integration deleted (`integration.delete`)
- Identity provider created (`identityprovider.create`), since v0.62.0
- Identity provider updated (`identityprovider.update`), since v0.62.0
- Identity provider deleted (`identityprovider.delete`), since v0.62.0
- **Agent Network (since v0.74.0):**
- Agent Network provider created (`agent_network.provider.create`)
- Agent Network provider updated (`agent_network.provider.update`)
- Agent Network provider deleted (`agent_network.provider.delete`)
- Agent Network policy created (`agent_network.policy.create`)
- Agent Network policy updated (`agent_network.policy.update`)
- Agent Network policy deleted (`agent_network.policy.delete`)
- Agent Network guardrail created (`agent_network.guardrail.create`)
- Agent Network guardrail updated (`agent_network.guardrail.update`)
- Agent Network guardrail deleted (`agent_network.guardrail.delete`)
- Agent Network budget rule created (`agent_network.budget_rule.create`)
- Agent Network budget rule updated (`agent_network.budget_rule.update`)
- Agent Network budget rule deleted (`agent_network.budget_rule.delete`)
- Agent Network settings updated (`agent_network.settings.update`)
- Agent Network settings deleted (`agent_network.settings.delete`)
</details>
Future versions will also support connection events that occur in NetBird agents (e.g., peer A connected to peer B).
Audit events cover configuration changes on the Management server. Connection level events, such as which peer connected to which
resource and whether the connection was allowed or blocked, are covered by [Traffic Events Logging](/manage/activity/traffic-events-logging).
<Note>
The `unknown` name or `unknown@unknown.com` email address may be displayed in the activity event store if the encryption key has been corrupted or lost. This issue is most relevant for self-hosted setups. In this case, the events returned by the API could show `unknown@unknown.com` for the email address field and `unknown` for the name field.
For the combined setup, the encryption key is the <b>server.store.encryptionKey</b> field in <b>config.yaml</b>. For older multi-container setups generated by the <b>configure.sh</b> script, look for the <b>DataStoreEncryptionKey</b> field in the <b>management.json</b> backup file.
</Note>
## Retrieve Audit Events Through the API
Audit events are also available over the REST API through the
[`GET /api/events/audit`](/api/resources/events) endpoint. It enforces the same role permissions as the dashboard and returns the
10,000 most recent events for your account, newest first. There are no pagination or filtering parameters, and the dashboard reads the
same endpoint, so the feed in the web UI is subject to the same limit.
The dashboard has no CSV or JSON download button. To archive events outside NetBird, either poll this endpoint or use
[event streaming](/manage/activity/event-streaming).
## Enable Audit Events Streaming to SIEM Systems
NetBird can stream audit events to your Security Information and Event Management (SIEM) system in real-time. With this feature enabled, you can monitor and analyze NetBird network changes within your SIEM infrastructure. Check the [integrations guide](/manage/activity/event-streaming) for more information about the supported integrations and how to enable them.
<Note>
Event streaming is a licensed feature. It is available on NetBird Cloud and on licensed self-hosted deployments; it is not served on open source self-hosted deployments.
</Note>
## Self-Hosted Event Storage
On self-hosted deployments the audit events are kept in a dedicated database, separate from the main Management store.
NetBird does not delete audit events on a schedule, so the store grows over time and you are responsible for its backup and retention.
- **SQLite (default).** Events are written to `events.db` inside the Management data directory, `/var/lib/netbird/` by default. Since v0.66.1 you can set `NB_ACTIVITY_EVENT_SQLITE_FILE` to use a different file name or an absolute path.
- **PostgreSQL.** Set `NB_ACTIVITY_EVENT_STORE_ENGINE=postgres` and `NB_ACTIVITY_EVENT_POSTGRES_DSN` to the connection string. See [Activity Events Postgres Store](/selfhosted/maintenance/activity-postgres-store) for the full procedure.
Names and email addresses of users who have since been deleted are stored encrypted with the data store encryption key described in the note
above, so that historical events still show who did what. Back that key up together with the database; without it those names and email
addresses cannot be decrypted and are shown as `unknown` and `unknown@unknown.com`. Names and email addresses of users who still exist are
resolved from your identity provider when the events are read, so they are not affected.
## Get Started
<div>

View File

@@ -2,10 +2,14 @@
<Note>
This feature is available in NetBird Cloud under the [Business plan](https://www.netbird.io/pricing?utm_source=docs&utm_content=traffic-events) and in licensed self-hosted Enterprise deployments with traffic flow enabled.
This feature is in Beta and may change over time — including how data is collected and reported.
Traffic events are experimental, so functionality and behavior may evolve, including how data is collected and reported.
To use this feature, make sure you're running NetBird client version 0.39 or higher.
</Note>
<Note>
On self-hosted deployments, traffic flow is an opt-in part of the [Enterprise stack](/selfhosted/enterprise/getting-started). It requires a license, a PostgreSQL store, and the extra `nats`, `receiver`, and `enricher` services. It is not available on the community self-hosted stack.
</Note>
The traffic events logging functionality enables comprehensive monitoring and analysis of connections across your infrastructure.
It captures network activity, including peer-to-peer, site-to-site, peer-to-resource, and other network traffic events.
@@ -51,7 +55,8 @@ You'll see two aggregated flow records, one reported by each peer (source and de
The record from `server` represents the receiver's perspective. Because `server` allows the connection, it includes the policy `IT Admins to Servers` that authorized the flow over `TCP` on port `443`.
<Note>
Use the `P2P` filter in the table to view only peer-to-peer connection events.
The `Router` column is empty for peer-to-peer flows, so an empty `Router` value is the quickest way to spot them in the table.
The API also accepts a `connection_type` query parameter on `GET /api/events/network-traffic` if you want to filter programmatically.
</Note>
#### Blocked P2P Connections Events
@@ -60,15 +65,15 @@ If a connection is refused, NetBird logs the blocked event on the peer that deni
The initiating peer `Alice` will still report the connection attempt but won't be aware that it was blocked.
In this scenario, the `IT Admins to Servers` policy is configured to allow only ping requests (`ICMP`),
meaning all `HTTP` requests are intentionally not allowed. The screenshot below illustrates this behavior.
meaning `TCP` connections are intentionally not allowed. The screenshot below illustrates this behavior.
<p>
<img src="/docs-static/img/manage/activity/traffic-events-logging/p2p-blocked-connection.png" alt="traffic-events-p2p-blocked-connection" className="imagewrapper-big"/>
</p>
### Peer-to-Network Resource Connections
When a peer connects to a [network resource](/manage/networks#resources), NetBird captures and logs the traffic
events for that connection on the peer that initiated the connection, and on the [routing peer](/manage/networks#routing-peers) that connects the peer to
When a peer connects to a [network resource](/manage/networks#resource), NetBird captures and logs the traffic
events for that connection on the peer that initiated the connection, and on the [routing peer](/manage/networks#routing-peer) that connects the peer to
the internal network resource.
A slightly modified example of the CRM server connection scenario would be if instead of running the NetBird client on the CRM server,
@@ -85,21 +90,21 @@ routed the connection to the CRM server. If the connection was blocked, NetBird
The screenshot below illustrates a successful connection from `Alice` to the network resource `CRM` running in the AWS VPC.
The traffic is routed through a routing peer, which logs the connection event and reports it to the NetBird servers.
The access is permitted by the policy `IT Admins to AWS Servers`, which allows connections over the `TCP` protocol on port `443`.
Note the `ROUTER` column in the table, which identifies the routing peer responsible for routing to the internal network resource.
Note the `Router` column in the table, which identifies the routing peer responsible for routing to the internal network resource.
<p>
<img src="/docs-static/img/manage/activity/traffic-events-logging/network-resource-successful-connection.png" alt="network-resource-succesful-connection" className="imagewrapper-big"/>
</p>
<Note>
Use the `Routed` filter in the table to view only peer-to-network resource connection events.
Routed flows are the ones with a value in the `Router` column, because the routing peer, not the destination, is the peer that reports them.
</Note>
#### Blocked Peer-to-Network Resource Events
In the event of a blocked connection, the initiating peer logs the connection attempt, while the routing peer records the blocked event.
The screenshot below demonstrates this behavior: the routing peer blocks a connection to the network resource `CRM` because
the policy `IT Admins to AWS Servers` does not permit connections over the `HTTP` protocol on port `6432`.
the policy `IT Admins to AWS Servers` does not permit `TCP` connections on port `6432`.
The routing peer's aggregate shows the number of dropped attempts, so repeated application retries increase the drop count instead of creating one top-level row for every attempt.
<p>
@@ -113,26 +118,30 @@ The routing peer's aggregate shows the number of dropped attempts, so repeated a
## Event Aggregation
Starting with v0.75, clients aggregate related traffic events before reporting them. For a given source address and direction, a group is identified by protocol, destination address, destination port for TCP or UDP, and ICMP type for ICMP traffic. Source port and ICMP code do not split aggregates. During each reporting window, NetBird accumulates:
Since client v0.75.0, clients aggregate related traffic events before reporting them. A group is identified by source address, destination address, direction, protocol, destination port for TCP or UDP, and ICMP type for ICMP traffic. Source port and ICMP code do not split aggregates. During each reporting window, NetBird accumulates:
* connection start, end, and drop counts;
* transmitted and received packet totals;
* transmitted and received byte totals;
* the start and end of the aggregation window.
The Dashboard and API therefore present one flow record with counters for activity in that window instead of a separate top-level record for every start, end, or blocked event. The `events` array can retain individual event timestamps where they are available.
The Dashboard and API therefore present one flow record with counters for activity in that window instead of a separate top-level record for every start, end, or blocked event. Only TCP, UDP, ICMP, and ICMPv6 flows are aggregated. Any other protocol is reported as an individual event.
<Note>
Aggregated rows in the Dashboard show the window range instead of a single timestamp, and the description reads as a summary, for example `Peer Alice started 3 connections to Peer server` or `Peer Alice got blocked 5 times trying to connect to Resource CRM`. Expand the row to see which policy allowed or blocked the flow.
</Note>
## Enabling Traffic Events Logging
Traffic events logging feature is disabled by default. To enable it on the NetBird dashboard, navigate to `Settings > Networks`.
Under the Experimental section, you'll find the `Enable Traffic Events` option. Toggle the switch to enable traffic event logging.
Traffic events logging is disabled by default. To enable it on the NetBird dashboard, navigate to `Settings > Networks`.
Under the `Experimental` section, you'll find the `Enable Traffic Events` option. Toggle the switch to enable traffic event logging.
Changing this setting requires the `Owner` or `Admin` role.
By default, traffic reporting in userspace is always enabled, providing basic logging of network interactions.
However, packet size reporting at the kernel level is disabled by default to minimize CPU usage.
Peers that run the NetBird userspace packet filter always report packet and byte counts for the flows they see.
Kernel-level counting is disabled by default to minimize CPU usage.
<Note>
You can optionally enable `Traffic Reporting (Kernel)` to capture additional details, such as network packet sizes,
at the kernel level. Be aware that enabling this option may lead to higher CPU usage on the NetBird client.
You can optionally turn on `Enable Traffic Reporting (Kernel)` to capture packet and byte counts on Linux peers that use the WireGuard kernel module. It turns on kernel connection tracking accounting (`net.netfilter.nf_conntrack_acct`) on those peers and has no effect on peers that already run in userspace, such as macOS and Windows clients. Be aware that enabling this option may lead to higher CPU usage on the NetBird client.
</Note>
@@ -147,20 +156,19 @@ You can scope traffic events logging to only the peers that belong to specific g
- When you select one or more groups, only peers that are members of the selected groups will report traffic events.
- If no group is selected, logging applies to all peers in the account (default behavior).
To configure this setting, navigate to `Settings > Networks` in the Experimental section, open the Group Selector under `Enable Traffic Events`
choose the groups you want to include, and click `Save Groups`.
To configure this setting, navigate to `Settings > Networks`, and in the `Experimental` section open the `Limit To Specific Groups` selector
below `Enable Traffic Events`, choose the groups you want to include, and click `Save Groups`.
<p>
<img src="/docs-static/img/manage/activity/traffic-events-logging/traffic-events-groups-logging-settings.png" alt="traffic-events-groups-logging-settings" className="imagewrapper-big"/>
</p>
## Log Retention
While in experimental mode, logs are retained for **seven days**.
Additionally, the current API returns a maximum of **50,000 flow records**.
This limit may change.
While the feature is experimental, traffic event data is retained for **48 hours** and capped at a maximum of **50,000 events**.
The same limits are printed in the `Experimental` section of `Settings > Networks`. They may change.
## Report rate
Aggregated flows might take up to **ten minutes** to become available through the API and Dashboard. An end count for some TCP connections can appear in a later window, depending on OS settings and connection termination.
A flow is only sent once its aggregation window closes, and the window length is set by the NetBird server, not by the client. Aggregated flows might take up to **ten minutes** to become available through the API and Dashboard. An end count for some TCP connections can appear in a later window, depending on OS settings and connection termination.
## Enable Traffic Events Streaming to SIEM Systems
@@ -174,111 +182,129 @@ For detailed instructions on supported integrations and how to set them up, refe
When enabled, a NetBird peer will record metadata for each network flow that it participates in. The data collected by peers includes:
* **Window start and end**: The bounds of the aggregation window.
* **Flow ID**: A unique identifier for the aggregated traffic flow.
* **Window start and end**: The bounds of the aggregation window (`window_start` and `window_end`).
* **Flow ID**: The identifier of the connection flow (`flow_id`). It is not globally unique, because both sides of the same connection can report it.
* **Event counts**: `num_of_starts`, `num_of_ends`, and `num_of_drops` for the group.
* **Source and Destination IP Addresses**: The IP of the peer (source) and the IP of the remote endpoint (destination). For peer-to-peer traffic,
these will be the NetBird network IPs (e.g. 100.x.x.x addresses of each peer). For traffic to an external resource (like a private server or subnet), the destination might be an IP in that remote network.
* **Source and Destination Ports**: The network ports recorded for TCP/UDP flows. Destination port is part of the aggregation key; source port does not split aggregates.
* **ICMP Type**: For ICMP traffic, the ICMP type used to group the flow. ICMP code does not split aggregates.
* **Protocol**: The protocol of the traffic, such as TCP, UDP, or ICMP.
* **Direction**: Whether the flow was inbound or outbound. This takes into consideration the perspective of the **peer reporting the traffic** and the NetBird interface.
* **Volume of Data**: Packet and byte totals sent and received during the aggregation window.
* **Resource ID**: Network route or Networks resource ID that the flow is associated with. This is useful for identifying the routing configuration that allowed the flow. DNS route information is **available only** on the routing client.
* **Rule ID**: The ID of the policy that allowed the flow. This is useful for identifying the access control policy that allowed the flow. This information is **available only** on the receiving side of the traffic.
* **Source and Destination Ports**: The network ports recorded for TCP/UDP flows. They are reported as part of the `address` field of the source and destination. Destination port is part of the aggregation key; source port does not split aggregates.
* **ICMP Type and Code**: For ICMP and ICMPv6 traffic, the type and code of the flow. Only the type is part of the aggregation key, so the code does not split aggregates.
* **Protocol**: The IANA protocol number of the traffic, for example `1` for ICMP, `6` for TCP, `17` for UDP, and `58` for ICMPv6.
* **Direction**: `INGRESS` or `EGRESS`. This takes into consideration the perspective of the **peer reporting the traffic** and the NetBird interface.
* **Volume of Data**: Packet and byte totals sent and received during the aggregation window (`tx_packets`, `rx_packets`, `tx_bytes`, `rx_bytes`).
* **Resource ID**: Network route or Networks resource ID that the flow is associated with. This is useful for identifying the routing configuration that allowed the flow. For domain based resources, the resource is attributed on the peer that resolved the domain, so one side of a flow can carry the resource while the other side reports only the address.
* **Rule ID**: The ID of the policy that allowed or blocked the flow. This is useful for identifying the access control policy that applied to the flow. This information is **available only** on the receiving side of the traffic, and only when that peer runs the userspace packet filter. See [Limitations](#limitations).
In addition to the data collected by the peers, the NetBird API provides additional context about the peers and resources involved in the traffic event. These details include:
* **Peer Name**: The name of the peer.
* **Peer ID**: The unique identifier of the peer.
* **Resource name**: The name of the resource or network route.
* **Policy Name**: The name of the policy that allowed the flow.
* **User ID, name, and email**: The name and email of the user associated with the source peer.
* **Reporter ID**: The unique identifier of the peer that reported the traffic event.
* **Received timestamp**: The timestamp when the event was received by the NetBird servers.
* **Peer or resource name, ID, and type**: Returned as the `source` and `destination` objects, with `type` set to `PEER`, `HOST_RESOURCE`, `SUBNET_RESOURCE`, `DOMAIN_RESOURCE`, `ROUTE`, or `UNKNOWN`.
* **Operating system, DNS label, and geo location**: Extra context on each endpoint.
* **Policy ID and name**: Returned as the `policy` object.
* **User ID, name, and email**: The user associated with the source peer, returned as the `user` object.
* **Reporter ID**: The unique identifier of the peer that reported the traffic event (`reporter_id`).
* **Sub-events**: The `events` array carries the individual event types and timestamps that the peer reported for the flow.
<details>
<summary>API sample response</summary>
<summary>API sample response (one entry from the data array)</summary>
```json
{
"destination": {
"address": "142.250.185.206:443",
"dns_label": "*.google.com",
"geo_location": {
"city_name": "",
"country_code": ""
},
"id": "cvco2st9q2cs73btphmg",
"name": "Any google.com domain",
"os": "",
"type": "DOMAIN_RESOURCE"
{
"flow_id": "9682d060-3b28-4fa3-8b47-98595a51bbda",
"reporter_id": "cvco2st9q2cs73btphm0",
"source": {
"id": "cvco2st9q2cs73btphm0",
"type": "PEER",
"name": "MacBook-Pro-10.local",
"geo_location": {
"city_name": "Frankfurt",
"country_code": "DE"
},
"direction": "EGRESS",
"flow_id": "9682d060-3b28-4fa3-8b47-98595a51bbda",
"icmp_code": 0,
"icmp_type": 0,
"id": "c94e398c-dbfb-4344-8c47-a731b984d86e",
"policy_id": "ndkslcanlksncl",
"policy_name": "Allow google access",
"protocol": 6,
"receive_timestamp": "2025-03-22T20:26:19.491144Z",
"reporter_id": "ldkfnwklenfklernl",
"rx_bytes": 0,
"rx_packets": 0,
"source": {
"address": "100.89.67.186:50229",
"dns_label": "macbook-pro-10-2",
"geo_location": {
"city_name": "Frankfurt",
"country_code": "DE"
},
"id": "ldkfnwklenfklernl",
"name": "MacBook-Pro-10.local",
"os": "Darwin",
"type": "PEER"
"os": "Darwin",
"address": "100.89.67.186:50229",
"dns_label": "macbook-pro-10-2"
},
"destination": {
"id": "cvco2st9q2cs73btphmg",
"type": "DOMAIN_RESOURCE",
"name": "Any google.com domain",
"geo_location": {
"city_name": "",
"country_code": ""
},
"window_start": "2025-03-22T20:26:16.937522Z",
"window_end": "2025-03-22T20:30:17.257891Z",
"num_of_starts": 1,
"num_of_ends": 1,
"num_of_drops": 0,
"tx_bytes": 64,
"tx_packets": 1,
"events": [
{
"type": "TYPE_START",
"timestamp": "2025-03-22T20:26:16.937522Z"
},
{
"type": "TYPE_END",
"timestamp": "2025-03-22T20:30:17.257891Z"
}
],
"user_email": "john@example.com",
"user_id": "google-oauth2|xyz0123",
"user_name": "John Doe"
}
"os": "",
"address": "142.250.185.206:443",
"dns_label": "*.google.com"
},
"user": {
"id": "google-oauth2|xyz0123",
"email": "john@example.com",
"name": "John Doe"
},
"policy": {
"id": "cvco2st9q2cs73btphn0",
"name": "Allow google access"
},
"icmp": {
"type": 0,
"code": 0
},
"protocol": 6,
"direction": "EGRESS",
"rx_bytes": 0,
"rx_packets": 0,
"tx_bytes": 64,
"tx_packets": 1,
"num_of_starts": 1,
"num_of_ends": 1,
"num_of_drops": 0,
"window_start": "2026-03-22T20:26:16.937522Z",
"window_end": "2026-03-22T20:30:17.257891Z",
"events": [
{
"type": "TYPE_START",
"timestamp": "2026-03-22T20:26:16.937522Z"
},
{
"type": "TYPE_END",
"timestamp": "2026-03-22T20:30:17.257891Z"
}
]
}
```
</details>
## Viewing Traffic Events on the Dashboard
There are two places where you can see the traffic events on the NetBird dashboard:
1. **Traffic events**: Under Activity, you will find the Traffic events menu. This view shows the traffic events in a table format for all peers in your network.
2. **Peer details**: When you click on a peer, you will see the traffic events for that peer in the Peer details view.
1. **Traffic Events**: Under `Activity`, you will find the `Traffic Events` menu. This view shows the traffic events in a table format for all peers in your network.
2. **Peer details**: When you click on a peer, the `Traffic Events` tab shows the events reported by that peer, with an `Inbound` and `Outbound` switch.
Reading traffic events requires the `Owner`, `Admin`, `Auditor`, or `Network Admin` role. Users with the `User` role do not see the `Activity` menu.
The `Traffic Events` table shows the following columns:
| Column | Description |
| --- | --- |
| `Event` | The aggregation window and a summary of what happened, for example how many connections started, ended, or were blocked. Expand the row to see which policy allowed or blocked the flow. |
| `Source` | The peer, resource, route, or address that the flow came from. Hover it for the endpoint's domain, geo location, and, on outbound flows from a peer, the user behind it. |
| `Protocol & Port` | The protocol of the flow and the destination port. For ICMP and ICMPv6, the type and code are shown instead of a port. |
| `Destination` | The peer, resource, route, or address that the flow was sent to. |
| `Traffic` | Received and transmitted bytes for the aggregation window. |
| `Router` | The routing peer that reported the flow. Empty for peer-to-peer flows. |
The peer's `Traffic Events` tab uses the same columns without `Router`, because every row on that tab is reported by the peer you are looking at.
### Filters
You can use various filters to search and filter received events. The filters include:
- **Source**: Select a source peer, network resource, route, or user. The API equivalent is `source_id`.
The traffic events table defaults to the last **7 days**. You can narrow the list with:
- **Search**: The `Search by ip, port, peer or resource...` box does a case-insensitive partial match on user email, source and destination names, and source and destination addresses. The API equivalent is `search`.
- **Date range**: The date picker sets the window to query. The API equivalents are `start_date` and `end_date`.
- **Source**: Select a source peer, network resource, or user. The API equivalent is `source_id` for peers and resources, and `user_id` for users.
- **Destination**: Select a destination peer or network resource. The API equivalent is `destination_id`.
- **IP address**: Source or destination IP addresses
- **Ports**: Source or destination ports
- **Timestamp**: Aggregation-window time range
- **Protocol**: ICMP, TCP, or UDP
- **Flow type and direction**: P2P or routed traffic, inbound or outbound, including groups with start, end, or drop counts
The `GET /api/events/network-traffic` endpoint accepts more filters than the Dashboard exposes, including `protocol`, `type`, `connection_type`, `direction`, and `reporter_id`. See the [API reference](/api/resources/events).
## Correlating events
Correlate a session by comparing the aggregated flow records reported by both sides. If Peer A connects to Peer B, each reporter can contribute a record for the same source and destination tuple. A successful flow normally increases the start and end counters. If Peer B rejects it, the receiver's record increases the drop counter while the initiator may only know that it attempted the connection.
<Note>
Blocked events are only reported when the destination peer is in userspace mode. See [Limitations](#limitations).
Blocked events are only reported when the peer that refuses the traffic runs the NetBird userspace packet filter. See [Limitations](#limitations).
</Note>
### Viewing TCP and UDP connections
@@ -296,7 +322,7 @@ The UDP connection is very similar:
<img src="/docs-static/img/manage/activity/traffic-events-logging/p2p-udp-allow.png" alt="P2P UDP Allowed" className="imagewrapper-big"/>
</p>
<Note>
UDP is stateless, so its end counter is updated after the client observes the configured inactivity period.
UDP is stateless, so its end counter is only updated after the client observes 30 seconds of inactivity on the connection.
</Note>
When a connection is blocked, you may see similar entries to the following events but with a few differences:
@@ -310,9 +336,9 @@ When a connection is blocked, you may see similar entries to the following event
<p>
<img src="/docs-static/img/manage/activity/traffic-events-logging/p2p-udp-blocked.png" alt="P2P UDP Blocked" className="imagewrapper-big"/>
</p>
On the refusing side, retries increase `num_of_drops`; the client does not record a successful start or end for traffic it rejected.
On the refusing side, retries increase `num_of_drops`; the client does not record a successful start or end for traffic it rejected. Drops are always recorded as `INGRESS`, because a peer can only observe traffic that it refused to accept.
<Note>
Blocked events are only reported when the destination peer is in userspace mode. See [Limitations](#limitations).
Blocked events are only reported when the peer that refuses the traffic runs the NetBird userspace packet filter. See [Limitations](#limitations).
</Note>
### Viewing ICMP connections
@@ -321,7 +347,7 @@ ICMP events are similar to TCP and UDP events. The main difference is that ICMP
<img src="/docs-static/img/manage/activity/traffic-events-logging/p2p-icmp-allowed.png" alt="P2P ICMP Allowed" className="imagewrapper-big"/>
</p>
<Note>
ICMP is grouped by ICMP type and does not use ports. Its end counter is updated after inactivity.
ICMP is grouped by ICMP type and does not use ports. Its end counter is only updated after 30 seconds of inactivity.
</Note>
### Routed events
Routed events follow the same pattern as P2P events. The main difference is that the destination or source can be a resource or network route. Below, we have a few examples of a connection from a peer to a resource:
@@ -334,7 +360,7 @@ Routed events follow the same pattern as P2P events. The main difference is that
<p>
<img src="/docs-static/img/manage/activity/traffic-events-logging/routed-tcp-allowed.png" alt="Routed TCP Allowed" className="imagewrapper-big"/>
</p>
For routed aggregates, the source or destination can be a resource or network route. The record identifies the routing peer that reported it. The source or destination identifier can be unknown on the routing-peer side for DNS resources.
For routed aggregates, the source or destination can be a resource or network route, and the `Router` column identifies the routing peer that reported it. For domain based resources, the endpoint is resolved on the peer that performed the DNS resolution, so one side of the flow can show the resource name while the other side shows only the address with type `UNKNOWN`.
For site-2-site connections, the events will be similar to the above examples, but you will see a routing peer for each event:
<p>
@@ -342,16 +368,29 @@ For site-2-site connections, the events will be similar to the above examples, b
</p>
## Limitations
<Note>
Policy IDs and blocked traffic events are not reported when the destination peer (or routing peer) is running in kernel mode.
</Note>
On Linux, you can force a routing peer into userspace mode with three [environment variables](/client/environment-variables):
Policy IDs and blocked traffic events are produced by the NetBird userspace packet filter. A peer that hands access control to the kernel does not report them.
* On **macOS and Windows**, the client always runs the userspace packet filter, so policy IDs and blocked events are reported.
* On **Linux**, the client uses the native `nftables` or `iptables` backend by default, even when WireGuard itself runs in userspace. On those peers, drops happen in the kernel and are not reported.
Packet and byte counters have a separate constraint. Linux peers that use the WireGuard kernel module only report them when `Enable Traffic Reporting (Kernel)` is on. Peers on the userspace packet filter always report them.
On Linux, you can force a peer or routing peer fully into userspace with three [environment variables](/client/environment-variables):
```bash
sudo netbird service reconfigure --service-env NB_WG_KERNEL_DISABLED=true,NB_FORCE_USERSPACE_FIREWALL=true,NB_FORCE_USERSPACE_ROUTER=true
```
<Warning>
Running the data path in userspace costs more CPU than the kernel path. Test the change on a non-critical peer before applying it to a routing peer that carries production traffic.
</Warning>
Two more classes of traffic are filtered out by the client before events are sent, unless the NetBird server enables them for your account:
* **DNS traffic**: UDP flows to port `53` and to the NetBird DNS forwarder ports `5353` and `22054`.
* **Exit node traffic**: Flows that match a default route through an [exit node](/use-cases/remote-access/exit-nodes).
## Conclusion
Traffic events logging provides a powerful tool for monitoring and analyzing network traffic across your infrastructure.
Enabling this feature can provide valuable insights into network activity, enhance security measures, and improve operational efficiency.