Document that a primary nameserver is exclusive on Windows (#950)

* docs: document that a primary nameserver is exclusive on Windows

A peer with a primary nameserver now gets a Name Resolution Policy Table rule
covering every namespace, so all resolution goes through NetBird and nowhere
else. Without it Windows queries every adapter's resolvers in parallel and keeps
whichever answer arrives first, which leaks queries to the local network and lets
another resolver answer for a name NetBird is authoritative for.

Two consequences worth knowing before it surprises someone:

- Zones only the local network resolves stop working while connected, unless
  they are declared as match domains. A more specific rule takes precedence, so
  declaring the zone is the fix. `.local` is exempt, so multicast DNS is
  unaffected.
- Short names depend on which adapter's suffix Windows tries first, and it stops
  at the first "no such name" rather than continuing down the list. On
  domain-joined machines the machine's own domain wins that first attempt, so a
  short name can fail while its fully qualified form resolves.

Placed next to the existing macOS note in the same section, since both are about
what a primary nameserver does beyond catching unmatched queries, and next to the
existing warning about emptying match domains, which the suffix caveat explains
the other half of.

Also documents NB_USE_LEGACY_DNS_RESOLUTION, which restores the old behaviour on
a peer.

* docs: correct how Windows expands short names, and say from which version

Two fixes to the notes added in the previous commit.

The short-name mechanism was described wrongly. Windows does not stop at the
first suffix that misses: it walks the whole suffix list of the preferred
interface, and what it will not do is fall through to another interface's
suffixes. Measured on a Windows 11 machine — with NetBird's adapter preferred, a
list of {fritz.box, netbird.cloud} resolves a name that only exists under the
second entry; with the metric raised so the physical adapter wins, the same name
fails because only that adapter's single suffix is ever tried. The practical
advice changes with it: declaring the local zone with search domains enabled puts
both suffixes in one list, which is what makes short names work either way.

Both notes now say the exclusive behaviour arrives in client v0.78.0 and what
earlier clients did instead, so the page reads correctly for someone still on
0.77, and the environment variable is marked with the version that introduces it.

* docs: say that exclusive resolution is what breaks short names on Windows

The suffix-search behaviour is not Windows' own: without the catch-all NRPT
rule Windows keeps searching the other adapters' suffix lists, and the short
name resolves. Gate the note to v0.78.0 and point at it from the exclusivity
note, so both texts agree on what the change costs.
This commit is contained in:
Riccardo Manfrin
2026-09-04 11:43:16 +02:00
committed by GitHub
parent 46cb61ed6b
commit cb5813d1df
2 changed files with 15 additions and 0 deletions
@@ -100,6 +100,7 @@ sudo ip -6 rule del not from all fwmark 0x1bd00 lookup netbird priority 110
| `NB_DNS_FORWARDER_PORT` | All | Override the port the internal DNS forwarder binds to for handling DNS routes received from clients (default: `22054`). The forwarder is separate from the local resolver. |
| `NB_SKIP_DNS_PROBE` | All | Skip the startup check that sends a test query to the local resolver to verify it is reachable. Set this if the probe causes delays (e.g. in air-gapped networks). |
| `NB_DNS_LAZY_WARMUP_TIMEOUT` | All | Per-query budget for waking an idle peer when the local resolver returns one of its A or AAAA records (Go duration, default: `2s`). The value must be positive; invalid, zero, or negative values use the default. |
| `NB_USE_LEGACY_DNS_RESOLUTION` | Windows | Available from client v0.78.0. Go back to only setting the NetBird address as the tunnel adapter's nameserver, leaving Windows free to query the other adapters' resolvers in parallel. By default, a peer with a primary nameserver also gets a Name Resolution Policy Table rule that sends every query to the NetBird resolver and nowhere else. Set this if a zone that only the local network resolves has to stay reachable while connected and cannot be declared as a match domain — it also brings back the query leak and the non-deterministic resolution the rule prevents. |
| `NB_UNCLEAN_SHUTDOWN_RESOLV_FILE` | Linux, FreeBSD | Custom file path to store a backup of `/etc/resolv.conf` before the client modifies it. Used to restore the original on next startup if the client crashed without cleaning up (default: `<state-dir>/resolv.conf`, i.e. `/var/lib/netbird/resolv.conf` on Linux, `/var/db/netbird/resolv.conf` on FreeBSD). |
## Connection retry