mirror of
https://github.com/netbirdio/docs.git
synced 2026-09-20 22:09:04 +02:00
docs: add Site-to-VPN scenario guide (#748)
* docs: add Site-to-VPN scenario guide
New dedicated guide for letting clientless devices on a local network
initiate connections to NetBird peers (the reverse of VPN-to-Site).
Covers static-route and DNAT options, DNS resolution via dnsmasq, and
explains why the target peer always observes the routing peer's NetBird
IP as the source.
- Add src/pages/manage/network-routes/use-cases/by-scenario/site-to-vpn.mdx
- Wire it into NavigationDocs.jsx
- Update the site-to-site overview table row to point at the new page
- Replace the stub Site-to-VPN subsection in site-to-site-office.mdx
with a pointer to the new guide
* docs(site-to-vpn): correct source-IP section, add firewall and interface notes
- Source IP Behavior: remove the option that suggested emptying the
destination peer's policies. That doesn't preserve source IP; it just
tears down the wireguard pairing. Replace with an honest "not possible
with legacy Network Routes."
- Step 3: call out that hosts with FORWARD-DROP firewalls (UFW, firewalld)
need an explicit ACCEPT rule between the site interface and wt0.
- Option B: prefix the DNAT step with `ip -br addr` so customers find the
right site-facing interface instead of assuming eth0.
- Step 1: use "Name" for the setup key field instead of the route-only
"Network Identifier".
* docs(site-to-vpn): tighten prereqs, firewall step, and source-IP wording
- Drop generic prereqs (account, routing peer hardware, target peer)
- Reduce Step 3 to the host-firewall FORWARD rule
- Label Networks-feature Site-to-VPN as 'not possible' rather than limited
- Rename topology arrow to 'NetBird Overlay'
- Clarify masquerade lives on the routing peer in troubleshooting
* docs(site-to-vpn): switch primary path to Networks; document outbound SNAT requirement
Verified in the lab that Networks supports Site-to-VPN with the same
shape as Network Routes (Resource + Routing Peer + peer-group policy).
The differentiating factor is not the feature but the routing peer
platform: NetBird's masquerade flag does not install a working outbound
SNAT on non-Linux peers or in userspace mode, so the user must configure
it explicitly on the routing peer or upstream firewall.
Doc changes:
- Lead with Networks; Network Routes is now framed as an equivalent
alternative rather than the only option
- New Step 3 dedicated to the outbound SNAT (Linux iptables, pfSense /
OPNsense, MikroTik examples)
- New section "Outbound SNAT requirement" explaining why the destination
peer's access control rejects unrewritten site IPs and where the
dashboard masquerade flag is and isn't sufficient
- Up-front Warning calls out the platform requirement so customers don't
silently misconfigure
- Troubleshooting entry updated to point at SNAT counters and tcpdump
- Updated Source IP Behavior section to reflect that the behavior is the
same on both Networks and Network Routes
Parent page changes:
- /use-cases/site-to-site: Scenario Support table now shows Site-to-VPN
as Yes on both Networks and Network Routes; "Which Scenario Do I Need"
row points at both implementations
* docs(site-to-vpn): make static route the only Step 6 path; move DNAT to appendix
The static-route approach is the canonical setup; the per-service DNAT
option is a fallback for sites where routing changes aren't possible.
Treat it that way in the doc to keep the main flow linear.
- Step 6 now describes only the static-route approach (former Option A)
- Add a one-line pointer at the end of Step 6 to the appendix for sites
where the route can't be set
- Move the DNAT instructions to a new appendix at the bottom of the page
- Simplify Test Connectivity to a single curl
- Trim the Option-A/Option-B framing from the Troubleshooting "Connection
times out" entry
* docs(site-to-vpn): drop Source IP Behavior section
The "Outbound SNAT requirement" section already covers why the source IP
ends up as the routing peer's NetBird IP; a separate Source IP Behavior
section was repeating the same point and adding a speculative paragraph
about future Networks support. Drop both, plus the up-front Warning that
pointed at the removed section.
* docs(site-to-vpn): drop the Networks-vs-Network-Routes note
The guide is written around Networks; the side-note suggesting Network
Routes as an alternative path adds noise without value. The Step 4 inline
note keeps the Network Routes equivalent for anyone who needs it.
* docs(site-to-vpn): drop the inline Network Routes equivalent note
The guide is Networks-only now. Pointing readers at Network Routes mid-flow
just creates two paths to maintain without serving the reader who's
following the steps in front of them.
* docs(site-to-vpn): move page under Networks → Use Cases
The page describes a Networks-based setup; living under Network Routes
mis-categorised it.
- git mv to /manage/networks/use-cases/site-to-vpn.mdx (as a direct
child of Use Cases, not under By Scenario)
- Navigation: remove entry from Network Routes → By Scenario, add under
Networks → Use Cases
- Redirect old URL (/manage/network-routes/use-cases/by-scenario/site-to-vpn)
to new URL, permanent
- Update in-tree links in use-cases/site-to-site/index.mdx and
network-routes/use-cases/by-scenario/site-to-site-office.mdx
* docs(site-to-site): drop Network Routes mentions for Site-to-VPN
The Site-to-VPN guide is Networks-only; the overview page shouldn't
still be listing Network Routes alongside it.
* docs(site-to-vpn): trust NetBird's automatic SNAT on Linux kernel mode
On Linux in kernel mode, NetBird installs the SNAT itself when masquerade
is enabled on the routing peer — the user does not need a manual iptables
rule. Reframe Step 3 around this:
- Linux: enable ip_forward only; NetBird does the SNAT
- Non-Linux (pfSense / OPNsense / MikroTik / Windows / macOS / userspace):
configure manual outbound SNAT on the routing peer or upstream firewall
- Tighten the "Outbound SNAT requirement" appendix accordingly
- Move the explicit Linux iptables MASQUERADE rule into a troubleshooting
fallback for the case where NetBird's automatic SNAT doesn't fire
* docs(site-to-vpn): drop sysctl ip_forward instruction on Linux
NetBird handles IP forwarding itself on Linux; the manual sysctl was
unnecessary noise. Keep the host-firewall FORWARD-ACCEPT note since
UFW/firewalld setups still need it.
* docs(site-to-vpn): route the account's /16, not the entire /10 CGNAT range
NetBird assigns each account one /16 block out of 100.64.0.0/10 (chosen
randomly, customisable). Routing the whole /10 sends unrelated CGNAT
addresses through the routing peer; the correct target is the account's
own /16.
Step 6 now:
- Explains the /16-per-account model with the 64-block context
- Shows how to read the account's /16 from `netbird status` on any peer
- Switches the Linux / Windows / DHCP-option-121 examples to a concrete
/16 example (100.121.0.0/16) with a note to substitute your own
* docs(site-to-vpn): clarify when the target peer uses a setup key
Setup keys are for service / appliance peers; user peers (laptops,
workstations) enroll through SSO and inherit groups from existing
assignments. Reword the target-peer instruction to reflect that
distinction.
* docs(site-to-vpn): rename target peer to overlay-peer / overlay-peers
The previous backup-collector / backup-collectors naming carried
scenario-specific framing into the step examples. Use the generic
overlay-peer / overlay-peers throughout to keep the guide universal.
* chore: add trailing commas in Kubernetes nav entries
* Revert "chore: add trailing commas in Kubernetes nav entries"
This reverts commit d11b7eb7d0.
This commit is contained in:
@@ -31,6 +31,11 @@ const nextConfig = {
|
|||||||
destination: '/manage/networks',
|
destination: '/manage/networks',
|
||||||
permanent: true,
|
permanent: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
source: '/manage/network-routes/use-cases/by-scenario/site-to-vpn',
|
||||||
|
destination: '/manage/networks/use-cases/site-to-vpn',
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
source: '/docs/getting-started/installation',
|
source: '/docs/getting-started/installation',
|
||||||
destination: '/get-started/install',
|
destination: '/get-started/install',
|
||||||
|
|||||||
@@ -232,6 +232,10 @@ export const docsNavigation = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Site-to-VPN',
|
||||||
|
href: '/manage/networks/use-cases/site-to-vpn',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -178,21 +178,11 @@ ping 10.0.0.100 # HQ server
|
|||||||
|
|
||||||
## Site-to-VPN: Office Systems Reaching Remote Workers
|
## Site-to-VPN: Office Systems Reaching Remote Workers
|
||||||
|
|
||||||
Some scenarios require office systems to initiate connections to remote workers (monitoring, management tools, etc.).
|
Some scenarios require office systems without NetBird to initiate
|
||||||
|
connections to NetBird-connected peers (monitoring, backups, management
|
||||||
### Configuration
|
tools, etc.). See [Site-to-VPN](/manage/networks/use-cases/site-to-vpn)
|
||||||
|
for the full step-by-step guide, including DNS resolution and the
|
||||||
1. Create a network route for the office network (as above)
|
per-service port-forwarding alternative.
|
||||||
2. On the office system that needs to reach remote workers, add a route to the NetBird network:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Route to NetBird network through the routing peer
|
|
||||||
sudo ip route add 100.64.0.0/10 via 10.0.0.50
|
|
||||||
```
|
|
||||||
|
|
||||||
Where `10.0.0.50` is the routing peer's office IP.
|
|
||||||
|
|
||||||
3. Create two access policies allowing traffic in both directions
|
|
||||||
|
|
||||||
## Best Practices for Business Deployments
|
## Best Practices for Business Deployments
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,407 @@
|
|||||||
|
import { Note, Warning } from '@/components/mdx'
|
||||||
|
|
||||||
|
# Site-to-VPN: Clientless Devices Reaching NetBird Peers
|
||||||
|
|
||||||
|
This guide shows how to let a device that does **not** have NetBird installed
|
||||||
|
initiate a connection to a NetBird peer over the overlay — the reverse of the
|
||||||
|
more common VPN-to-Site direction.
|
||||||
|
|
||||||
|
## What You'll Achieve
|
||||||
|
|
||||||
|
After following this guide, a clientless device on your local network can
|
||||||
|
reach a NetBird peer by its overlay IP or NetBird DNS name. Typical examples:
|
||||||
|
|
||||||
|
- An on-premise monitoring system pushing metrics to a NetBird-connected
|
||||||
|
collector
|
||||||
|
- A legacy server initiating outbound backups to a NetBird peer in the cloud
|
||||||
|
- An office printer reporting status to a NetBird-connected management
|
||||||
|
application
|
||||||
|
|
||||||
|
```
|
||||||
|
Clientless Device ──► Routing Peer ──► NetBird Overlay ──► NetBird Peer
|
||||||
|
(no NetBird) (peer) (peer)
|
||||||
|
```
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
The routing peer must perform **outbound source NAT** for site traffic
|
||||||
|
entering the NetBird overlay. NetBird performs this automatically only when
|
||||||
|
the routing peer is **Linux running in kernel mode**. On any other platform
|
||||||
|
(pfSense, OPNsense, MikroTik, Windows, macOS, or Linux in userspace mode),
|
||||||
|
you must configure the outbound NAT yourself on the routing peer or on its
|
||||||
|
upstream firewall. Without this, the overlay peer drops the traffic at its
|
||||||
|
access control. See [Outbound SNAT requirement](#outbound-snat-requirement).
|
||||||
|
</Warning>
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- A device on the local network to serve as the routing peer. **Linux is
|
||||||
|
strongly recommended** for the routing peer because it can install the
|
||||||
|
required outbound SNAT automatically (see the warning above).
|
||||||
|
- A separate device running the NetBird client that the clientless device
|
||||||
|
needs to reach
|
||||||
|
- The ability to either add a static route on the clientless device (or its
|
||||||
|
upstream router), or to install a port-forwarding rule on the routing peer
|
||||||
|
— both options are covered below
|
||||||
|
|
||||||
|
## Example Setup
|
||||||
|
|
||||||
|
- **Local site:** `192.168.50.0/24`
|
||||||
|
- **Routing peer (`site-router`):** site IP `192.168.50.10`, NetBird IP
|
||||||
|
assigned at enrollment
|
||||||
|
- **Clientless device:** `192.168.50.20`
|
||||||
|
- **Target NetBird peer (`overlay-peer`):** runs the NetBird client; we
|
||||||
|
reach it on TCP port `8080`
|
||||||
|
|
||||||
|
## Step 1: Create Setup Keys with Groups
|
||||||
|
|
||||||
|
Before installing NetBird on the routing peer, create a setup key with an
|
||||||
|
auto-assigned group so the peer lands in the right place:
|
||||||
|
|
||||||
|
1. Go to **Setup Keys** in the NetBird dashboard
|
||||||
|
2. Click **Create Setup Key**
|
||||||
|
3. Configure:
|
||||||
|
- Name: "Site Routing Peer"
|
||||||
|
- Auto-assigned groups: create and add `site-routing-peers`
|
||||||
|
4. Click **Create** and note the key
|
||||||
|
|
||||||
|
The target peer is a regular NetBird peer; nothing special needs to be
|
||||||
|
configured on it for this scenario. If the target peer is a service or
|
||||||
|
appliance (not a user device), create a second setup key for it the same
|
||||||
|
way and add it to a group like `overlay-peers`. User peers — laptops
|
||||||
|
and workstations — enroll through SSO instead and pick up their group via
|
||||||
|
your existing group assignments.
|
||||||
|
|
||||||
|
## Step 2: Deploy the Routing Peer
|
||||||
|
|
||||||
|
Install NetBird on the routing peer and enroll it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://pkgs.netbird.io/install.sh | sh
|
||||||
|
sudo netbird up --setup-key YOUR_SITE_SETUP_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm the peer appears in the dashboard and shows the `site-routing-peers`
|
||||||
|
group.
|
||||||
|
|
||||||
|
## Step 3: Configure the Outbound SNAT (If applicable)
|
||||||
|
|
||||||
|
The routing peer must SNAT site traffic onto its NetBird interface so the
|
||||||
|
overlay peer's access control sees a NetBird IP it recognises. See
|
||||||
|
[Outbound SNAT requirement](#outbound-snat-requirement) for the reasoning.
|
||||||
|
|
||||||
|
**On Linux:** no manual SNAT configuration is needed. NetBird enables IP
|
||||||
|
forwarding and installs the SNAT itself when masquerade is enabled on the
|
||||||
|
routing peer (Step 4).
|
||||||
|
|
||||||
|
The only Linux-side caveat is if you run a host firewall (UFW, firewalld)
|
||||||
|
with the `FORWARD` chain default set to `DROP` — in that case, allow
|
||||||
|
forwarding between the site-facing interface and `wt0`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo iptables -I FORWARD 1 -i <site-iface> -o wt0 -j ACCEPT
|
||||||
|
```
|
||||||
|
|
||||||
|
**On any other platform** — pfSense, OPNsense, MikroTik, Windows, macOS, or
|
||||||
|
Linux running in userspace mode — NetBird does not install the SNAT for
|
||||||
|
you. Configure it manually on the routing peer or its upstream firewall.
|
||||||
|
|
||||||
|
For pfSense / OPNsense, add an outbound NAT rule on the `wt0` (or
|
||||||
|
equivalent) interface that translates traffic sourced from `192.168.50.0/24`
|
||||||
|
to the interface address. Switch outbound NAT mode to **Manual** (or
|
||||||
|
**Hybrid**) so this rule is honoured.
|
||||||
|
|
||||||
|
For MikroTik (RouterOS):
|
||||||
|
|
||||||
|
```
|
||||||
|
/ip firewall nat add chain=srcnat src-address=192.168.50.0/24 \
|
||||||
|
out-interface=wt0 action=masquerade
|
||||||
|
```
|
||||||
|
|
||||||
|
Any outbound source NAT mechanism that rewrites the site-CIDR source to the
|
||||||
|
routing peer's NetBird IP (or to the `wt0` interface address) on the
|
||||||
|
NetBird egress path is sufficient.
|
||||||
|
|
||||||
|
## Step 4: Create the Network
|
||||||
|
|
||||||
|
In the NetBird dashboard:
|
||||||
|
|
||||||
|
1. Go to **Networks** and click **Add Network**
|
||||||
|
2. Name: `site-50-network`
|
||||||
|
3. Click **Create Network**
|
||||||
|
|
||||||
|
Now add the site CIDR as a resource:
|
||||||
|
|
||||||
|
1. In the new network, click **Add Resource**
|
||||||
|
2. Configure:
|
||||||
|
- **Name:** `site-50`
|
||||||
|
- **Address:** `192.168.50.0/24`
|
||||||
|
- **Type:** Subnet
|
||||||
|
- **Groups:** create and add `site-50-cidr` (this group represents the
|
||||||
|
site CIDR for use in policies)
|
||||||
|
3. Click **Add Resource**
|
||||||
|
|
||||||
|
Attach the routing peer:
|
||||||
|
|
||||||
|
1. In the network, click **Add Routing Peer**
|
||||||
|
2. Select `site-router` (or the `site-routing-peers` group)
|
||||||
|
3. **Masquerade:** Enabled is fine, but does not replace
|
||||||
|
[Step 3](#step-3-configure-the-outbound-snat) — this dashboard flag does
|
||||||
|
not install a working SNAT on non-Linux routing peers and is unreliable in
|
||||||
|
userspace mode
|
||||||
|
4. Click **Save**
|
||||||
|
|
||||||
|
## Step 5: Create the Access Policy
|
||||||
|
|
||||||
|
The routing peer needs to be allowed to reach the target peer over the
|
||||||
|
overlay. Because Step 3's SNAT rewrites the source to the routing peer's
|
||||||
|
NetBird IP, the policy uses peer groups:
|
||||||
|
|
||||||
|
1. Go to **Access Control** → **Policies** and click **Add Policy**
|
||||||
|
2. Configure:
|
||||||
|
- **Name:** `Site Router to Overlay Peer`
|
||||||
|
- **Protocol:** `TCP`
|
||||||
|
- **Ports:** `8080` (or `All` to allow any port)
|
||||||
|
- **Source Groups:** `site-routing-peers`
|
||||||
|
- **Destination Groups:** `overlay-peers`
|
||||||
|
3. Click **Add Policy**
|
||||||
|
|
||||||
|
## Step 6: Direct Site Traffic Through the Routing Peer
|
||||||
|
|
||||||
|
Tell the clientless device — or the site's upstream router — to send
|
||||||
|
traffic destined for your account's NetBird IP range through the routing
|
||||||
|
peer.
|
||||||
|
|
||||||
|
### Find your account's NetBird range
|
||||||
|
|
||||||
|
NetBird assigns each account a single `/16` block from inside the
|
||||||
|
`100.64.0.0/10` CGNAT range (one of 64 possible blocks such as
|
||||||
|
`100.64.0.0/16`, `100.121.0.0/16`, `100.127.0.0/16`, …). The block is
|
||||||
|
chosen randomly per account and can be customised. Use that `/16` for the
|
||||||
|
site's static route — not the whole `/10` — so you don't route unrelated
|
||||||
|
CGNAT addresses through the routing peer.
|
||||||
|
|
||||||
|
Read it off any enrolled peer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ netbird status | grep "NetBird IP"
|
||||||
|
NetBird IP: 100.121.195.4/16
|
||||||
|
# → this account's block is 100.121.0.0/16
|
||||||
|
```
|
||||||
|
|
||||||
|
In the examples below, replace `100.121.0.0/16` with your own block.
|
||||||
|
|
||||||
|
### Install the route
|
||||||
|
|
||||||
|
**On a Linux clientless device:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ip route add 100.121.0.0/16 via 192.168.50.10
|
||||||
|
# Persist via /etc/network/interfaces, netplan, or NetworkManager
|
||||||
|
```
|
||||||
|
|
||||||
|
**On Windows:**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
route -p add 100.121.0.0 mask 255.255.0.0 192.168.50.10
|
||||||
|
```
|
||||||
|
|
||||||
|
**On a site router that issues DHCP:** add a classless static route option
|
||||||
|
(DHCP option 121) pointing your account's `/16` to the routing peer. Every
|
||||||
|
device on the network will then learn the route automatically.
|
||||||
|
|
||||||
|
The clientless device can now reach the target peer by its NetBird IP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://<TARGET_PEER_NETBIRD_IP>:8080/
|
||||||
|
```
|
||||||
|
|
||||||
|
To use NetBird's DNS names instead of IPs, see
|
||||||
|
[Resolving NetBird DNS Names](#resolving-netbird-dns-names) below.
|
||||||
|
|
||||||
|
If you cannot add a static route on the clientless device or the site
|
||||||
|
router — or you only need to expose a small number of specific services —
|
||||||
|
see [Appendix: Per-Service Port Forwarding](#appendix-per-service-port-forwarding)
|
||||||
|
for a DNAT-based alternative.
|
||||||
|
|
||||||
|
## Test Connectivity
|
||||||
|
|
||||||
|
From the clientless device:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -v http://<TARGET_PEER_NETBIRD_IP>:8080/
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify on the target peer that the request arrived:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ss -tnp | grep :8080
|
||||||
|
```
|
||||||
|
|
||||||
|
The connection's remote address on the target peer will be the **routing
|
||||||
|
peer's NetBird IP**, not the clientless device's local IP.
|
||||||
|
|
||||||
|
## Resolving NetBird DNS Names
|
||||||
|
|
||||||
|
By default, the clientless device has no way to resolve `*.netbird.cloud`
|
||||||
|
hostnames — that lookup happens locally on each NetBird peer. You can
|
||||||
|
publish those names to the site by running a forwarding resolver on the
|
||||||
|
routing peer.
|
||||||
|
|
||||||
|
A minimal `dnsmasq` configuration on the routing peer:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# /etc/dnsmasq.d/netbird.conf
|
||||||
|
bind-interfaces
|
||||||
|
listen-address=192.168.50.10
|
||||||
|
interface=eth0
|
||||||
|
|
||||||
|
# Forward NetBird-managed names to this peer's local NetBird resolver.
|
||||||
|
# The NetBird daemon listens on the peer's NetBird IP, port 53.
|
||||||
|
server=/netbird.cloud/<ROUTING_PEER_NETBIRD_IP>
|
||||||
|
|
||||||
|
# Everything else to upstream
|
||||||
|
server=8.8.8.8
|
||||||
|
server=1.1.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Then point the clientless device's DNS at `192.168.50.10` (via DHCP,
|
||||||
|
`/etc/resolv.conf`, or static configuration) and use the NetBird hostname
|
||||||
|
directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://overlay-peer.netbird.cloud:8080/
|
||||||
|
```
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
The NetBird daemon binds its DNS resolver on the peer's own NetBird IP,
|
||||||
|
not on `127.0.0.1`. Substitute the routing peer's actual NetBird IP into
|
||||||
|
the `server=/netbird.cloud/...` line — you can find it with
|
||||||
|
`netbird status` on the routing peer.
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
## Outbound SNAT requirement
|
||||||
|
|
||||||
|
NetBird's per-peer access control on the destination peer matches inbound
|
||||||
|
traffic against an ipset of allowed source IPs. The ipset is populated from
|
||||||
|
the **NetBird IPs of peers in the policy's source group** — it cannot
|
||||||
|
contain a routed CIDR like `192.168.50.0/24`. So when a packet from
|
||||||
|
`192.168.50.20` arrives at the overlay peer, the access control has no
|
||||||
|
matching entry and the packet is dropped.
|
||||||
|
|
||||||
|
The fix is to rewrite the source IP at the routing peer before the packet
|
||||||
|
enters the overlay, replacing the site IP with the routing peer's NetBird
|
||||||
|
IP. That NetBird IP **is** in the policy's source group, so the access
|
||||||
|
control matches and the packet is accepted.
|
||||||
|
|
||||||
|
On a Linux routing peer running in kernel mode, NetBird installs the SNAT
|
||||||
|
itself via the kernel netfilter hooks when masquerade is enabled on the
|
||||||
|
routing peer. On any other platform — pfSense, OPNsense, MikroTik,
|
||||||
|
Windows, macOS, or Linux in userspace mode — that hook isn't available, so
|
||||||
|
the SNAT must be configured manually on the routing peer or on its
|
||||||
|
upstream firewall, as shown in [Step 3](#step-3-configure-the-outbound-snat).
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Connection times out from the clientless device.**
|
||||||
|
|
||||||
|
Check that the static route is in place:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip route get <TARGET_PEER_NETBIRD_IP>
|
||||||
|
# Should show "via 192.168.50.10 dev <iface>"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using the appendix DNAT alternative instead, verify the
|
||||||
|
forwarding rule on the routing peer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo iptables -t nat -L PREROUTING -n -v
|
||||||
|
# Should show your DNAT rule with non-zero packet counters when traffic flows
|
||||||
|
```
|
||||||
|
|
||||||
|
**Routing peer receives packets but they don't reach the target peer.**
|
||||||
|
|
||||||
|
Check that IP forwarding is enabled and confirm the target peer is reachable
|
||||||
|
from the routing peer directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On the routing peer
|
||||||
|
cat /proc/sys/net/ipv4/ip_forward # should be 1
|
||||||
|
curl http://<TARGET_PEER_NETBIRD_IP>:8080/ # should succeed
|
||||||
|
```
|
||||||
|
|
||||||
|
If the second command fails, the access policy is wrong — verify the policy
|
||||||
|
allows `site-routing-peers` → target peer's group on the required port.
|
||||||
|
|
||||||
|
**Target peer receives packets but drops them.**
|
||||||
|
|
||||||
|
The outbound SNAT in [Step 3](#step-3-configure-the-outbound-snat) is
|
||||||
|
missing or not effective. On the routing peer, packets going out `wt0` must
|
||||||
|
have their source IP rewritten to the routing peer's NetBird IP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On the routing peer, verify packet counters on the MASQUERADE rule:
|
||||||
|
sudo iptables -t nat -L POSTROUTING -n -v
|
||||||
|
# Or watch overlay traffic on the way out:
|
||||||
|
sudo tcpdump -ni wt0 'src net 192.168.50.0/24'
|
||||||
|
# Seeing site IPs here means SNAT is NOT firing; the target peer will drop.
|
||||||
|
```
|
||||||
|
|
||||||
|
If the routing peer is Linux in kernel mode and masquerade is enabled but
|
||||||
|
the SNAT counters stay at zero, drop in an explicit rule as a fallback:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o wt0 -j MASQUERADE
|
||||||
|
```
|
||||||
|
|
||||||
|
**DNS resolution returns NXDOMAIN.**
|
||||||
|
|
||||||
|
Confirm the routing peer's NetBird IP is correct in `dnsmasq.conf` (it
|
||||||
|
changes if the peer is re-enrolled), and that `dnsmasq` is not bound to
|
||||||
|
`lo` — binding loopback causes it to refuse forwarding to its own
|
||||||
|
`127.0.0.1`-co-located NetBird resolver.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- [Networks — Concept](/manage/networks)
|
||||||
|
- [Network Routes — Concept](/manage/network-routes)
|
||||||
|
- [Site-to-Site: Office Networks](/manage/network-routes/use-cases/by-scenario/site-to-site-office)
|
||||||
|
- [Site-to-Site Overview](/use-cases/site-to-site)
|
||||||
|
|
||||||
|
## Appendix: Per-Service Port Forwarding
|
||||||
|
|
||||||
|
If you cannot change routing on the site — for example, the clientless
|
||||||
|
device's IP stack is fixed and the upstream router is out of your control —
|
||||||
|
you can still expose individual NetBird services through the routing peer
|
||||||
|
using DNAT. This avoids the [Step 6](#step-6-direct-site-traffic-through-the-routing-peer)
|
||||||
|
static route entirely, but each service has to be configured explicitly.
|
||||||
|
|
||||||
|
First identify the routing peer's site-facing interface:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip -br addr
|
||||||
|
# Pick the interface that holds the routing peer's site IP (e.g. eth0, ens18).
|
||||||
|
```
|
||||||
|
|
||||||
|
Then install the DNAT rule on the routing peer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo iptables -t nat -A PREROUTING -i <site-iface> -p tcp --dport 18080 \
|
||||||
|
-j DNAT --to-destination <TARGET_PEER_NETBIRD_IP>:8080
|
||||||
|
# Persist via iptables-persistent / netfilter-persistent
|
||||||
|
```
|
||||||
|
|
||||||
|
The clientless device now reaches the service through the routing peer's
|
||||||
|
local IP and the forwarded port:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://192.168.50.10:18080/
|
||||||
|
```
|
||||||
|
|
||||||
|
The outbound SNAT configured in [Step 3](#step-3-configure-the-outbound-snat)
|
||||||
|
applies to this traffic as well — the target peer still observes the
|
||||||
|
routing peer's NetBird IP as the source.
|
||||||
|
|
||||||
|
Each forwarded service needs its own DNAT rule. This pattern is a good fit
|
||||||
|
for a small number of well-known services; for general overlay access, use
|
||||||
|
the static-route approach in Step 6 instead.
|
||||||
@@ -42,7 +42,7 @@ Office Server ──────► Routing Peer ──────► NetBird T
|
|||||||
- On-premise servers initiating backups to cloud peers
|
- On-premise servers initiating backups to cloud peers
|
||||||
- Legacy systems that must initiate outbound connections
|
- Legacy systems that must initiate outbound connections
|
||||||
|
|
||||||
**Implementation:** Requires [Network Routes](/manage/network-routes) (Networks does not currently support this)
|
**Implementation:** See the [Site-to-VPN guide](/manage/networks/use-cases/site-to-vpn) for the full setup with [Networks](/manage/networks).
|
||||||
|
|
||||||
### Site-to-Site
|
### Site-to-Site
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ Your Laptop ──────► NetBird Tunnel ──────► Exit Node
|
|||||||
|-------------|----------|----------------|
|
|-------------|----------|----------------|
|
||||||
| Access home devices from my laptop | VPN-to-Site | [Networks](/manage/networks/use-cases/by-scenario/access-home-devices) |
|
| Access home devices from my laptop | VPN-to-Site | [Networks](/manage/networks/use-cases/by-scenario/access-home-devices) |
|
||||||
| Access office resources while traveling | VPN-to-Site | [Networks](/manage/networks/use-cases/by-scenario/remote-worker-access) |
|
| Access office resources while traveling | VPN-to-Site | [Networks](/manage/networks/use-cases/by-scenario/remote-worker-access) |
|
||||||
| Let an office server connect to my laptop | Site-to-VPN | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-office) only |
|
| Let an office server connect to my laptop | Site-to-VPN | [Networks](/manage/networks/use-cases/site-to-vpn) |
|
||||||
| Connect two home networks together | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-home) only |
|
| Connect two home networks together | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-home) only |
|
||||||
| Link branch offices | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-office) only |
|
| Link branch offices | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-office) only |
|
||||||
| Bridge cloud VPC with on-premise network | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-cloud) only |
|
| Bridge cloud VPC with on-premise network | Site-to-Site | [Network Routes](/manage/network-routes/use-cases/by-scenario/site-to-site-cloud) only |
|
||||||
@@ -158,14 +158,14 @@ NetBird offers two features for routing traffic to private networks: [Networks](
|
|||||||
|
|
||||||
**Use Networks** for VPN-to-Site scenarios where you want a guided setup experience and per-resource access policies.
|
**Use Networks** for VPN-to-Site scenarios where you want a guided setup experience and per-resource access policies.
|
||||||
|
|
||||||
**Use Network Routes** when you need Site-to-VPN or Site-to-Site connectivity, or require advanced options like disabling masquerade.
|
**Use Network Routes** when you need Site-to-Site connectivity, or require advanced options like disabling masquerade.
|
||||||
|
|
||||||
### Scenario Support
|
### Scenario Support
|
||||||
|
|
||||||
| Scenario | Networks | Network Routes |
|
| Scenario | Networks | Network Routes |
|
||||||
|----------|----------|----------------|
|
|----------|----------|----------------|
|
||||||
| VPN-to-Site | Yes | Yes |
|
| VPN-to-Site | Yes | Yes |
|
||||||
| Site-to-VPN | No | Yes |
|
| Site-to-VPN | Yes | Yes |
|
||||||
| Site-to-Site | No | Yes |
|
| Site-to-Site | No | Yes |
|
||||||
|
|
||||||
### Detailed Comparison
|
### Detailed Comparison
|
||||||
|
|||||||
Reference in New Issue
Block a user