Skip to content

docs: masquerade-off HA is achievable, not impossible - #893

Draft
SunsetDrifter wants to merge 4 commits into
mainfrom
cc/masqoff-ha-routing-peers
Draft

docs: masquerade-off HA is achievable, not impossible#893
SunsetDrifter wants to merge 4 commits into
mainfrom
cc/masqoff-ha-routing-peers

Conversation

@SunsetDrifter

@SunsetDrifter SunsetDrifter commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Why

Two pages state that high availability "stops working" when masquerade is off:

  • manage/networks/how-routing-peers-work — "High availability also stops working with masquerade off, because return traffic must flow back through one specific routing peer's LAN address"
  • manage/networks/masquerade — "High availability stops working"

That reads as a flat impossibility, and it turns away a legitimate use case: preserving the client source IP for auditing, per-user database permissions, or firewall policy keyed on the real source.

The true statement is narrower. NetBird's half of a 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. That is a condition to meet, not a dead end.

What changed

masquerade.mdx

  • The "stops working" bullet now points to a new short section.
  • New High availability with masquerade off section: give the routing peers distinct metrics so the active peer is the same for every client, then make the return route's next hop follow that peer, either with a shared virtual IP (VRRP) or a router that moves the route on a failed health check. The health check has to track the tunnel rather than the host answering pings.
  • A warning 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: replies arriving at the peer a client is not using are discarded, so both ends look healthy.
  • A note that the second interruption on recovery cannot be avoided by pinning the virtual IP to the standby, because the client's switch back to the lower-metric peer is automatic. Pinning the route while the client moves back strands the return path rather than protecting it.
  • The return route may live on the destination subnet's default gateway even when that gateway and the routing peer share the subnet. This is the only option when the destination host is not the operator's to configure, which is common for appliances and managed databases. The page previously offered the gateway only for a destination in a different subnet, and its persistent-configuration steps assume host access throughout.

Both mechanisms live outside NetBird, so the section names the pattern without shipping a third-party configuration we would then own.

how-routing-peers-work.mdx

  • The masquerade note now states the condition instead of the impossibility, and links to the new section.
  • "Failover is automatic and immediate" softened to "normally within seconds". Client re-selection is fast but not instant, and "immediate" invites a report from anyone who measures it. Also rephrased so it no longer asserts whether the client or the management side detects the loss.

Notes for review

  • No new pages, no navigation changes. Anchors used: #high-availability-with-masquerade-off (new) and #high-availability (already referenced from the Kubernetes use-case page).
  • The timing wording is deliberately qualitative. Publishing a figure would read as a commitment.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • Documentation
    • Clarified automatic failover timing and updated switch-back wording for routing peers.
    • Expanded masquerade guidance when high availability is not configured, including return-route behavior during failover.
    • Added explicit requirements for the NetBird CIDR return route to target the routing peer LAN IP.
    • Documented that masquerade-off is supported on Linux routing peers and provided supported failover approaches, route placement options, and expected impacts (dropped replies, connection resets, brief interruptions).

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.
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Jul 30, 2026 8:27am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d8723066-ea73-4eec-b3eb-16a425b72cf3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The documentation updates clarify automatic routing peer failover timing, masquerade-off return-route placement, and high-availability configurations that keep return traffic aligned with the active peer.

Changes

Routing and masquerade documentation

Layer / File(s) Summary
Failover timing and failure behavior
src/pages/manage/networks/how-routing-peers-work.mdx
Documents automatic standby takeover timing and explains that stale return routes can drop replies after failover.
Masquerade-off return routing and HA setup
src/pages/manage/networks/masquerade.mdx
Clarifies return-route placement and adds HA requirements covering metrics, next-hop tracking, incorrect route configurations, resets, and interruptions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: lixmal

Poem

I thump my feet where routes align,
Through failover hops and paths that shine.
The standby wakes when primaries fall,
Return roads guide the packets all.
With virtual hops, the links stay bright—
A bunny’s routing docs take flight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main documentation change: clarifying that high availability with masquerade disabled is possible.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
  • Commit unit tests in branch cc/masqoff-ha-routing-peers

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 `@src/pages/manage/networks/masquerade.mdx`:
- Line 184: Update the recovery interruption statement in the masquerade
failover documentation to make it conditional: recovery can cause a second brief
interruption when clients return before the route does, and the behavior depends
on convergence timing. Preserve the surrounding explanation about automatic
client switching and virtual IP pinning.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: da772466-f08a-4d07-8b2a-ce88319d735a

📥 Commits

Reviewing files that changed from the base of the PR and between 0977b7e and 6690f06.

📒 Files selected for processing (2)
  • src/pages/manage/networks/how-routing-peers-work.mdx
  • src/pages/manage/networks/masquerade.mdx

Do not point the return route at both peers at once, as two static routes or an equal-cost pair. Replies reaching the peer a client is not using are silently discarded, so both ends look healthy while traffic fails.
</Warning>

Established connections reset on failover, as they do with masquerade on. Recovery causes a second brief interruption, because clients return to the primary faster than the route does, and you cannot avoid it by pinning the virtual IP to the standby: the client's switch back is automatic.

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'src/pages/manage/networks/masquerade.mdx' || true

echo "== relevant MDX section =="
if [ -f src/pages/manage/networks/masquerade.mdx ]; then
  wc -l src/pages/manage/networks/masquerade.mdx
  sed -n '150,210p' src/pages/manage/networks/masquerade.mdx
fi

echo "== search related docs for VRRP/keepalived/router failoff wording =="
rg -n "VRRP|keepalived|router|health check|failover|masquerade|second brief|return to the primary|switch back" src/pages/docs src/pages/manage public docs -S || true

echo "== repo config/build hints =="
for f in package.json netbird setup.sh; do
  [ -f "$f" ] && { echo "--- $f ---"; sed -n '1,220p' "$f"; }
done

echo "== git status/stat =="
git diff --stat || true
git status --short || true

Repository: netbirdio/docs

Length of output: 23780


🌐 Web query:

NetBird routing peers failure detection recovery failback documentation seconds clients switch back primary

💡 Result:

NetBird handles routing peer failure, recovery, and failback through an automated high availability (HA) mechanism that operates continuously [1][2][3]. Failure Detection and Failover When you assign multiple routing peers to a network, NetBird automatically monitors the availability and health of those peers [4][3][5]. If a primary routing peer (the one with the lowest metric) becomes unreachable, NetBird clients immediately detect the failure and fail over to an available standby routing peer [1][2]. This process is designed to be immediate, ensuring that traffic continues to flow through the remaining healthy peer(s) [1][2][6]. Recovery and Failback When the primary routing peer comes back online and restores connectivity, NetBird clients automatically detect its return and switch back to it immediately [1]. This ensures that the network traffic is again routed through the preferred, lower-metric peer [1]. Key Technical Details: - Metric-based Selection: Routing peers are assigned metrics. A lower metric indicates a primary peer, while higher metrics indicate standby peers [1][4]. If peers are assigned the same metric, NetBird balances traffic among them based on latency [4][2]. - Automatic Switching: Failover and failback are triggered automatically by the NetBird client's route management system, which continuously evaluates peer status (e.g., connection status, latency, and metrics) [1][5]. - Connection Handling: While the failover and failback processes happen near-instantaneously, any established TCP connections passing through the previous routing peer will reset when the switch occurs, requiring applications to re-establish those connections [1]. - Configuration: High availability is achieved by adding multiple routing peers to the same network [4][7]. It is recommended to keep these peers in different failure domains to ensure genuine redundancy [4]. If you experience issues where a client fails to switch, it may indicate a stale route or a synchronization delay, which have been addressed in recent versions of NetBird to ensure robust automatic recovery [6][8]. Verify that your routing peers are correctly configured in a routing group or assigned individually with appropriate metrics [4][7].

Citations:


🌐 Web query:

VRRP keepalived failover convergence versus host/application reconnect after routing peer failure

💡 Result:

The convergence process following a routing peer or VRRP (keepalived) failure consists of two distinct phases: network-layer re-convergence and application-layer recovery [1]. Network-layer convergence (VRRP/Keepalived) The time taken for keepalived to fail over is primarily governed by the VRRP advertisement interval and the number of missed advertisements allowed before declaring the Master node dead [2][3][4]. - Default Behavior: With standard configuration (1-second advertisement, 3-second hold time), failover typically takes 3-4 seconds [2][4]. - Optimization: Convergence can be accelerated by tuning these timers (e.g., using sub-second advertisements if supported by the version and network environment) and ensuring Gratuitous ARP (GARP) behavior is optimized [2][5]. - Hidden Latency: Even after the backup node assumes the Master state, traffic may remain unreachable due to upstream switch ARP cache timeouts [2]. Configuring keepalived to send multiple, repeated GARPs can mitigate this by forcing upstream devices to update their MAC tables faster [2]. Application/Host Reconnect Network convergence is only the "gate opener"; it does not guarantee immediate restoration of traffic for active sessions [1]. - TCP Implications: A VRRP failover typically forces existing TCP connections to reset because the new Master often lacks the conntrack/stateful information of the original Master [6][7]. Unless state synchronization (such as conntrackd or application-level state replication) is in place, clients must re-establish sessions, which depends on application timeouts and retry logic [6][7]. - Physics of Failure: For established connections, a failover event often results in a brief window of dropped packets (RTO) [8]. Modern applications usually handle these short outages gracefully through automatic retries [3][4]. For more critical, high-availability scenarios, simple network-level redundancy is often insufficient; solutions such as Protective ReRoute (PRR) or stateful synchronization are required to mask these failures from the application layer [7][9]. Summary of Key Differences - VRRP/Keepalived Convergence: Focuses on the transition of the Virtual IP (VIP) and MAC ownership at the L2/L3 boundary [2][10]. It is deterministic and governed by timer configurations [3][4]. - Application Reconnect: Depends on the interaction between the network outage duration and the application's tolerance for connectivity loss [4][1]. Even if the network converges in 1 second, the application may require much longer to detect a "broken" session and initiate a reconnect, depending on its internal keepalive/timeout settings [4]. Top Results: [2], [3], [4], [8], [7], [1]

Citations:


Qualify the recovery interruption claim.

The supported routes setup is VRRP/keepalived or router health checks, but convergence timing can differ across configs. “Recovery causes a second brief interruption” is better as “Recovery can cause a second brief interruption if clients return before the return route moves; behavior depends on convergence timing.”

🤖 Prompt for 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.

In `@src/pages/manage/networks/masquerade.mdx` at line 184, Update the recovery
interruption statement in the masquerade failover documentation to make it
conditional: recovery can cause a second brief interruption when clients return
before the route does, and the behavior depends on convergence timing. Preserve
the surrounding explanation about automatic client switching and virtual IP
pinning.

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.
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.
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.
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