Skip to content

[management]: Enhance relay and STUN service configuration logic#6715

Open
josark2005 wants to merge 7 commits into
netbirdio:mainfrom
josark2005:dev
Open

[management]: Enhance relay and STUN service configuration logic#6715
josark2005 wants to merge 7 commits into
netbirdio:mainfrom
josark2005:dev

Conversation

@josark2005

@josark2005 josark2005 commented Jul 10, 2026

Copy link
Copy Markdown

Describe your changes

Previously, setting server.relays.addresses unconditionally disabled the embedded relay and local STUN. This change allows the embedded relay to remain active alongside external relays when server.authSecret is set.

Changes

  • New predicate shouldStartEmbeddedRelay() — determines whether theembedded relay should start: requires authSecret to be set, and whenexternal relays are configured, authSecret must equal relays.secret

  • applyRelayDefaults() — uses the new predicate instead of a simple hasExternalRelay check; logs a warning when secrets mismatch; STUN is no longer disabled by external STUN config

  • autoConfigureClientSettings() — relay list: external and embedded addresses can coexist (embedded prepended for priority); STUN list: external and local STUN addresses can coexist (local appended)

  • config.yaml.example — comments updated to reflect the new behavior

Config behavior

authSecret relays relays.secret Embedded relay
empty any any off
set unset N/A on
set set == authSecret on
set set != authSecret off (warn)

STUN additive behavior

Previously, configuring server.stuns (external STUN servers) replaced the local STUN with the external ones. Now, external STUN addresses are sent to peers alongside local STUN addresses (configured via server.stunPorts). Local STUN is only advertised when the embedded relay is active (i.e., server.authSecret is set and matches relays.secret).

This means peers will receive more STUN candidates, improving NAT traversal success. Local STUN only starts when server.stunPorts is explicitly set (defaults to [3478]). To disable local STUN, set stunPorts to an empty list or simply omit the field:

server:
  stunPorts: []

Relay additive behavior

Previously, configuring server.relays.addresses (external relay servers) replaced the embedded relay entirely. Now, when server.authSecret is set and matches relays.secret, the embedded relay address is prepended to the external relay list sent to peers (embedded preferred for lower latency).

This means operators can add external relay capacity without losing their local relay. The embedded relay address is auto-detected from server.exposedAddress — no need to declare it in relays.addresses.

To use external relays without the embedded relay, simply omit server.authSecret:

server:
  # authSecret not set — embedded relay disabled
  relays:
    addresses:
      - "rels://relay.example.com:443"
    secret: "relay-secret"

Issue ticket number and link

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • This change does not modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — OR I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See CONTRIBUTING.md.

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

netbirdio/docs#845

Summary by CodeRabbit

  • New Features

    • Improved automatic configuration of embedded Relay, STUN, and signal settings.
    • Embedded Relay startup is now strictly controlled by the configured authentication secret, including when external relays are configured.
    • Embedded STUN is enabled whenever stunPorts are set, even alongside external STUN servers.
    • Client settings now prefer the embedded Relay address when applicable, while preserving external relay addresses when configured.
  • Documentation

    • Updated the example configuration to reflect the new conditional embedded Relay and STUN behavior.
  • Tests

    • Added unit tests covering embedded Relay enablement, address selection, STUN composition, and relay secret fallback.

dependabot Bot and others added 2 commits July 8, 2026 15:56
Bumps [github.com/pion/dtls/v3](https://github.com/pion/dtls) from 3.0.9 to 3.1.5.
- [Release notes](https://github.com/pion/dtls/releases)
- [Commits](pion/dtls@v3.0.9...v3.1.5)

---
updated-dependencies:
- dependency-name: github.com/pion/dtls/v3
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7fc5b271-acf2-4737-9e41-c8a28295dfd6

📥 Commits

Reviewing files that changed from the base of the PR and between 73129a0 and 6d37c21.

📒 Files selected for processing (1)
  • combined/cmd/config_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • combined/cmd/config_test.go

📝 Walkthrough

Walkthrough

ApplySimplifiedDefaults now gates embedded relay startup using authentication and external relay secrets, enables embedded STUN from configured ports, and auto-configures client relay/STUN settings accordingly. Tests and example configuration documentation cover the updated behavior.

Changes

Embedded service defaults

Layer / File(s) Summary
Service startup gating
combined/cmd/config.go, combined/cmd/config_test.go, combined/config.yaml.example
Default application delegates service setup through helpers, gates embedded relay startup on authentication and matching external relay secrets, enables embedded STUN from configured ports, and documents the revised conditions.
Client service auto-configuration
combined/cmd/config.go, combined/cmd/config_test.go
Client STUN settings use configured ports and embedded-service eligibility, while relay settings prefer the embedded address and fall back to external addresses or the authentication secret as appropriate.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ApplySimplifiedDefaults
  participant shouldStartEmbeddedRelay
  participant autoConfigureClientSettings
  ApplySimplifiedDefaults->>shouldStartEmbeddedRelay: evaluate authentication and external relay secret
  shouldStartEmbeddedRelay-->>ApplySimplifiedDefaults: embedded relay eligibility
  ApplySimplifiedDefaults->>autoConfigureClientSettings: configure client relay and STUN settings
  autoConfigureClientSettings-->>ApplySimplifiedDefaults: updated management addresses and secret
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main relay and STUN configuration change.
Description check ✅ Passed The description covers the change, behavior, tests, and docs, though the issue ticket/link and Stack sections are left empty.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@combined/config.yaml.example`:
- Line 12: Update the STUN-related comments at the referenced configuration
entries to state that configuring stunPorts keeps local STUN active only when
the embedded local relay is enabled, requiring authSecret and, with external
relays, a matching relays.secret; clarify that stuns enables external STUN and
may coexist with local STUN rather than implying exclusive use.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 27255987-3e01-4fc2-aba6-cb8d89fb6c01

📥 Commits

Reviewing files that changed from the base of the PR and between e0c25ba and d8ea04f.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • combined/cmd/config.go
  • combined/config.yaml.example
  • go.mod

Comment thread combined/config.yaml.example Outdated
@josark2005 josark2005 changed the title Dev [management]: Enhance relay and STUN service configuration logic Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@josark2005 josark2005 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem

When external relays are configured via server.relays.addresses, the
embedded relay is unconditionally shut down. This prevents operators who
want both their own local relay and external relays from using the
combined-server deployment — they must run a separate standalone relay
process instead.

Similarly, configuring external STUN servers via server.stuns disables
the local STUN server, even though the two are independent.

Solution

When server.authSecret is set, the embedded relay stays active. If
external relays are also configured, the embedded relay remains active
only when server.authSecret matches relays.secret (they must share
the same secret for unified token authentication). The embedded relay
address is auto-added to the peer relay list — no need to declare it in
relays.addresses.

Local STUN (configured via server.stunPorts) is no longer dependent on
external STUN config. When stunPorts is set, the local STUN server
starts and its address is sent to peers alongside any external STUN
addresses.

@CoderSufiyan CoderSufiyan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good direction but a few things to address before merging:

1. Missing tests
The config logic changed significantly - shouldStartEmbeddedRelay, the else if to if split in autoConfigureClientSettings, STUN becoming additive. Zero test coverage for any of this. Add test cases for: local + external relay coexistence, STUN additive behavior, authSecret mismatch disabling embedded relay, authSecret empty skipping embedded relay.

2. Unrelated dependency bumps
The pion/dtls/v3 and pion/transport/v4 bumps in this PR are unrelated to relay/STUN config. Move these to a separate PR or at minimum explain why they are needed for this change.

3. STUN additive behavior change
Previously else if meant external STUN replaced local. Now it is plain if so both are advertised. This is probably the right behavior but it should be documented in the PR description since it changes existing user-facing behavior.

Otherwise the direction looks good.

@josark2005 josark2005 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dependabot close

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@combined/cmd/config_test.go`:
- Around line 84-92: Update TestApplyRelayDefaults_StunEnabledWhenStunPortsSet
to also assert that c.Relay.Stun.Ports matches c.Server.StunPorts after
applyRelayDefaults, preserving the existing Enabled assertion.
- Around line 143-157: Extend
TestAutoConfigureClientSettings_StunAdditiveWithExternal to assert the local
STUN URIs at Management.Stuns indices 1 and 2, verifying they use
local.example.com with ports 3478 and 3479 respectively. Keep the existing count
and external-entry assertions unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8ea75e59-a5de-4d52-a28f-3b815298ee91

📥 Commits

Reviewing files that changed from the base of the PR and between 8d573a0 and 73129a0.

📒 Files selected for processing (2)
  • combined/cmd/config_test.go
  • combined/config.yaml.example
🚧 Files skipped from review as they are similar to previous changes (1)
  • combined/config.yaml.example

Comment thread combined/cmd/config_test.go
Comment thread combined/cmd/config_test.go
@sonarqubecloud

Copy link
Copy Markdown

@CoderSufiyan

CoderSufiyan commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

All concerns from my earlier review are addressed:

  • Added 14 test functions covering relay/STUN config logic
  • Removed dependency bumps
  • Additive STUN behavior clearly documented in code comments and config.yaml.example

The shouldStartEmbeddedRelay addition is clean. LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants