Reverse Proxy Access Logs

Updated

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:

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.

FieldDescriptionHTTPL4 (TCP/UDP/TLS)
TimestampWhen the request or connection occurredYesYes
Protocolhttp, tcp, udp, or tlsYesYes
MethodHTTP method (GET, POST, etc.). For L4, displays the protocol name.YesProtocol name
Host / URLDomain and path for HTTP. Host and listen port for L4.host/pathhost:port
Status CodeHTTP status code (200, 401, 403, 500, etc.)YesEmpty
DurationRequest or connection duration in millisecondsYesYes
Bytes UploadedBytes sent from client to backendYesYes
Bytes DownloadedBytes sent from backend to clientYesYes
Source IPThe client's IP addressYesYes
LocationCountry, city, and subdivision based on source IP geolocationYesYes
Auth MethodRaw auth_method_used value: oidc (shown as SSO in the dashboard), password, pin, or header. For denied requests, carries the restriction code instead (e.g. ip_restricted, crowdsec_ban). Omitted from the API response when emptyYesRestriction code on denials
UserThe authenticated user's ID, set when oidc authentication was used. Omitted from the API response when emptyYesN/A
ReasonExactly 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 reasonsYesOmitted

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.
  • Denied requests: failed authentication or access restriction blocks show 401 or 403 status codes with reason set to Authentication failed. The specific cause (invalid password, missing SSO session, IP restricted, country restricted, CrowdSec verdict) is carried in auth_method_used, not in reason.
  • 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.

ReasonDescription
ip_restrictedThe client IP was blocked by a CIDR access restriction
country_restrictedThe client's country was blocked by a country access restriction
geo_unavailableCountry restrictions are configured but the GeoIP database is unavailable (fail-closed)
crowdsec_banThe client IP has a CrowdSec ban decision
crowdsec_captchaThe client IP has a CrowdSec captcha decision
crowdsec_throttleThe client IP has a CrowdSec throttle decision
crowdsec_unavailableCrowdSec 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.

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.

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:

{
    "ReverseProxy": {
        "AccessLogRetentionDays": 7,
        "AccessLogCleanupIntervalHours": 24
    }
}
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.