[GH-ISSUE #5413] Support for Internal Reverse Proxy using Custom DNS Zones #11171

Open
opened 2026-08-05 01:28:46 -04:00 by saavagebueno · 3 comments
Owner

Originally created by @freddyholms on GitHub (Feb 22, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5413

Is your feature request related to a problem? Please describe.
I am looking for a way to create short names for internal services (e.g., prox or dashboard.netbird.internal) that map directly to a specific IP and Port (e.g., 100.64.0.5:8080).

Currently, NetBird DNS Zones only handle Layer 3 (IP resolution), which requires me to append the port manually in the browser. While the new "Reverse Proxy" feature solves the port-mapping issue, it currently requires a public domain and Let's Encrypt certificate validation. This makes it impossible to use the Reverse Proxy for strictly internal, non-public domains or short names without installing a third-party proxy (like Caddy or Nginx) on the target peer.

Describe the solution you'd like
I would like the "Reverse Proxy" feature to support domains defined in "Custom DNS Zones."
Specifically:

The ability to select a "Custom DNS Zone" as the domain for a Reverse Proxy service.

An option to disable public SSL (Let's Encrypt) for these services, as they are intended for internal mesh traffic only.

The NetBird agent/management layer should automatically route traffic for http://shortname to the correct internal target IP and port defined in the Reverse Proxy config.

I would like a "Private Reverse Proxy" mode where the NetBird agent on the local machine intercepts requests for a DNS record and forwards it to the target peer's port, effectively acting as an internal ingress.

Describe alternatives you've considered

Manual Reverse Proxy: Installing Caddy/Nginx on every target peer. This adds management overhead and complexity.

DNS CNAME/A Records: This only points to the IP; I still have to type :8080 in the browser.

Current Reverse Proxy Feature: I tried setting a DNS zone equal to my proxy domain and adding prox as both a CNAME to that zone and as a service. This works from external devices via public DNS, but does not work for NetBird peers trying to resolve it internally without public exposure.

Additional context
This would allow users to have a "Headless" internal dashboard experience. Users could simply type http://prox/ in their browser, and NetBird would handle both the name resolution and the port redirection securely within the encrypted mesh, without ever needing to touch the public internet or public DNS records.

Originally created by @freddyholms on GitHub (Feb 22, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5413 **Is your feature request related to a problem? Please describe.** I am looking for a way to create short names for internal services (e.g., prox or dashboard.netbird.internal) that map directly to a specific IP and Port (e.g., 100.64.0.5:8080). Currently, NetBird DNS Zones only handle Layer 3 (IP resolution), which requires me to append the port manually in the browser. While the new "Reverse Proxy" feature solves the port-mapping issue, it currently requires a public domain and Let's Encrypt certificate validation. This makes it impossible to use the Reverse Proxy for strictly internal, non-public domains or short names without installing a third-party proxy (like Caddy or Nginx) on the target peer. **Describe the solution you'd like** I would like the "Reverse Proxy" feature to support domains defined in "Custom DNS Zones." Specifically: The ability to select a "Custom DNS Zone" as the domain for a Reverse Proxy service. An option to disable public SSL (Let's Encrypt) for these services, as they are intended for internal mesh traffic only. The NetBird agent/management layer should automatically route traffic for http://shortname to the correct internal target IP and port defined in the Reverse Proxy config. I would like a "Private Reverse Proxy" mode where the NetBird agent on the local machine intercepts requests for a DNS record and forwards it to the target peer's port, effectively acting as an internal ingress. **Describe alternatives you've considered** Manual Reverse Proxy: Installing Caddy/Nginx on every target peer. This adds management overhead and complexity. DNS CNAME/A Records: This only points to the IP; I still have to type :8080 in the browser. Current Reverse Proxy Feature: I tried setting a DNS zone equal to my proxy domain and adding prox as both a CNAME to that zone and as a service. This works from external devices via public DNS, but does not work for NetBird peers trying to resolve it internally without public exposure. **Additional context** This would allow users to have a "Headless" internal dashboard experience. Users could simply type http://prox/ in their browser, and NetBird would handle both the name resolution and the port redirection securely within the encrypted mesh, without ever needing to touch the public internet or public DNS records.
saavagebueno added the feature-request label 2026-08-05 01:28:46 -04:00
Author
Owner

@WolfspiritM commented on GitHub (Apr 13, 2026):

Having something like "internal services" is something I'm really missing aswell but I do have a slightly different usecase.
I have multiple independent networks with the same local subnet each having a peer and a local server running at e.g. 192.168.0.3.
Creating a Network for each doesn't work cause I can only have one 192.168.0.3 in the network.
It would be nice to instead be able to define a internal service on a peer which will create a new netbird IP and proxy traffic with that IP to the destination.

For example having:

  • Peer 1 (100.64.0.1) -> Internal Service "server-1" proxy port 22 to 192.168.0.3:22 -> Service IP: 100.64.1.1
  • Peer 2 (100.64.0.2) -> Internal Service "server-2" proxy port 22 to 192.168.0.3:22 -> Service IP: 100.64.1.2

server-1.svc.netbird.selfhost for example could resolve to 100.64.1.1

OPs usecase would then be another Internal Service e.g. "dashboard" that proxies port 80 to 127.0.0.1:8080.
A CNAME record in an internal DNS zone could then point for example to "dashboard.svc.netbird.selfhost".

An internal service could also have multiple port mappings similar to a docker container:
server-2.svc.netbird.selfhost (100.64.1.2):
100.64.1.2:22 (tcp) -> 192.168.0.3:22
100.64.1.2:80 (tcp) -> 127.0.0.1:8080

<!-- gh-comment-id:4239752284 --> @WolfspiritM commented on GitHub (Apr 13, 2026): Having something like "internal services" is something I'm really missing aswell but I do have a slightly different usecase. I have multiple independent networks with the same local subnet each having a peer and a local server running at e.g. 192.168.0.3. Creating a Network for each doesn't work cause I can only have one 192.168.0.3 in the network. It would be nice to instead be able to define a internal service on a peer which will create a new netbird IP and proxy traffic with that IP to the destination. For example having: - Peer 1 (100.64.0.1) -> Internal Service "server-1" proxy port 22 to 192.168.0.3:22 -> Service IP: 100.64.1.1 - Peer 2 (100.64.0.2) -> Internal Service "server-2" proxy port 22 to 192.168.0.3:22 -> Service IP: 100.64.1.2 server-1.svc.netbird.selfhost for example could resolve to 100.64.1.1 OPs usecase would then be another Internal Service e.g. "dashboard" that proxies port 80 to 127.0.0.1:8080. A CNAME record in an internal DNS zone could then point for example to "dashboard.svc.netbird.selfhost". An internal service could also have multiple port mappings similar to a docker container: server-2.svc.netbird.selfhost (100.64.1.2): 100.64.1.2:22 (tcp) -> 192.168.0.3:22 100.64.1.2:80 (tcp) -> 127.0.0.1:8080
Author
Owner

@akarabach commented on GitHub (May 18, 2026):

any updates on it ?

<!-- gh-comment-id:4478508558 --> @akarabach commented on GitHub (May 18, 2026): any updates on it ?
Author
Owner

@martasskv5 commented on GitHub (May 19, 2026):

I think this is not possible with the default built-in reverse proxy config, because it's listening on all interfaces. It's also not possible with DNS, because DNS doesn't care about ports; it just maps a name to an IP.

I achieved the "Internal Reverse Proxy" by binding the NetBird proxy to the interface facing the internet (the physical interface, e.g., eth0, enp0s3, or wlan0) and running another Traefik instance that only binds to the NetBird interface (wt0 on Linux). Then I created a new DNS zone for the internal domain martas.internal. This one has to be different from the NetBird DNS domain to avoid conflicts. I added a wildcard A record (*.martas.internal) pointing to the NetBird IP of the server running the proxy. This ensures all custom domains (e.g., dash.martas.internal) get resolved by Traefik. Traefik also handles ports, meaning you don't have to type dash.martas.internal:8080 — only dash.martas.internal.

I mostly use the reverse proxy with Docker containers, so I don't need to expose ports directly to the host, saving them when needed (probably never, but who knows). I have set up traefik-manager, which is a simple webpage, something like the NetBird dashboard.

Some services require HTTPS, but classic SSL providers like Let's Encrypt don't provide certificates for internal, local, lan, and other non-public TLDs. So I added smallstep Step-CA, which integrates well with Traefik. This required adding a new A record (ca.martas.internal) pointing to the server running the CA. Then I installed the generated root CA on all machines that have access to the proxy, and I haven't seen an insecure warning since.

My Docker Compose files:

I use this setup mostly with Docker containers that are in the same network as Traefik. To create proxy records for other devices in the NetBird network, Traefik must be able to communicate with them. Test with: docker exec -it traefik-internal ping {IP}.

<!-- gh-comment-id:4487073322 --> @martasskv5 commented on GitHub (May 19, 2026): I think this is not possible with the default built-in reverse proxy config, because **it's** listening on all interfaces. **It's** also not possible with DNS, because DNS **doesn't** care about ports; it just maps a name to an IP. I **achieved** the "Internal Reverse Proxy" by binding the NetBird proxy to the interface facing the internet (the physical interface, e.g., `eth0`, `enp0s3`, or `wlan0`) and running another Traefik instance that only binds to the NetBird interface (`wt0` on Linux). Then I created a new DNS zone for the internal domain `martas.internal`. This one has to be **different from** the NetBird DNS domain to avoid conflicts. I added a wildcard `A` record (`*.martas.internal`) pointing to the NetBird IP of the server running the proxy. This ensures all custom domains (e.g., `dash.martas.internal`) get resolved by Traefik. Traefik also **handles** ports, meaning you **don't** have to type `dash.martas.internal:8080` — only `dash.martas.internal`. I mostly use the reverse proxy with Docker containers, so I **don't** need to expose ports directly to the host, saving them when needed (probably never, but who knows). I **have set up** `traefik-manager`, which is a simple webpage, something like the NetBird dashboard. Some services require HTTPS, but classic SSL providers like Let's Encrypt **don't** provide certificates for `internal`, `local`, `lan`, and other non-public TLDs. So I added [smallstep Step-CA](https://smallstep.com/docs/step-ca/), which integrates well with Traefik. This required adding a new `A` record (`ca.martas.internal`) pointing to the server running the CA. Then I installed the generated root CA on all machines that have access to the proxy, and I **haven't** seen an **insecure** warning since. My Docker Compose files: - [internal-reverse-proxy](https://github.com/martasskv5/homelab/blob/main/docker/compose/internal-reverse-proxy/docker-compose.yml) - [step-ca](https://github.com/martasskv5/homelab/blob/main/docker/compose/step-ca/docker-compose.yml) I use this setup mostly with Docker containers that are in the same network as Traefik. To create proxy records for other **devices** in the NetBird network, Traefik must be able to communicate with them. Test with: `docker exec -it traefik-internal ping {IP}`.
Sign in to join this conversation.
No Label feature-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11171