[GH-ISSUE #5810] Feature Request: Expose peer LAN network addresses (Meta.NetworkAddresses) via GET /api/peers #11098

Open
opened 2026-08-05 01:28:28 -04:00 by saavagebueno · 1 comment
Owner

Originally created by @renne on GitHub (Apr 7, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5810

Originally assigned to: @jnfrati on GitHub.

External tools that configure subnet routes on local gateway hardware — for example a sidecar daemon that injects NetBird routes into a Fritz!Box via TR-064 — need the LAN IP address of a subnet-routing peer as the route's next-hop gateway.

Currently GET /api/peers returns only:

Field Value
ip Overlay mesh IP (100.x.x.x)
connection_ip WAN/public IP (from gRPC connection metadata)

Neither field is usable as a LAN next-hop. This forces operators to maintain a manual peer_id → LAN IP mapping in external tooling, which is error-prone and breaks silently when peers move or change.

Describe the solution you'd like

Expose Meta.NetworkAddresses in the GET /api/peers (and GET /api/peers/{id}) response.

The management server already collects and stores this data: the NetBird client reports all its network interfaces as part of PeerSystemMeta, which includes:

// management/server/peer/peer.go
type NetworkAddress struct {
    NetIP netip.Prefix  // LAN IP with CIDR, e.g. 192.168.178.5/24
    Mac   string
}

type PeerSystemMeta struct {
    // ...
    NetworkAddresses []NetworkAddress `gorm:"serializer:json"`
}

However, toSinglePeerResponse() and toPeerListItemResponse() in management/server/http/handlers/peers/peers_handler.go do not include NetworkAddresses in the API response object.

The proposed change is to add a new field to the Peer / PeerBatch API response types, e.g.:

{
  "id": "...",
  "ip": "100.x.x.x",
  "connection_ip": "...",
  "network_addresses": [
    { "net_ip": "192.168.178.5/24", "mac": "aa:bb:cc:dd:ee:ff" },
    { "net_ip": "10.0.0.5/8",       "mac": "..." }
  ]
}

External tools can then filter the list (e.g. by matching against the announced route CIDR from GET /api/routes) to determine the correct LAN interface IP without any manual configuration.

Describe alternatives you've considered

  • Manual peer → LAN IP mapping (current workaround): requires operators to maintain a static map in external config files. Breaks silently on IP changes.
  • Fritz!Box Hosts:1 DHCP lookup (AVM-specific): could resolve MAC → LAN IP from the router's DHCP table, but couples external tooling to AVM-specific TR-064 actions and only works as a workaround for missing upstream data.
  • connection_ip: This is the public WAN IP derived from the gRPC connection, not the LAN IP.

Additional context

  • Motivated by netbird-tr064, a daemon that injects NetBird subnet routes into Fritz!Box routers via TR-064 LANIPRoute:1. It currently requires a manual peers map in config.yaml (peer_id → LAN IP) for exactly this reason.
  • Related: #5801 (management server TR-064 integration feature request)
  • The data path already exists end-to-end: client → gRPC SyncResponsePeerSystemMeta → database. Only the HTTP serialization step is missing.
Originally created by @renne on GitHub (Apr 7, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5810 Originally assigned to: @jnfrati on GitHub. ### Is your feature request related to a problem? External tools that configure subnet routes on local gateway hardware — for example a sidecar daemon that injects NetBird routes into a Fritz!Box via TR-064 — need the **LAN IP address of a subnet-routing peer** as the route's next-hop gateway. Currently `GET /api/peers` returns only: | Field | Value | |---|---| | `ip` | Overlay mesh IP (100.x.x.x) | | `connection_ip` | WAN/public IP (from gRPC connection metadata) | Neither field is usable as a LAN next-hop. This forces operators to maintain a manual `peer_id → LAN IP` mapping in external tooling, which is error-prone and breaks silently when peers move or change. ### Describe the solution you'd like Expose `Meta.NetworkAddresses` in the `GET /api/peers` (and `GET /api/peers/{id}`) response. The management server **already collects and stores this data**: the NetBird client reports all its network interfaces as part of `PeerSystemMeta`, which includes: ```go // management/server/peer/peer.go type NetworkAddress struct { NetIP netip.Prefix // LAN IP with CIDR, e.g. 192.168.178.5/24 Mac string } type PeerSystemMeta struct { // ... NetworkAddresses []NetworkAddress `gorm:"serializer:json"` } ``` However, `toSinglePeerResponse()` and `toPeerListItemResponse()` in `management/server/http/handlers/peers/peers_handler.go` do **not** include `NetworkAddresses` in the API response object. The proposed change is to add a new field to the `Peer` / `PeerBatch` API response types, e.g.: ```json { "id": "...", "ip": "100.x.x.x", "connection_ip": "...", "network_addresses": [ { "net_ip": "192.168.178.5/24", "mac": "aa:bb:cc:dd:ee:ff" }, { "net_ip": "10.0.0.5/8", "mac": "..." } ] } ``` External tools can then filter the list (e.g. by matching against the announced route CIDR from `GET /api/routes`) to determine the correct LAN interface IP without any manual configuration. ### Describe alternatives you've considered - **Manual peer → LAN IP mapping** (current workaround): requires operators to maintain a static map in external config files. Breaks silently on IP changes. - **Fritz!Box `Hosts:1` DHCP lookup** (AVM-specific): could resolve MAC → LAN IP from the router's DHCP table, but couples external tooling to AVM-specific TR-064 actions and only works as a workaround for missing upstream data. - **`connection_ip`**: This is the public WAN IP derived from the gRPC connection, not the LAN IP. ### Additional context - Motivated by [netbird-tr064](https://github.com/renne/netbird-tr064), a daemon that injects NetBird subnet routes into Fritz!Box routers via TR-064 `LANIPRoute:1`. It currently requires a manual `peers` map in `config.yaml` (peer_id → LAN IP) for exactly this reason. - Related: #5801 (management server TR-064 integration feature request) - The data path already exists end-to-end: client → gRPC `SyncResponse` → `PeerSystemMeta` → database. Only the HTTP serialization step is missing.
saavagebueno added the enhancementfeature-requestwaiting-feedback labels 2026-08-05 01:28:28 -04:00
Author
Owner

@jnfrati commented on GitHub (Apr 7, 2026):

Hi @renne! Taking a look at this with the team, I'll get back at you later this week, otherwise feel free to tag me here early next week for an answer 👍

<!-- gh-comment-id:4197797032 --> @jnfrati commented on GitHub (Apr 7, 2026): Hi @renne! Taking a look at this with the team, I'll get back at you later this week, otherwise feel free to tag me here early next week for an answer 👍
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11098