* docs: unmanaged DNS mode also ignores Custom Zone records
A peer whose group is under DNS Settings -> Disable DNS Management (or
started with --disable-dns) never gets NetBird's resolver wired into the
OS, so Custom Zone records silently stop resolving along with
nameservers. The unmanaged-mode description, the Custom Zones
limitations list, and the DNS troubleshooting flow now say so, and the
troubleshooting page gains a confirm-managed-mode first check (the
existing --disable-dns isolation test reproduces this exact cause and
misreads as 'not NetBird DNS').
Also fixes the API Reference links to the canonical /api path (/ipa
redirects).
* docs: fix DNS API Reference link on the DNS landing page
* docs: explain macOS two-resolver-stack DNS behavior and the match-only vs primary nameserver split
Lab-validated against client 0.76.3 (macOS 26, NetBird Cloud):
- DNS troubleshooting: new Issue 5 'dig and host fail, but browsers and
curl work (macOS)' with the scoped-resolver vs resolv.conf explanation,
the language-runtime split table (pure-Go/dnspython/c-ares vs
getaddrinfo), and the Windows nslookup-vs-NRPT analog; renumbered
Issues 5-8 to 6-9; checklist step 6 now says why it prescribes
dscacheutil/Resolve-DnsName
- Internal DNS Servers: primary-vs-match now explains that match-only
leaves resolv.conf untouched on macOS; new warning that emptying a
match group's domains silently drops the search suffix (masked on
domain-joined Windows); split-horizon example gains the
route-everything-internal variant (the OpenVPN migration shape)
- DNS overview: macOS line now distinguishes scoped resolvers from the
primary case, where configd regenerates resolv.conf with NetBird's
resolver
* docs: add dashboard screenshot for the route-all-internal nameserver example
* docs: polish wording in the macOS DNS additions
* docs: promote the route-all-internal example to its own section
* docs: drop the Example prefix from the nameserver scenario headings
* docs: state the public-resolution prerequisite for an internal primary nameserver
* docs: make the direct-resolver check precise
* docs: anchor the scoped-resolver term to scutil output and split the dense solution paragraph
* docs: move MDM deployment guides under Manage > Peers
The five fleet-deployment guides (GPO, macOS .pkg, Jamf Pro, Kandji,
Intune) lived under Integrations, but nothing in them integrates with
NetBird's platform — they are peer onboarding at scale, which lives
under Peers. The label also collided with Access Control's
'Integrate MDM & EDR', which uses MDM in the opposite sense.
- Move pages from /manage/integrations/mdm-deployment/ to
/manage/peers/mdm-deployment/ with a permanent wildcard redirect
- Re-point legacy /how-to redirects directly at the new paths
- Move the nav group under Peers as 'MDM Deployment'; remove the
now-empty Integrations group
- Update internal links
* docs: link full GPO deployment guide from MDM integration page
* docs: show setup-key secret wiring and replica naming for k8s routing peers
Fold the two verified-novel bits from the Access Infrastructure
autoscaling tutorial before purging it:
- Replace the 'use a secret' Note with the actual kubectl create
secret + secretKeyRef wiring (matches what the NetBird operator
injects for routing peers)
- In the HA section, note that removing the static NB_HOSTNAME lets
each replica register under its pod name (client falls back to
os.Hostname(), which is the pod name in Kubernetes)
* docs: purge redundant Access Infrastructure tutorials
The four pages under Manage > Peers > Access Infrastructure were
2024-era SEO tutorials that duplicated canonical feature docs and
carried outdated claims (pre-rewrite SSH model without the built-in
SSH server, a Docker section that never actually enrolls the
container with a setup key, CrowdStrike presented as the only EDR
integration, stale v0.29 output and vintage-UI screenshots).
Cross-checked each page against its canonical counterpart; nothing
novel remained (the two useful Kubernetes snippets were folded into
the routing-peers use case in the previous commit).
- Delete the four pages and their screenshot directory
- Remove the Access Infrastructure nav group
- Redirect each URL to its canonical replacement:
secure-remote-webserver-access -> /manage/peers/ssh
setup-keys-add-servers-to-network -> /manage/peers/register-machines-using-setup-keys
access-internal-resources-from-autoscaled-environments -> /use-cases/kubernetes
peer-approval-for-remote-worker-access -> /manage/peers/approve-peers
- Re-point the legacy /how-to redirects at the same targets to avoid
redirect chains
* docs: reorder Peers nav into enrollment, approval, day-2 flow
Group the five enrollment methods first (Add Peers, Setup Keys,
Bootstrap via Config File, MDM Deployment, Browser Client), then the
Approve Peers admission gate, then running-peer features (SSH, Lazy
Connections, Remote Jobs) and Auto Update last. Approve Peers
previously sat between two enrollment pages.
* docs: cross-link DNS aliases and internal DNS pages, fix tutorial inaccuracies
The two pages solve adjacent problems (NetBird-hosted records vs
forwarding to existing internal DNS) but never pointed at each other.
Add a which-page-do-I-need Note to each.
Also fix defects in the DNS Aliases tutorial found while cross-checking
it against the Custom Zones reference and dashboard source:
- 'Keep this enabled' implied search domain is on by default; it is
off by default (DNSZoneModal.tsx: enable_search_domain ?? false)
- Step 3 said 'wildcard resource' but the steps add exact-name domain
resources
- Wrong alt text ('Delete DNS Zone') on the zone-config screenshot
- Add missing meta description and a link to the Custom Zones
reference
* docs: align MSP portal page with 2026 partner program, rename For Partners nav
Cross-checked the MSP portal page against the 2026 MSP/MSSP Partner
Program document:
- Point the application link at netbird.io/use-cases/msp (the program's
canonical page) instead of a demo-form URL displayed as netbird.io/msp
- State tenant plan options (Team or Business) and the post-trial
minimum (Team plan with one user)
- Mention CSV/PDF usage export alongside the API
- Clarify the 3-day trial for existing accounts brought in as tenants:
it is a window to subscribe the tenant under the MSP account
- Add a subtle msp@netbird.io contact line at the bottom
Also rename the For Partners nav entries by deliverable instead of
audience (the section header already says who it's for): MSP Portal,
Distributor Portal, Deploy with Acronis.
* docs: update CLAUDE.md for agent-network, proxy.js, and tooling gaps
Audited every claim against the current repo. Stack, routing, security,
and convention claims all still hold; four gaps had accumulated:
- Add agent-network/ to the content structure list
- Document src/proxy.js in URL Routing: /api data requests must be
rewritten there because the config rewrite loses data-request context
on client-side navigation (Next.js #39669) and strips pageProps
- Add npm run lint:mdx; note npm run gen requires a Go toolchain
- Note fenced mermaid code blocks render as diagrams
* docs: address review findings on PR #906
- Move the MDM deployment screenshot directories to match the new page
paths; the URL rewrite had updated MDX image references without
moving the assets, breaking all Intune/Jamf/Kandji images
- Normalize pre-existing double slashes in Jamf and Kandji image URLs
- Align the routing-peers secret example with bootstrap-via-config-file
(same secret name, so both now use the NB_SETUP_KEY data key)
- DNS aliases: include the routing peer's group in the zone's
distribution groups. Verified in client source: the DNS route
interceptor (priority 100) outranks local zone records (priority 75)
and never falls through, so clients forward routed-domain queries to
the routing peer, which must receive the zone to answer
The supported identity providers were a bullet list of links, so none of
them appeared in the "On this page" navigation. Make each one a
subsection heading with its setup link, and promote Generic SCIM to a
top-level section so it is a peer rather than a sub-item. Also fix a
typo (identify -> identity).
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* docs: masquerade-off HA is achievable, not impossible
Both the routing-peers page and the masquerade page stated that high
availability "stops working" with masquerade off. That reads as a flat
impossibility and loses a legitimate use case (source IP preservation for
audit, per-user database rules, or firewall policy keyed on the real source).
What is actually true is narrower: NetBird's half of the failover still
works, clients move to the standby peer on their own. What is missing is the
return route inside the destination network following that move. State the
condition instead of the impossibility, and add a short section on what
meeting it takes: distinct metrics so the active peer is the same for every
client, plus a virtual IP or a router-moved route so the next hop follows.
Both live outside NetBird, so the section names the pattern rather than
shipping a third-party config we would then own.
Also:
- Soften "failover is automatic and immediate". Clients re-select within
seconds, which is fast but not instant, and "immediate" invites a support
ticket from anyone who measures it. Phrased so it does not assert whether
the client or the management side detects the loss, which this change did
not verify.
- Warn against pointing the return route at both peers, as two static routes
or an equal-cost pair. It is the intuitive fix and it fails silently.
- Note that the second interruption on recovery cannot be avoided by pinning
the virtual IP to the standby, since the client's switch back is automatic.
Pinning the route while the client moves back strands the return path.
- The return route can live on the destination subnet's default gateway even
when the gateway and the routing peer share that subnet, which is the only
option when the destination host is not the customer's to configure. The
page previously offered the gateway only for a different-subnet
destination, and its persistent-config steps assume host access throughout.
* docs: health check must cross the path, not test the peer
A routing peer can stay enrolled and report healthy, with its WireGuard
interface present, while being unable to forward from the tunnel to the
destination subnet: a failed LAN interface, or a firewall change. Nothing
fails over in that state. NetBird sees a reachable peer, and a health check
that only looks for the interface sees a healthy one, so the return route
stays pointed at a peer that forwards nothing until someone intervenes.
Say that the check has to reach a destination through the tunnel.
* docs: held connections stall across a failover, they do not reset
Measured on a routing-peer pair with masquerade off: a held TCP connection
survives the switch. Four failovers, graceful shutdown and hard kill, all
showed the same signature — one round trip with multi-second latency, then the
same connection continuing with monotonic sequence numbers. No resets, and no
RST on the wire in any of them.
The reason is a property of masquerade being off: the addresses on the
connection do not change when another peer takes over, so the flow is portable
between peers, and the routed ACL accepts on addresses rather than on
connection state, so the standby forwards mid-stream packets it never saw a
handshake for.
Note this is specific to masquerade being off. The general high-availability
section still says established connections reset, which is the masquerade-on
default, where the standby would translate to a different source address.
Also trims the mechanism guidance to name the pattern rather than lean on any
one implementation, since which mechanism is right may change.
* docs: scope the reset claim to masquerade on, fix leftover contradiction
Review of the branch turned up three problems.
The Networks overview still said disabling masquerade 'breaks high
availability', one click from the page arguing it does not. Reworded to say it
makes high availability something you arrange rather than something you get.
Neither reset/stall sentence named its masquerade scope, so a reader with
masquerade off met both and they flatly disagreed. The general failover section
now scopes its reset claim to masquerade on, names the reason (the standby
translates to a different source address), and links onward.
'Stalls for the length of the failover' understated it. Measured stalls were 6
to 13 seconds against a 6 second failover, because the sender waits for its
next retransmit after the path returns. Says so, with the range, and keeps the
claim hedged to what was observed rather than asserting connections are never
broken.
* new: Windows GPO deployment guide under MDM for Deployment
* new: point GPO guide at the full policy key reference
* new: bold the example-posture disclaimer in GPO guide
* new: grammar and readability pass on GPO guide
* new: clarify AUTOSTART=0 vs Disable Autostart policy
* new: address review feedback on GPO guide install script and pinning
* Expand Issue 8 (NRPT lingering GPO) with GPO-hunt and source-side fixes
Enrich the Windows NRPT lingering-GPO troubleshooting with the deeper
diagnosis and remediation the issue needs: the DnsPolicyConfig registry
check, finding the responsible GPO (gpresult plus a SYSVOL registry.pol
scan), and the source-side fixes (the dummy-rule trick for an empty
lingering container, and guidance when a GPO carries real NRPT rules).
Heading and anchor are unchanged, so existing links keep resolving.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Replace em dash with a period in Issue 8 (house style)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Step 10 now asks customers to tell us which region their JumpCloud
console is in (US, EU, or India) along with the Client ID and Client
Secret, so the connector is configured against the right endpoint.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Reference the config-file bootstrap workflow from install and peer pages
Link Bootstrap peers via config file from the setup-key sections of the
Linux, Windows, macOS, and Docker install pages, from the Setup Keys
page, and from the Kubernetes routing-peers guide. The page was only
reachable from the sidebar, so this surfaces the unattended deployment
workflow where headless and at-scale enrollment is already discussed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Clarify the Kubernetes example demonstrates setup-key enrollment
The manifest passes a setup key but does not mount a pre-populated
config, so reword the cross-link: the example enrolls with a setup key,
and the bootstrap guide covers the additional config-file step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Clarify in "Step 3b: Configure access control" that access restrictions
of different types (IP CIDR, country, CrowdSec) are combined with a
logical AND by default: a connection must satisfy all of them.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Link the existing "WireGuard port conflict on Domain Controllers"
guidance (on /manage/dns/internal-dns-servers) from two pages a
troubleshooting-hub user could not previously reach it from:
- Windows client troubleshooting: a bullet under Windows DNS scenarios
for the "NetBird won't start on a DC" symptom.
- DNS troubleshooting: a note after the AD/DC issue, disambiguating the
client-running-on-the-DC case.
No content duplicated; both are pointers to the one existing section.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* docs: lazy connections are no longer experimental
Lazy connections have graduated from experimental status. Remove the
"experimental" framing from the feature guide, the zero-trust use case,
and the CLI flag reference.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* remove outdated routing peer limitation
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: add routing peer sizing guide
Add a Sizing Routing Peers page under Networks covering the four-step
sizing method, a per-peer capacity table, the tuning levers that matter,
and how to scale out by sharding load across identical Networks.
Cross-link it from How Routing Peers Work (HA note + related tile) and
the Networks overview, and add it to the docs navigation.
* docs: refine wording in routing peer sizing guide
Generalize the Acme example to remote users, correct the encrypt/decrypt
framing and reach the local network rather than the datacenter, use
'routing peer' instead of 'gateway', and rename the recap to Summary.
* docs: tighten and correct HA behavior in routing peer sizing guide
Correct the high-availability description: a single Network does not
balance load across its peers — different metrics give failover (one
peer carries all), equal metrics give latency-based nearest-peer
selection, which splits traffic by geography but never evenly. Shard
into more Networks to split load deterministically.
Also collapse redundant restatements, drop the secondary worked
example (the capacity table covers it), and slim the commodity-hardware
guidance.
* docs: add 1- and 2-vCPU rows to the routing peer capacity table
Extend the capacity table down to 1 and 2 vCPUs, drop the 'or more' from
the interface column, and adjust the methodology note so the interface
column reads uniformly as the minimum NIC to pair with each size.
* docs: add userspace WireGuard table and when-to-use cases
Add a userspace-mode capacity table showing wireguard-go does not scale
across cores (download plateaus ~6.8 Gbps, only ~4-5 cores used), and
the cases where a routing peer runs userspace: missing/broken/conflicting
kernel module, no TUN device (netstack, incl. rootless Docker), non-Linux
peers, and forcing userspace to capture policy IDs and blocked traffic
events. Name the exact benchmark CPU (Xeon Platinum 8375C).
* docs: replace 'sharding' with plain wording in sizing guide
Rename the Scaling out heading and reword the body, description, and
recap to talk about splitting load across more Networks instead of
sharding. Update the in-page anchor link to match the new heading.
* docs: clarify download/upload direction bullets in sizing guide
Lead each direction bullet with Download:/Upload: and say the routing
peer encrypts/decrypts, tying the pulling/pushing distinction to the
capacity table's column names.
* docs: replace 'shard' with plain wording in HA note
* docs: add jumbo frames section to routing peer sizing guide
* docs: align jumbo upload figure with capacity table, mark 16-vCPU line-rate as projection
* docs: use consistent numerals for MTU byte sizes
* docs: consolidate scenario guides under /use-cases with redirects
Move 11 pages: feature-nested use cases from manage/networks,
manage/network-routes, manage/reverse-proxy, and the Kubernetes
integration into /use-cases/remote-access, /use-cases/cloud, and
/use-cases/security; the site-to-site decision page becomes
/use-cases/remote-access; the MikroTik guide becomes an install
guide at /get-started/install/mikrotik.
Add one redirect per moved page and flatten existing redirect
chains so every legacy URL resolves in a single hop. The
deprecated Routes site-to-site recipe stays put.
* docs: rebuild sidebar navigation for use-cases reorg
Remove the four nested Use Cases sublists from Manage NetBird;
keep the deprecated Routes recipe as a direct 'Site-to-Site
(legacy)' link. Rebuild USE CASES with Remote Access, Cloud &
Kubernetes, Security groups and a flat Homelab link. Add MikroTik
to Get Started > Platforms.
* docs: rebuild use-case index pages and refresh feature landing links
Turn /use-cases into an "I want to..." scenario finder. Retitle
the site-to-site decision page to Remote Access and point its
links at the new sibling URLs. Add the Kubernetes service and
private-proxy guides to the cloud and security indexes, refresh
the homelab landing links, and update the Networks, Routes,
Reverse Proxy, and Kubernetes landing pages to the new use-case
URLs.
* docs: update internal links to new use-case URLs
Point cross-links across the docs at the consolidated
/use-cases URLs. Links to the deprecated Routes site-to-site
recipe and all image paths under public/docs-static are left
unchanged.
* docs: shorten sidebar label to Site-to-Site
* docs: move Kubernetes into its own Use Cases section
Pull the entire Kubernetes integration out of Manage > Integrations
into a dedicated Kubernetes group under Use Cases at /use-cases/
kubernetes, and move the two Kubernetes cloud guides there too.
Rename the Cloud group (was 'Cloud & Kubernetes'); Integrations
keeps the MDM deployment pages. Add redirects for every moved page
and flatten existing chains.
* docs: drop 'NetBird on' prefix from cloud sidebar labels
* docs: alphabetize Remote Access use cases in sidebar
* ❯ add mikrotik to install index
* docs: fix duplicated word in remote-access link label on TV install pages
---------
Co-authored-by: Brandon Hopkins <brandon@techhut.tv>
* docs: recommend Linux routing peers for file-share workloads
Add performance guidance to the Active Directory use case (Step 1
placement choice) and a performance trade-off note to Reach Services
on the Routing Peer: Windows/macOS peers process the data path in
userspace, and self-access delivery is slowest for reads, so a
dedicated Linux routing peer is the fast default for SMB/DFS.
* docs: platform-split the self-access performance note
Linux kernel-mode service hosts deliver to their own LAN IP at full
speed; the read-direction penalty is specific to Windows/macOS
userspace hosts.
* docs: scope the AD self-access caveat to Windows file servers
* docs: drop read-direction specifics from performance notes
The directional asymmetry is a suspected client defect under
engineering escalation, not durable documented behavior. Keep only
the kernel-vs-userspace guidance.
* docs: address review — dedupe performance guidance, fix note placement
- AD page: performance point stated once (Step 1 note, linking
how-routing-peers-work for the mechanism); bullets and recap trimmed;
Step 1 bullet now carries the Windows qualifier
- reach-services: note compressed to consequence + links, moved below
The scenario where LAN IP and the shape are defined
Document running a BYOP proxy in private mode with no public inbound
ports by disabling proxy ACME, issuing the wildcard TLS certificate
externally over DNS-01, and serving it as a static certificate that the
proxy hot-reloads on renewal.
Adds the page under reverse-proxy/use-cases with a new Use Cases nav
group, plus cross-links from the Bring Your Own Proxy page (port-443
prerequisite + TLS table) and the Reverse Proxy overview (static cert
mode).
* docs: add 'Choosing a pattern' overview to K8s getting started
Add a decision table and rules of thumb covering routing peer vs client
sidecar vs API server proxy vs Gateway API, so readers can pick the right
operator pattern. Clarifies that a sidecar (not a routing peer) is the
answer when a pod needs its own identity or to originate traffic onto the
overlay.
* docs: name the NetworkRouter CRD and clarify its DNS zone in the pattern table
* docs: add Highly Available Routing Peers use-case page (Kubernetes operator)
Add a standalone use-case page under a new Use Cases group in the Kubernetes
nav, covering how to run the operator's routing peers in HA: NetworkRouter
workloadOverride.replicas (default 3), the auto-created PodDisruptionBudget
(maxUnavailable: 1), equal-metric automatic failover, and spreading replicas
across failure domains via workloadOverride.podTemplate. Models least-privilege
(named destination group + access policy) rather than the All group.
* docs: add topology diagrams to HA routing peers page
Two SVG topology diagrams: replicas on a single node (single point of
failure) and replicas spread one-per-node via topologySpreadConstraints.
Embedded in Step 1 and the failure-domains section.
* docs: correct HA scheduling framing; drop single-node diagram
kube-scheduler spreads a Deployment's replicas across nodes by default
(best-effort, via built-in PodTopologySpread defaults). The earlier text/
diagram wrongly implied replicas co-locate by default. Reframe: multi-node
spread is the default; topologySpreadConstraints turns it into a guarantee
(or spans zones). Remove the single-node diagram (non-HA case, out of scope).
* docs: add Friendly DNS names appendix to HA routing peers page
Document exposing a service under a cleaner name via a CNAME in a custom
zone pointing at the operator's <service>.<namespace>.<zone> record (verified
end-to-end). Placed as an appendix for now; can move to a shared location later.
* docs: use ScheduleAnyway in spread example; note DoNotSchedule rollout deadlock
Multi-node verification: default scheduling already spreads replicas one-per-node;
the operator merges workloadOverride.podTemplate.topologySpreadConstraints into the
Deployment. DoNotSchedule with replicas == schedulable nodes deadlocks rolling updates
(surge pod can't place). Switch the example to ScheduleAnyway (verified clean rollout)
and document DoNotSchedule + the node-count/maxSurge caveat for a hard guarantee.
* docs: clarify custom-zone records are per-name (no whole-domain shadowing)
Verified on the lab: a NetBird custom zone serves only the records you add; other
names under the domain fall through to upstream DNS. Reusing a real internal domain
for friendly names is safe except for exact-name collisions.
* docs: expand into full 'Route to a Kubernetes service' how-to
Restructure the HA use-case page into an end-to-end guide covering the whole
journey: create the custom DNS zone, groups, and access policy (dashboard) ->
deploy HA routing peers (NetworkRouter, replicas:3) -> expose a Service
(NetworkResource) -> verify + failover. Generic, human-readable example names
(k8s.company.internal, kubernetes-clients/-services, network 'kubernetes',
nginx). Keeps the failure-domains diagram + ScheduleAnyway/DoNotSchedule note
and the friendly-DNS appendix. Adds <img> slots for 5 dashboard/terminal
screenshots (to be supplied). Renames the page + nav entry to
route-to-a-kubernetes-service; old slug removed.
* docs: add dashboard/terminal screenshots to the K8s how-to
Four screenshots (DNS zone, access policy, the kubernetes network with HA +
3 routing peers, kubectl pods-across-nodes). Drop the groups screenshot and
renumber the <img> refs to match.
* docs: swap in cleaner pods-across-nodes screenshot for Step 5
* docs: make node-spread central to the HA guide
Node-spread is the point of an HA guide, not a tail-end section. Move the
topology diagram up to 'What you'll achieve', fold the node-spread story into
Step 3 (deploy HA routing peers) - leading with the verified fact that the
scheduler spreads replicas across nodes by default (HA out of the box), with
topologySpreadConstraints as optional hardening - and drop the orphaned
'Spread across failure domains' section.
* docs: clarify the custom zone is created empty (operator fills the record)
Step 1 showed the auto-created A record without saying you don't enter it.
Note that you create only the zone (no hostname/IP/TTL by hand) and the
operator adds <service>.<namespace>.<zone> -> ClusterIP (5-min TTL) in Step 4.
* docs: replace Excalidraw topology with a custom dark-mode SVG
Hand-authored dark-background topology diagram (NetBird overlay -> routing
peers one-per-node -> Service) that matches the dark docs theme, replacing the
light Excalidraw-derived SVG. Removes the orphaned ha-routing-peers-spread-nodes.svg.
* docs: add CNAME dialog screenshot to the friendly-DNS appendix
Show the Add DNS Record dialog (CNAME 'app' -> nginx.default.k8s.company.internal)
and align the example hostname to 'app' to match.
* docs: drop maxSurge:0 workaround (not configurable via the operator)
The operator's workloadOverride only exposes annotations, labels, podTemplate,
and replicas — there is no hook for the Deployment's strategy.rollingUpdate.maxSurge.
Keep the achievable workaround (more schedulable nodes than replicas).
* docs: drop manual topology spread guidance (operator handles it by default)
* Restructure Troubleshooting into a hub with per-area pages
- Add a Troubleshooting hub (/help/troubleshooting) with icon/chip cards and a "Still stuck?" CTA
- Split NetBird Client troubleshooting into an overview + per-OS pages (Linux, Windows, macOS, Android, iOS)
- Split Self-hosted troubleshooting into an overview + per-area pages (installation, IdP, dashboard, certificates, connectivity, database)
- Split "Report bugs and issues" into Community Support and NetBird Support pages
- Add Troubleshooting resource connectivity and a NetBird Cloud pending-approval page
- Add DNS troubleshooting Issue 8 (Windows NRPT rule blocked by a lingering GPO)
- Cross-reference the new pages from networks, DNS, and reverse-proxy docs; update nav
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Address review: client terminology, dead props, labels, cross-links
- Use "client" instead of "agent" across the client troubleshooting pages (headings, prose, anchors)
- Remove unused source: props from the Troubleshooting hub tiles
- Relabel the "NetBird Cloud" grouping to "Cloud & identity" (SSO/provisioning also apply to self-hosted)
- Add a Tiles title on the report-bug landing; add reverse-proxy -> resource-connectivity cross-link
- Fix comma splices introduced by the em-dash cleanup in relayed-connections
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add client-side hash redirect for moved self-hosted anchors
Old deep links like /selfhosted/troubleshooting#debugging-turn-connections now
forward to the per-area page, since next.config redirects can't act on the URL fragment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Apply docs-skill review: conventions + reshape area pages
- "open source" (no hyphen), expand NRPT on first use, descriptive alt text + captions on TURN images
- Fix inherited "Netbird" casing in the client glossary
- Reshape the six self-hosted area pages to Symptom -> likely causes (ordered) -> Fix -> Confirm, preserving anchored headings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Fix two typos in client glossary (CodeRabbit)
- "nunning" -> "running" in the glossary
- possessive "it's" -> "its" in the routing-table sentence
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: fix two broken links in troubleshooting pages
- database: point the "upgrade path" link at /selfhosted/maintenance/upgrade;
selfhosted-quickstart has no #upgrade anchor so the old link landed at page top
- client: add HashRedirect so old #net-bird-agent-status deep links forward to
the renamed #net-bird-client-status section on the same page
* docs: address review follow-ups (deep-link redirects + client casing)
- self-hosted troubleshooting: extend the HashRedirect map with the per-issue
(###-level) anchors from the old single page, so old deep links land on the
exact sub-section of the new area page rather than just the page top
- client glossary: lowercase "NetBird client" in the peer-a/peer-b entries
(house convention) and fix "linux" -> "Linux"
* docs: review polish — fix image class + first-use acronym glosses
- connectivity: fix bad CSS class imagewrapper-nig -> imagewrapper on the
TURN-test screenshot (the typo'd class matched no style and broke zoom)
- gloss acronyms on first use: GPO (DNS Issue 8), IdP/SSO (identity-provider),
ACME (certificates), CORS (dashboard)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
* docs: add persistent-route guidance for clientless devices and align site-to-site on Networks
Step 5 of both site-to-site guides (and the masquerade page) now walk a
first-time admin through persisting a Linux static route end to end:
detect Netplan vs systemd-networkd with `ls /etc/netplan/`, then a clear
Option A / Option B that are framed as alternatives, with the exact
editing mechanics (open in nano, save/exit keys, or a one-paste
systemd-networkd drop-in). Standardize on the `<IFACE>` placeholder with
an `ip -br addr` hint so a literal `eth0` can't silently misconfigure
hosts using predictable interface names.
Update the site-to-site use-case hub to recommend Networks for all
non-exit-node scenarios, rename "Network Routes" to "Routes", and
reconcile the comparison section with the Routes deprecation.
* docs: promote Routes site-to-site recommendation to a deprecation warning
Move the 'use Networks instead' callout above the Architecture section
and make it a Warning, matching the Routes deprecation. Keep the legacy
no-Policy nuance and the Site-to-VPN pointer; rename Network Routes to Routes.
* docs: correct Networks scenario support and mark Routes deprecated
- advanced-configuration: Networks supports all scenarios (VPN-to-Site,
Site-to-VPN, Site-to-Site), not VPN-to-Site only
- how-routing-peers-work: Routes labeled deprecated, not 'still supported'
* docs: import Note explicitly in site-to-site use-case page
Addresses CodeRabbit: <Note> was used without an explicit import from
@/components/mdx, relying on the global MDX provider.
* docs: repoint site-to-site cross-links to Networks
Site-to-site moved to Networks; update the homelab and cloud use-case
tiles/table and the access-home-devices and cloud-to-on-premise Next
Steps links to /manage/networks/use-cases/site-to-site.
* docs: rename Network Routes to Routes in prose and repoint advanced-config links
Bucket A rename (display text only): rename the 'Network Routes' feature
name to 'Routes' across prose, link labels, table cells, alt text, Tiles
names, and code comments. Headings are deliberately left unchanged to
avoid breaking anchors and inbound links; URL paths (/manage/network-routes)
are unchanged. Generic routing-table mentions and the desktop system-tray
UI label are left as-is.
Also repoint the access-home-devices and cloud-to-on-premise 'Advanced
configuration' Next Steps links from the Routes advanced-config page to
/manage/networks/masquerade.
* Update site-to-site documentation for clarity
Removed outdated information about using Routes for site-to-site connections.
* Update src/pages/manage/networks/use-cases/site-to-site.mdx
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update section title from 'Networks vs Network Routes' to 'Networks vs Routes'
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* docs: add routing-peer self-access and Active Directory guides
New use-case guides: reaching a service on a routing peer's own LAN IP
(route + peer-to-peer policy + NB_ENABLE_LOCAL_FORWARDING) and an
end-to-end Active Directory / Windows file shares guide over NetBird.
Clarify domain-resource DNS: with Routing Peer DNS Resolution on, the
routing peer answers the client's A/AAAA lookups (a domain resource
matches the exact name; use a wildcard for hostnames under a domain),
but AD still needs a nameserver group for the SRV/DC-locator records.
Add navigation entries, overlay-vs-LAN-IP notes, and ICMP/ping
troubleshooting guidance.
* docs: fix WireGuard anchor slug and sharpen local-forwarding caution
The #why-wireguard-with-netbird anchor doesn't resolve — the heading
slugifies to #why-wire-guard-with-net-bird (decamelized). Fix it in the
networks intro and the netbird-vs-traditional-vpn self-link.
Clarify the NB_ENABLE_LOCAL_FORWARDING caution: with it on, any permitted
peer can reach services bound to the routing peer's own addresses,
including 127.0.0.1, at the peer's NetBird IP.
* docs: polish routing-peer and Active Directory guides
- Correct the DC policy note: TCP/UDP need separate policies because a
policy carries one protocol, not because of a first-rule limitation
- Make internal-dns-servers the canonical A/AAAA-vs-SRV explanation;
collapse the three duplicates to one-line pointers
- Trim emphatic bold to enumerated requirements, ports, and flags
- Reduce em-dash density and clarify the routing-peer SSH-management
and HA cautions in the AD guide
* docs: make Active Directory guide clearer for junior admins
- Rewrite the Verify section to explain why (test as the signed-in
domain user, port 445 vs ping, name vs IP) instead of assuming
ICMP/Kerberos/NTLM knowledge
- Clarify the SSH-management and HA cautions in Step 3
- Note Get-DfsnFolderTarget needs the DFS Management tools (RSAT),
not just any domain-joined machine
- Reduce em-dash density throughout
* docs: Routing Peer DNS Resolution applies to all domain resources, not just wildcards
* docs: refine Active Directory guide and nameserver terminology
- Step 3 DC ports as a Port/Protocol/Needed-for table; promote 123
(time sync) and 464 (kpasswd) into the baseline
- DFS step: derive each target server's FQDN for the domain resource
- order the agent-placement and reachability shapes consistently
(dedicated routing peer first)
- drop the niche SSH-wedge caution and the premature masquerade note
- tie the ping/ICMP caveat to the port-scoped policies
- use "Nameserver" + "match domain" (the UI term) instead of
"nameserver group" across the AD, internal-DNS, and reach-services pages
* docs: scope the local-forwarding caution — loopback exposure is netstack-only
Reaching the routing peer's own 127.0.0.1-bound services via its NetBird IP
only happens on netstack-mode peers; on userspace-TUN (Windows/macOS) it does
not (verified), and Linux kernel mode is a no-op. The general "exposes own
addresses" caution stands; drop the over-broad 127.0.0.1/localhost specifics.
* docs: trim DC-through-routing-peer section to the DNS-only reason and reorder AD subsections
Drop the setup-flavored framing from 'Reaching a Domain Controller
through a routing peer' (it lives on the AD use-case page), keeping the
DNS reference fact: A/AAAA resolves on the routing peer but SRV/DC-locator
records don't, so AD still needs a nameserver to the DC. Heading text is
unchanged so the existing anchor still resolves. Reorder the AD & Domain
Controllers subsections to lead with the recommended case (reach the DC
through a separate routing peer), then the discouraged DC-as-routing-peer
path, then its WireGuard port-conflict troubleshooting.
* docs: drop redundant cross-link from AD Step 4 nameserver note
The note already explains why a domain resource doesn't remove the
nameserver requirement (SRV/DC-locator records). The trailing link to the
DNS page's 'Reaching a Domain Controller through a routing peer' section
just repeated that fact and linked back here, bouncing the reader. Step 4
already links to Internal DNS Servers for the general setup.
* docs: restructure AD routing-peer guidance — least-privilege tiers, DC route/policy split, de-loop cross-links
Active Directory & Windows File Shares:
- Add a TL;DR linking to a new 'The four settings' checklist at the bottom.
- Split Step 3 into Step 3 (route the DC) and Step 4 (allow the AD ports);
DNS becomes Step 5. Keeps the route distinct from the access policies.
- Step 2: break each routing-peer case into sub-bullets of what's needed;
point the self-access case to Reach Services on the Routing Peer.
- Step 3: present /32 or apex domain as the granular default and the
*.corp.example.com wildcard as the least-privilege opt-in — and spell out
the wildcard's one-policy-scope cost (uniform ports across the whole domain).
Reach Services on the Routing Peer:
- Tighten the setup steps; concrete DNS-nameserver instruction for AD/DFS;
state the Linux kernel-mode default for NB_ENABLE_LOCAL_FORWARDING.
- 'recipe' -> 'setup' throughout.
Internal DNS Servers:
- Clarify nameserver vs plain share: A/AAAA via the routing peer needs no
nameserver; AD needs one for SRV records and because the resolver won't
fall back. Distribute the nameserver to the routing peer's group *and*
client groups that resolve directly; only when the peer can't resolve on
its own. Reorder AD subsections; fix the overbroad distribution note.
How Routing Peers Work / cross-links:
- Remove redundant/circular cross-links across the four pages (the
HRPW -> Internal DNS -> Active Directory -> HRPW loop).
* docs: use "NetBird client"/"clientless" wording in AD and self-access guides
Replace 'the agent'/'agentless' with the preferred 'NetBird client'/'clientless' terms, and add the missing blank line before the Step 2 heading.
* docs: lower altitude of routing-peer/AD guides for junior admins
- Unify the overlay address as 'NetBird IP' and the local one as 'LAN IP' across the routing-peer/DNS pages; add a 2-line two-address primer to the two crux pages.
- Replace the dense userspace/netstack/kernel forwarding sentence with a platform table framed to the self-access case, plus a netstack-override footnote.
- Demote the wildcard policy-scope trade-off in the AD guide to a Note, keeping the granular-first nudge in the main flow.
- Split the 'Reaching a DC through a routing peer' paragraph into what-it-needs / why-a-domain-resource-isn't-enough bullets.
- De-duplicate the self-access section: it now owns the mental model and points to the use-case page for the concrete setup.
* docs: clarify the forwarding section for junior admins
- Disambiguate NB_ENABLE_LOCAL_FORWARDING from the IP-forwarding sysctl by naming the setting explicitly before the table.
- Split local forwarding into its own '### Local forwarding' subheading, distinct from '### IP forwarding'; repoint the #local-forwarding cross-link.
- Drop the netstack-specific override footnote — edge-case reference material that doesn't help the target reader (the row already names the correct flag).
* docs: apply review feedback to routing-peer/AD guides
- AD Step 4: list the AD ports per TCP/UDP access control policy instead of a dense one-rule-per-policy sentence; add 123 to the four-settings recap.
- De-duplicate the route+policy+local-forwarding triad within how-routing-peers-work (Local forwarding now points to the canonical statement); render the LAN-IP requirements as a sub-list.
- Plain-language rewrite of why a domain resource isn't enough for AD DNS.
- Qualify Global Catalog 3268/3269 to multi-domain forests; state the default branch in AD Step 1.
- Fix the Networks Tiles description to say 'NetBird client', not 'agent'.
- Add DNS troubleshooting Issue 7 for the AD symptom (login/DFS fails but file-by-IP works), cross-linked to the AD guide and the DC section.
* docs: recast AD "four settings" as an explicit NetBird config checklist
Rename the summary to 'What you configure in NetBird' and list the discrete NetBird objects: routing peer, a route (resource) to the file server and to the DC, separate access control policies for each, and a DNS nameserver. Keep the full AD port set in Step 4 only; update the TL;DR link to the new (decamelized) anchor.
* docs: clarify the self-access setup steps
- Identify NB_ENABLE_LOCAL_FORWARDING as an environment variable and link the Client Environment Variables reference.
- Front-load the platform on step 3 (Windows/macOS need the flag; Linux kernel forwarding doesn't, only netstack) and soften the 'all three required' framing accordingly.
- Explain that steps 1 and 3 exist only because clients reach the file server at its LAN IP; reaching a peer at its NetBird IP needs only the policy.
* docs: rename Network Routes to Routes, deprecate, and relocate Browser Client Architecture
- Rename the docs sidebar entry "Network Routes" to "Routes" and the page H1
- Add a deprecation note to the Routes page: all use cases except exit nodes
have moved to Networks; reconcile the body framing accordingly
- Move Browser Client Architecture under Peers > Browser Client
(/manage/peers/browser-client/architecture), nest the nav, add a redirect,
and update cross-links
- Shrink the site-to-site Architecture diagram boxes to fit their content
* docs: rename Routes nav 'Concept' link to 'Overview'
Create a standalone User Roles reference covering all six roles (Owner,
Admin, Network Admin, Billing Admin, Auditor, User) with a permission
matrix aligned to the current dashboard, per-role sections, API/token
notes, and role-assignment steps.
Reduce the role section on the Add Users page to a pointer (keeping the
existing anchor), repoint inbound links from delete-account,
control-center, and msp-portal, add the page to the Team sidebar, and
refresh the role screenshots.
* bulk text edit to fit new flows
* Updated screenshots, some minor docs fix. (#782)
* Update Settings on site-to-site.mdx
* fix image names and embedded links
* Update high level dia
* general dashboard images and auto-update stucture fix
* remove temp audit file
---------
Co-authored-by: PizzaLovingNerd <cameron@stillhq.io>
* docs: rewrite Networks page as a teaching guide
Rework /manage/networks from a reference-style concept page into a
structured teaching guide: mental model, the four building blocks
(Network, Resource, Access policy, Routing peer), how a packet reaches
a resource, and an end-to-end walkthrough for reaching two internal
apps with Zero Trust access by default.
- Add a production checklist (HA, monitoring, masquerade, internal DNS,
routing-peer access) and a clear "Networks or Network Routes?" split:
Networks now covers every remote-access scenario except exit nodes.
- Add worked-example and resource-list screenshots.
- how-routing-peers-work: point site-to-site at Networks, describe
Routing Peer DNS Resolution as on by default, and restore the
0.59.x domain-resolution compatibility note.
- Rename the sidebar entry from "Concept" to "Overview".
* image organization into /networks dir
* fix embedded images in networks/index.mdx
* docs: note no inbound ports and Linux-only masquerade on Networks page
---------
Co-authored-by: TechHutTV <brandon@techhut.tv>
* docs: add Networks site-to-site use-case guide
Add a canonical site-to-site guide built on Networks/Resources/Policies,
which is the recommended and actively developed approach. Reposition the
legacy Network Routes site-to-site Note to point at the new page and scope
Network Routes to the wide-open, no-policy case only. Add the new page to
the docs sidebar under Networks > Use Cases.
* docs: fix Resource fields, policy heading, and prerequisites in Networks site-to-site
- Remove non-existent 'Type: Subnet' field; describe Resource Groups under
Additional Options to match the actual UI
- Rename Step 4 to 'Create access control policies'
- Trim prerequisites (drop account line and device examples)
* docs: clarify Masquerade requirement and Linux-only SNAT for site-to-site
Add a 'When Posture Checks Are Evaluated' section to the posture checks
page covering connect/login evaluation, immediate distribution of changes,
and the connection-time evaluation caveat for mid-session state changes.
Add a 'How Policy Changes Are Distributed' section to the access control
overview covering event-driven push, no redistribution interval, and
change coalescing. The two sections cross-link.
Answers common customer questions about the Entra ID API to SCIM
migration that the public docs did not cover:
- One-integration-at-a-time limit and tenant-separation workaround
- Reusing an existing Enterprise Application for SCIM vs. the legacy
API App Registration
- Why the group externalId mapping is removed (displayName matching)
- Why unused user attribute mappings are trimmed
- Why externalId source changes from mailNickname to objectId
- New Sync Behavior section contrasting 5-min API polling with
event-driven SCIM provisioning
* fix: replace invalid <p> wrapping Button with <div>
The Button component renders a <div> in its primary variant. HTML
disallows block elements inside <p>, so browsers auto-close the <p>
during parsing and React 19 reports a hydration mismatch. The
float="center" attribute was non-functional, so rendering is unchanged.
* chore: gitignore .playwright-mcp run artifacts
* Update BYOP documentation to reflect "Clusters" terminology and add shared vs account cluster details.
* Update BYOP DNS documentation and replace modal images
* docs: add Masquerade configuration page
Documents persistent return-route setup on the destination host when
masquerade is disabled on a routing peer. Covers Netplan, systemd-networkd,
NetworkManager, ifupdown, and RHEL legacy network-scripts, plus verification
and a security note. Resolves the previously dangling "Related" tile in
how-routing-peers-work.mdx.
* docs: clarify masquerade page and trim persistent recipes
- Netplan: show as a fragment with addresses/default route context so readers
don't paste it as a standalone file
- systemd-networkd: note the drop-in needs a matching .network file and
point at networkctl status to find it
- Test section: add ping/curl reachability examples
- Verify section: call out that proto/onlink/metric fields are normal
- Remove NetworkManager, ifupdown, and RHEL legacy sections
* docs: clarify netplan section when /etc/netplan is empty
Lead with the common case (cloud-init / installer yaml already exists),
and call out the placeholders in the example. Add a fallback path for
the rare case where /etc/netplan/ is empty.
* docs: comment <IFACE> placeholder in netplan example
* docs: clarify <IFACE> is the destination's LAN interface
* docs: comment <PEER_LAN_IP> placeholder in netplan example
* docs: tighten <PEER_LAN_IP> comment to 'local IP on this subnet'
* docs: make 'pick one' explicit for the persistent-config methods
Replace the weak one-liner with a bold "pick one" callout and a
two-bullet decision criterion (ls /etc/netplan/) so readers don't
mistake the two H3 sections for sequential steps.
* docs: add 'Find your account's NetBird range' to the masquerade page
Mirror the section already on the site-to-vpn page so readers learn to
use their account's /16 block rather than pinning the whole /10. Same
prose and netbird status recipe; trailing line adapted to reference
100.64.0.0/10 (the placeholder used elsewhere on this page).
* docs: remove 'Related' Tiles block from masquerade page
* docs: align security warning with the recommended /16 range
* docs: restore cross-link from advanced-configuration to masquerade
* docs: drop ping from the test-route example
ping would fail for ACL reasons (not routing reasons) on policies
scoped to specific TCP ports, misdirecting troubleshooting. Use curl or
nc against an allowed port instead.
* docs: apply review findings to masquerade page and legacy warning
masquerade.mdx
- add "Disable masquerade on the routing peer" section (dashboard +
API path), so the page actually documents the toggle, not just
the prerequisite
- "What changes when masquerade is off": say the route lives on the
destination host (or its gateway for multi-hop)
- forward-ref "Find your account's NetBird range" from the inputs
list to remove the substitute-then-rewind loop
- ip route del: include via <PEER_LAN_IP> so the test takedown is
unambiguous
- netplan prose: spell out that you append to the existing routes:
list, not add a second routes: key (YAML rejects that)
- verify output: use 192.168.1.10 for the routing peer so it stops
colliding with the 192.168.1.50 used as the destination's own IP
in the netplan example
- add an end-to-end verification step (curl + tcpdump) so a reader
confirms source IPs are actually preserved, not just that a route
exists in the table
advanced-configuration.mdx
- rewrite the contradictory Warning so it scopes correctly to legacy
Network Routes (which match peer NetBird IPs only) and points
readers to the Networks path when they want policy-layer ACLs
with masquerade off
* docs: promote the /16 substitution reminder to a Note callout
* docs: clearer wording for the /16 substitution Note
The agent already enables ip_forward inside the container's own network
namespace when it has NET_ADMIN, so the blanket claim that a container
cannot do this on its own is misleading. The preceding paragraph
already covers the fallback case when the agent cannot modify sysctl.
* docs: rewrite Site-to-VPN SNAT requirement to always be manual
The dashboard Masquerade flag does not cover the Site-to-VPN direction on
any route — the marking rules NetBird installs are only wired up when a
policy targets the resource, and the documented flow uses a peer-to-peer
policy. The old guidance ("on Linux kernel mode, no manual SNAT needed")
was wrong, so manual SNAT is now framed as required on every routing peer
regardless of OS or WireGuard mode.
Also adds an nftables example alongside the iptables one, drops the
"(If applicable)" qualifier from the Step 3 heading, fixes the four
in-page anchor links that were already 404ing against the old heading,
and reframes the Step 4 masquerade-flag note plus the Outbound SNAT
requirement and Troubleshooting sections to match.
Verified end-to-end in a kernel-mode Linux lab: with the documented setup
(masquerade=true, peer-to-peer policy only, no manual SNAT) curl from a
clientless device to the overlay peer's NetBird IP times out; adding
either the iptables or the nftables rule from the new Step 3 makes it
return HTTP 200.
* docs: make Step 3 SNAT examples persistent
The previous version showed runtime iptables/nft commands with
persistence as a trailing comment. Replace with two equivalent
fully-persistent options: iptables-persistent (recommended) and a
dedicated systemd-unit + /etc/nftables.d/ file for nftables-native
setups.
Explicitly call out why /etc/nftables.conf is not the right persistence
target — its default starts with "flush ruleset", which wipes the
iptables-nft chains NetBird installs.
Both options verified end-to-end in a lab: rule applied, curl succeeds;
rule removed (simulating reboot), curl fails; reload via
netfilter-persistent / systemctl restart, curl succeeds again.
* docs: drop nftables-only option from Step 3
iptables-persistent works on every Linux NetBird supports — whether the
underlying backend is iptables-legacy or iptables-nft — so a separate
nftables variant with its own systemd unit was strictly more complexity
for the same outcome. Keep the iptables-persistent block as the single
Linux instruction.
* docs: drop UFW/firewalld FORWARD caveat from Step 3
The note was scoped to a minority of routing peers (those running UFW or
firewalld with default-DROP on FORWARD), and the persistence guidance
was too vague to be actionable. The symptom — packets reaching the
routing peer but not the target — is already covered by the
Troubleshooting section, which is enough of a lead for affected users.
* docs: drop standalone Outbound SNAT requirement section
The section's three takeaways — ACL ipset rejects routed-CIDR sources,
SNAT rewrites the source to a known NetBird IP, dashboard Masquerade
flag doesn't cover this direction — are already covered inline in Step
3 and the Step 4 masquerade note. Fold the one unique bit (the ipset
mechanic) into Step 3's opening sentence and drop the standalone
section plus the three "see Outbound SNAT requirement" backreferences
that pointed at it.
* docs: use ss -tan in Test Connectivity verification
The previous command (ss -tnp | grep :8080) filters by process and
misses TIME-WAIT sockets, which are kernel-owned. After a fast curl the
TCP connection closes before ss runs, so the user only ever sees the
LISTEN socket — no indication of the source IP. ss -tan lists all
states, so the TIME-WAIT entry showing the routing peer's NetBird IP as
the remote address is reliably visible for ~60 s.
Verified end-to-end in a kernel-mode Linux lab.
* docs: make Linux static route in Step 6 persistent
Replace the runtime "ip route add" + persistence-as-a-comment with two
fully-persistent options: a netplan drop-in (Ubuntu Server default) and
an nmcli equivalent (RHEL / Fedora / desktop). The netplan YAML was
validated against netplan generate. Also annotate the Windows command
to highlight that "-p" is what makes it persistent.
* docs: drop unverified pfSense/OPNsense and MikroTik examples
Neither platform ships a first-class NetBird routing-peer setup, and we
have no way to verify the SNAT commands in those sections work as
written. Replace with a single "Other platforms" paragraph that points
back to the general principle (any SNAT that rewrites the site-CIDR
source on egress from wt0 is sufficient) without claiming to give
verified instructions. Also tighten the Prerequisites line that
referenced "per-platform SNAT syntax" that no longer exists.
* docs: rewrite DNS NXDOMAIN troubleshooting entry
The previous entry referenced a "127.0.0.1-co-located NetBird resolver"
that doesn't exist — the doc's own DNS section explicitly notes that
the NetBird daemon binds its resolver on the peer's own NetBird IP,
not on 127.0.0.1. The "binding loopback causes it to refuse forwarding"
explanation was therefore exactly backwards.
Replace with a dig-based isolation flow that distinguishes the three
real failure modes (timeout = dnsmasq not reachable on the site IP;
SERVFAIL = forward to NetBird resolver failed; NXDOMAIN = wrong FQDN).
Diagnostic flow verified end-to-end in a lab — valid hostnames return
NOERROR with an answer record, unknown ones return status: NXDOMAIN as
described.