import {Note} from "@/components/mdx" export const description = 'Monitor and audit HTTP requests and L4 connections flowing through your NetBird reverse proxy services with detailed access logs.' # Reverse Proxy Access Logs NetBird logs every request and connection that passes through your reverse proxy services, including both HTTP and L4 (TCP, UDP, TLS) traffic. Access logs provide visibility into who is accessing your services, from where, and whether requests were allowed or denied. This is useful for auditing, debugging, and monitoring traffic to your publicly exposed services. ## Viewing access logs Access logs are available in the NetBird dashboard under **Reverse Proxy** > **Access Logs**. This view displays a table of all HTTP requests and L4 connections that have passed through your reverse proxy services, with filters to narrow down results by time range, status, or other fields.

Proxy Events table showing reverse proxy access log entries

You can also retrieve access logs programmatically using the API: ```bash GET /api/events/proxy ``` ## What access logs capture Every log entry (HTTP and L4) shares a common set of fields. Some fields are only meaningful for certain protocols. | Field | Description | HTTP | L4 (TCP/UDP/TLS) | |-------|-------------|:----:|:-----------------:| | **Timestamp** | When the request or connection occurred | Yes | Yes | | **Protocol** | `http`, `tcp`, `udp`, or `tls` | Yes | Yes | | **Method** | HTTP method (GET, POST, etc.). For L4, displays the protocol name. | Yes | Protocol name | | **Host / URL** | Domain and path for HTTP. Host and listen port for L4. | `host/path` | `host:port` | | **Status Code** | HTTP status code (200, 401, 403, 500, etc.) | Yes | Empty | | **Duration** | Request or connection duration in milliseconds | Yes | Yes | | **Bytes Uploaded** | Bytes sent from client to backend | Yes | Yes | | **Bytes Downloaded** | Bytes sent from backend to client | Yes | Yes | | **Source IP** | The client's IP address | Yes | Yes | | **Location** | Country, city, and subdivision based on source IP geolocation | Yes | Yes | | **Auth Method** | Raw `auth_method_used` value: `oidc` (shown as SSO in the dashboard), `password`, `pin`, `header`, or a target access action such as `path_bypass` or `path_block`. For denied requests, carries the restriction code instead (e.g. `ip_restricted`, `crowdsec_ban`). Omitted from the API response when empty | Yes | Restriction code on denials | | **User** | The authenticated user's ID, set when `oidc` authentication was used. Omitted from the API response when empty | Yes | N/A | | **Reason** | Exactly one of two values: `Authentication failed` when authentication or an access restriction rejected the request, or `Request failed` when an authenticated request returned `4xx`/`5xx`. Set for HTTP entries only and omitted from the API response when empty. Never a specific denial code: see the note under [Deny reasons](#deny-reasons) | Yes | Omitted | | **Metadata** | Additional decision details. Target access records `access_action` as `bypass`, `block`, or `invalid_path` (an ambiguous request path rejected with `400`); CrowdSec records its mode and verdict here | Yes | Yes | ## Understanding log entries ### HTTP log entries HTTP log entries fall into three categories based on the status code: - **Allowed requests**: successful requests show a `2xx` status code along with the authentication method used to access the service. A target that bypasses authentication records `path_bypass`. The dashboard marks these entries with a small open-lock icon in the **User** column, at the right end of the row, labeled **Auth Bypassed** on hover. - **Denied requests**: failed authentication, access restriction blocks, and blocked target paths show `401` or `403` status codes with `reason` set to `Authentication failed`. The specific cause (invalid password, missing SSO session, blocked path, IP restricted, country restricted, CrowdSec verdict) is carried in `auth_method_used`, not in `reason`. A blocked target path records `path_block`. The dashboard marks these entries with a small shield icon in the **User** column, at the right end of the row, labeled **Path Blocked** on hover. - **Errors**: backend errors or proxy issues show `5xx` status codes. These typically indicate that the target service is unreachable or returned an error. ### L4 log entries L4 entries are logged when the connection closes and record the total bytes transferred in each direction and the connection duration. L4 entries do not have HTTP status codes. Denied L4 connections (blocked by access restrictions) are logged immediately. L4 entries carry no `reason` value, so the restriction code identifies the denial. Since L4 services do not support authentication, denials come from access restrictions only. ### Deny reasons The following deny reasons identify why a connection was rejected. Note that for HTTP services these values are not carried in the entry's `reason` field: see the note below the table. | Reason | Description | |--------|-------------| | `path_block` | The matching HTTP target is configured to block access | | `ip_restricted` | The client IP was blocked by a CIDR access restriction | | `country_restricted` | The client's country was blocked by a country access restriction | | `geo_unavailable` | Country restrictions are configured but the GeoIP database is unavailable (fail-closed) | | `crowdsec_ban` | The client IP has a CrowdSec ban decision | | `crowdsec_captcha` | The client IP has a CrowdSec captcha decision | | `crowdsec_throttle` | The client IP has a CrowdSec throttle decision | | `crowdsec_unavailable` | CrowdSec enforce mode is active but the bouncer has not completed its initial sync (fail-closed) | All CrowdSec decision types (ban, captcha, throttle) result in a connection denial in enforce mode. The proxy does not serve captcha challenges or apply rate limiting: the decision type is recorded for informational purposes only. For HTTP services, the deny code from the table above is recorded in the `auth_method_used` field, and the entry's `reason` field carries a synthesized generic value rather than the specific code. This applies to every access restriction, not only CrowdSec: ```json { "status_code": 403, "reason": "Authentication failed", "auth_method_used": "ip_restricted" } ``` ```json { "status_code": 403, "reason": "Authentication failed", "auth_method_used": "crowdsec_ban", "metadata": { "crowdsec_verdict": "crowdsec_ban" } } ``` When reading entries through `GET /api/events/proxy`, match on `auth_method_used` (and `metadata.crowdsec_verdict` for CrowdSec specifically) rather than `reason`. Observe-mode entries carry the normal status code and record both `crowdsec_mode` and `crowdsec_verdict` in `metadata`. Because the connection is allowed, CrowdSec itself contributes no `reason`, but the field can still be populated by a later stage of the request such as an authentication or backend failure. Treat `metadata.crowdsec_mode` as the signal that an entry is an observe-mode verdict, not the absence of `reason`. When CrowdSec is in **observe** mode, the verdict appears in the log metadata and CrowdSec adds no deny reason of its own (the connection is allowed). In the dashboard, these entries render with an observe-mode badge on the reason cell and show the underlying decision type (ban, captcha, throttle, unavailable) on hover. This lets you audit what CrowdSec would block without affecting traffic. For a self-test workflow, see [Testing the integration](/selfhosted/maintenance/crowdsec#testing-the-integration). ## Use cases Access logs support several operational and security workflows: - **Security auditing** - Review who accessed sensitive services, which authentication method they used, and from which geographic locations. This helps identify unauthorized access attempts and verify that authentication policies are working as expected. - **Debugging** - Trace failed requests to understand authentication or routing issues. The status code, duration, and reason fields help pinpoint whether problems originate from authentication configuration, target availability, or network connectivity. - **Monitoring** - Track usage patterns across your services. Identify which services receive the most traffic, peak usage times, and unusual access patterns that may warrant investigation. - **Compliance** - Maintain records of service access for regulatory requirements. Access logs provide an auditable trail of who accessed what, when, and from where. ## Retention and Cleanup For the cloud version of NetBird, access logs are retained for 7 days. For the self-hosted version, access log retention can be configured in the `management.json` or `config.yaml` by setting the following config parameters: ```json { "ReverseProxy": { "AccessLogRetentionDays": 7, "AccessLogCleanupIntervalHours": 24 } } ``` ```yaml reverseProxy: accessLogRetentionDays: 7 accessLogCleanupIntervalHours: 24 ``` - **accessLogRetentionDays** - Define how long access logs are retained before they are automatically deleted. - **accessLogCleanupIntervalHours** - Set how often the system checks for and deletes expired access log entries. ## Related pages - [Reverse Proxy Overview](/manage/reverse-proxy) - learn how to create and manage reverse proxy services - [Audit Events Logging](/manage/activity) - view management-level events such as configuration changes and user activity - [Traffic Events Logging](/manage/activity/traffic-events-logging) - monitor network-level traffic events across your NetBird mesh