[GH-ISSUE #6050] [Feature Request] Reverse Proxy: Support path prefix rewriting per target #12771

Open
opened 2026-08-05 02:06:39 -04:00 by saavagebueno · 0 comments
Owner

Originally created by @renne on GitHub (May 2, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/6050

Is your feature request related to a problem? Please describe.

The Reverse Proxy supports path-based routing — you can assign a path prefix (e.g. /ui) to a target so that only requests matching that prefix are forwarded to it. However, the path is forwarded to the backend as-is: a request to /ui/dashboard reaches the backend as /ui/dashboard.

Many real-world services expect to be served at / or at a different prefix than the one used on the public URL. Without path rewriting, these services either require reconfiguration to handle the prefix, or the integration is simply not possible.

Describe the solution you'd like

Add a "Rewrite Path" field on HTTP targets that controls how the incoming request path is transformed before being forwarded to the backend.

Two common rewrite modes cover most use cases:

Mode Example incoming path Configured match prefix Configured rewrite target Path sent to backend
Strip prefix /ui/dashboard /ui / /dashboard
Replace prefix /ui/dashboard /ui /app /app/dashboard

The simplest UI representation would be a single "Rewrite path to" text field on the target. When empty (default), no rewriting occurs and the current behaviour is preserved. When set, the matched prefix portion of the incoming path is replaced with the value in this field before forwarding.

Implementation sketch:

  • New optional field rewrite_path on the target proto/model (HTTP targets only)
  • In the proxy HTTP handler: after selecting the target by prefix match, strip the matched prefix from the request path and prepend rewrite_path before forwarding
  • UI: text input next to the existing "Path" field on the target editor, labelled "Rewrite to" (visible only for HTTP targets)

Use case examples:

  • Immich iOS app: Immich expects its API at /. Using the NetBird proxy to expose it under /photos breaks the app unless path stripping is available.
  • Grafana / Nextcloud / other apps with configurable root_url: Easier to configure a strip rule than to change the application's base URL setting.
  • Consolidating multiple services under one domain: Route /api → backend A at /, /ui → backend B at / without requiring each backend to be aware of the public path prefix.

Describe alternatives you've considered

  • Reconfigure the backend application to serve at the prefixed path (e.g. Grafana's GF_SERVER_ROOT_URL). Works per-app, but not all apps support this and it couples the app config to the proxy layout.
  • Put an Nginx/Traefik instance in front of the backend to strip the prefix before Netbird sees it. Adds an extra hop and defeats the point of a built-in proxy.

Additional context

Path-based routing was introduced in v0.65. The proxy already performs prefix matching to select a target; extending that to also rewrite the path before forwarding is a natural and low-risk extension of the existing logic. Redirect rewriting (Rewrite Redirects setting) already shows the proxy intercepts and mutates HTTP-layer data, so the plumbing for this kind of transformation is already present.

Originally created by @renne on GitHub (May 2, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/6050 **Is your feature request related to a problem? Please describe.** The Reverse Proxy supports path-based routing — you can assign a path prefix (e.g. `/ui`) to a target so that only requests matching that prefix are forwarded to it. However, the path is forwarded to the backend **as-is**: a request to `/ui/dashboard` reaches the backend as `/ui/dashboard`. Many real-world services expect to be served at `/` or at a different prefix than the one used on the public URL. Without path rewriting, these services either require reconfiguration to handle the prefix, or the integration is simply not possible. **Describe the solution you'd like** Add a **"Rewrite Path"** field on HTTP targets that controls how the incoming request path is transformed before being forwarded to the backend. Two common rewrite modes cover most use cases: | Mode | Example incoming path | Configured match prefix | Configured rewrite target | Path sent to backend | |---|---|---|---|---| | **Strip prefix** | `/ui/dashboard` | `/ui` | `/` | `/dashboard` | | **Replace prefix** | `/ui/dashboard` | `/ui` | `/app` | `/app/dashboard` | The simplest UI representation would be a single **"Rewrite path to"** text field on the target. When empty (default), no rewriting occurs and the current behaviour is preserved. When set, the matched prefix portion of the incoming path is replaced with the value in this field before forwarding. **Implementation sketch:** - New optional field `rewrite_path` on the target proto/model (HTTP targets only) - In the proxy HTTP handler: after selecting the target by prefix match, strip the matched prefix from the request path and prepend `rewrite_path` before forwarding - UI: text input next to the existing "Path" field on the target editor, labelled "Rewrite to" (visible only for HTTP targets) **Use case examples:** - **Immich iOS app:** Immich expects its API at `/`. Using the NetBird proxy to expose it under `/photos` breaks the app unless path stripping is available. - **Grafana / Nextcloud / other apps with configurable `root_url`:** Easier to configure a strip rule than to change the application's base URL setting. - **Consolidating multiple services under one domain:** Route `/api` → backend A at `/`, `/ui` → backend B at `/` without requiring each backend to be aware of the public path prefix. **Describe alternatives you've considered** - **Reconfigure the backend application** to serve at the prefixed path (e.g. Grafana's `GF_SERVER_ROOT_URL`). Works per-app, but not all apps support this and it couples the app config to the proxy layout. - **Put an Nginx/Traefik instance in front of the backend** to strip the prefix before Netbird sees it. Adds an extra hop and defeats the point of a built-in proxy. **Additional context** Path-based routing was introduced in v0.65. The proxy already performs prefix matching to select a target; extending that to also rewrite the path before forwarding is a natural and low-risk extension of the existing logic. Redirect rewriting (`Rewrite Redirects` setting) already shows the proxy intercepts and mutates HTTP-layer data, so the plumbing for this kind of transformation is already present.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#12771