diff --git a/public/docs-static/img/manage/reverse-proxy/authentication/target-access-badges.png b/public/docs-static/img/manage/reverse-proxy/authentication/target-access-badges.png new file mode 100644 index 00000000..4e5f560d Binary files /dev/null and b/public/docs-static/img/manage/reverse-proxy/authentication/target-access-badges.png differ diff --git a/public/docs-static/img/manage/reverse-proxy/authentication/target-access-setting.png b/public/docs-static/img/manage/reverse-proxy/authentication/target-access-setting.png new file mode 100644 index 00000000..09394499 Binary files /dev/null and b/public/docs-static/img/manage/reverse-proxy/authentication/target-access-setting.png differ diff --git a/src/pages/manage/reverse-proxy/access-logs.mdx b/src/pages/manage/reverse-proxy/access-logs.mdx index bd412614..cd5c70f3 100644 --- a/src/pages/manage/reverse-proxy/access-logs.mdx +++ b/src/pages/manage/reverse-proxy/access-logs.mdx @@ -37,9 +37,10 @@ Every log entry (HTTP and L4) shares a common set of fields. Some fields are onl | **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`, or `header`. 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 | +| **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 @@ -47,8 +48,8 @@ Every log entry (HTTP and L4) shares a common set of fields. Some fields are onl 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`. +- **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 @@ -63,6 +64,7 @@ The following deny reasons identify why a connection was rejected. Note that for | 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) | diff --git a/src/pages/manage/reverse-proxy/authentication.mdx b/src/pages/manage/reverse-proxy/authentication.mdx index 64f086a9..15ec0c3a 100644 --- a/src/pages/manage/reverse-proxy/authentication.mdx +++ b/src/pages/manage/reverse-proxy/authentication.mdx @@ -1,11 +1,11 @@ import {Note, Warning} from "@/components/mdx" export const description = - 'Configure SSO, password, PIN, and header authentication methods, plus IP and country access restrictions, for NetBird Reverse Proxy services.' + 'Configure service authentication, per-target access actions, and IP, country, and reputation restrictions for NetBird Reverse Proxy services.' # Reverse Proxy Authentication and Access Restrictions -NetBird Reverse Proxy supports multiple authentication methods and connection-level access restrictions to control who can access your exposed services. You can enable one or more methods on each service, or leave a service completely public. Authentication and access restrictions are configured per service in the **Authentication** tab when creating or editing a service. +NetBird Reverse Proxy supports multiple authentication methods and connection-level access restrictions to control who can access your exposed services. You can enable one or more methods on each service, leave a service completely public, or choose a different authentication action for an individual HTTP target path. Authentication and access restrictions are configured when creating or editing a service.
@@ -175,6 +175,59 @@ Services can also be configured without any authentication. When no authenticati
**Best for:** Public-facing websites, APIs that handle their own authentication internally, or services that are intentionally open to the internet.
+## Per-target access actions
+
+HTTP targets can override the service authentication behavior for their matching path. Open or add a target, expand **Optional Settings**, and choose **Access**:
+
+| Action | Behavior |
+|--------|----------|
+| **Use service authentication** | Apply the authentication configured on the service. This is the default. |
+| **Bypass authentication** | Skip SSO, password, PIN, and header authentication for requests routed to this target. Service-level access restrictions still apply. |
+| **Block access** | Return `403` for requests routed to this target without contacting its backend. |
+
+
+
+
+
+
@@ -405,21 +407,21 @@ The proxy's main port always runs an SNI router that peeks at the TLS ClientHell
## Path-based routing
-When a service has multiple targets, you can assign each target a unique path prefix to route different URL paths to different backends. For example:
+When a service has multiple targets, you can assign each target a unique path prefix to route different URL paths to different backends. Each HTTP target can also choose what happens after its path matches:
-| Path | Target | Description |
-|------|--------|-------------|
-| `/` | Peer A (port 3000) | Main web application |
-| `/api` | Peer B (port 8080) | API service |
-| `/docs` | Resource C (port 80) | Documentation server |
+| Path | Target | Access | Example result |
+|------|--------|--------|----------------|
+| `/` | Peer A (port 3000) | Use service authentication | `/account` uses the authentication configured on the service |
+| `/public/` | Peer B (port 8080) | Bypass authentication | `/public/logo.svg` reaches Peer B without service authentication |
+| `/admin/` | Resource C (port 80) | Block access | `/admin/users` returns `403`; Resource C is not contacted |
-Incoming requests are matched against the configured path prefixes and forwarded to the corresponding target. Each path must be unique within a service.
+Incoming requests are matched against the configured path prefixes. When an enabled target uses **Bypass authentication** or **Block access**, all enabled target paths must be unique within the service. If more than one prefix matches, the **longest matching prefix** wins. In the example above, `/public/logo.svg` matches both `/` and `/public/`, so the `/public/` target and its access action are selected.
This is useful for consolidating multiple internal services under a single public domain, reducing the number of domains and TLS certificates you need to manage.
-Prefixes match the request path as text, not by path segment, so a target on `/api` also receives `/api-docs`. To match a whole segment, end the path with a slash: a target on `/api/` receives `/api/x`, but not `/api-docs` or `/api` itself.
+Prefix matching is literal and case-sensitive. Glob patterns such as `*` or `**` and regular expressions are not supported. Prefixes match the request path as text, not by path segment, so a target on `/api` also receives `/api-docs`. To match a whole segment, end the path with a slash: a target on `/api/` receives `/api/x`, but not `/api-docs` or `/api` itself. Likewise, `/Public/x` does not match `/public/`.
-By default, the matched prefix is removed before the request reaches the backend: `/api/x` arrives as `/x`, and `/api-docs` as `/-docs`. To keep the full path, turn on **Preserve Full Path** for the target (`path_rewrite: preserve` in the API).
+The access action does not change how paths are forwarded. By default, the matched prefix is removed before the request reaches the backend: `/api/x` arrives as `/x`, and `/api-docs` as `/-docs`. To keep the full path, use the existing **Preserve Full Path** target setting (`path_rewrite: preserve` in the API).
## Integration with Networks