Antivirus, VPNs, and Corporate Proxies
Security products interpose on exactly the things a mesh agent depends on: they re-sign TLS connections, pull traffic into their own tunnels, and filter packets. On a machine running one — most corporate laptops, and any consumer machine with a security suite — noBGP works, but a few products need to be told about it. This page covers what to exclude, per vendor, and how to recognize which product is interfering.
What noBGP traffic looks like
Everything the agent does is outbound. It never needs an inbound port opened.
| Traffic | Protocol | Destination |
|---|---|---|
| Control channel + mesh | QUIC, UDP 443 | your router (e.g. router.nobgp.com) |
| Fallback control channel + mesh | TLS (wss), TCP 443 | same |
| Install and upgrades | HTTPS, TCP 443 | downloads.nobgp.com |
If UDP 443 is blocked, the agent detects it and falls back to TLS over TCP on its own — a firewall that drops UDP costs some latency, never connectivity.
Either row can travel over IPv4 or IPv6, and by default the agent tries both and takes whichever answers first. From agent 0.4.113 a node can be told to lead with one family and use the other only as a fallback — transport-family — which is the setting for a machine whose own hardware or uplink misbehaves on one of them, rather than for a filtering product.
Recognizing the interference
| Symptom | Likely cause |
|---|---|
| Certificate error during install or upgrade | HTTPS inspection (antivirus "web shield" or corporate proxy) re-signing the download connection |
| Node registers and shows online, but connections to peers stall or drop | A VPN client's virtual adapter pulling routes (its adapter usually shows a 169.254.x.x or its own tunnel address) |
Agent always on wss, never quic | Outbound UDP 443 blocked — harmless, see above |
nobgp status reports which transport the node is actually using (router.transport), and recent agents also flag detected TLS interception and foreign VPN adapters directly in the status output.
What to exclude
You never need to disable a security product. Three narrow exclusions cover everything:
- Exclude from HTTPS/SSL scanning:
downloads.nobgp.comand your router's domain (router.nobgp.comunless self-hosted). Inspection proxies replace the server certificate, which breaks the installer's certificate validation. - Allow the agent through the firewall: the
nobgpbinary (/usr/local/bin/nobgp,C:\Program Files\nobgp\nobgp.exe), outbound TCP 443 and UDP 443. - If a VPN client is active: add noBGP to its split-tunnel exclusions so overlay traffic doesn't get pulled into the VPN's tunnel.
Per-vendor notes
Norton 360 / Norton Security
Two separate components interfere, and they produce different symptoms:
- Web/Mail Shield re-signs HTTPS (its root certificate is literally named "generated by Norton Antivirus for SSL/TLS scanning") — this is the install-time certificate error. Settings → Antivirus → Scans and Risks → Web/Mail Shield → exclude
downloads.nobgp.comand your router domain, or disable HTTPS scanning. - Norton VPN installs Wintun/OpenVPN adapters that grab routes — this is the "online but peers flaky" symptom. Either enable split-tunneling for nobgp under the VPN's settings, or turn the VPN component off.
- Norton Firewall: Settings → Firewall → Traffic Rules → allow
nobgp.exe, outbound TCP/UDP 443.
Windows Defender
Defender does not inspect TLS and normally coexists cleanly. Two known cases:
- During install, real-time scanning of the freshly written binary can delay the service's first start by a few seconds. No action needed; the installer waits.
- If Controlled Folder Access is enabled, allow
nobgp.exeunder Ransomware protection → Allow an app.
Corporate proxies (Zscaler, Netskope, Palo Alto, Cisco Umbrella)
These re-sign all TLS, with a root certificate your IT department deployed via MDM — so connections succeed, silently inspected, on managed machines. noBGP still works, but ask IT to add downloads.nobgp.com and your router domain to the SSL-inspection bypass list: inspection middleboxes buffer long-lived connections and can drop the agent's control channel on idle. On an unmanaged machine behind such a proxy, the missing root causes the same certificate errors as consumer antivirus — the bypass list is the fix there too.
Zscaler Client Connector and similar agents also install a packet-filter tunnel; if peers are unreachable, ask IT to add the noBGP overlay range (100.64.0.0/10) to the tunnel's exclusions.
macOS: MDM profiles, Little Snitch, LuLu
- Managed Macs trust MDM-deployed inspection roots, so installs succeed even under inspection — see the corporate-proxy section above.
- Little Snitch / LuLu prompt on the agent's first outbound connection. Approve
nobgpfor TCP and UDP 443 to your router domain anddownloads.nobgp.com. If you dismissed the prompt, the agent appears installed-but-offline; open the firewall's rule list and allownobgp.
macOS: the built-in packet filter (pf)
macOS ships pf, its built-in packet filter, disabled, and from agent 0.4.110 noBGP leaves that decision to you. The agent writes one anchor file for its overlay interface (/etc/pf.anchors/nobgp-<device>, a single permissive pass in quick on lo0 rule): if pf is enabled the rule is loaded, and if pf is disabled the agent notes it in its log at debug level and runs without it. Nothing about connectivity, peers or the overlay depends on that rule — it permits traffic, it does not isolate anything — so both states work.
⚠ Agents through 0.4.109 could switch pf on. When the anchor could not be loaded because pf was off, the agent ran pfctl -e and retried, and nothing ever turned it back off — stopping or uninstalling the agent removes only its own anchor. So a Mac that ran one of those agents while pf was off can have pf enabled, applying whatever else /etc/pf.conf carries.
⚠ An enabled pf is not proof that noBGP enabled it. macOS enables pf at boot on some machines, and other network tools enable it too. The check below reports the state and never says who set it — and where this was measured on Macs running the agent, pf was already on at boot and the agent's enable path had never run. Read the state first. Disable pf only if you know that nothing else on the machine needs it.
sudo pfctl -s info | head -1 # "Status: Enabled" or "Status: Disabled"
sudo pfctl -d # disable it — only if nothing else on this Mac needs it
Upgrading to 0.4.110 does not change an already-enabled pf either way. Deliberately: switching a filter off on a machine whose rules you may since have come to depend on is your call, not the agent's.
Other VPN clients (WireGuard, Tailscale, OpenVPN, vendor VPNs)
noBGP coexists with other overlay networks — it detects a VPN already holding a CGNAT (100.64.x.x) address, and reads the machine's routing table so it can pick its own /20 around whatever the other product has already claimed. Interference, when it happens, is route-based: a full-tunnel VPN that claims the default route can swallow overlay traffic. Prefer split-tunnel mode, or exclude 100.64.0.0/10 from the VPN's routes.
Where those routes live matters, and through agent 0.4.110 the agent looked in one place. On Linux it read only the main routing table, while products that use policy routing — Tailscale among them — keep their routes in a table of their own and reach them with a rule that sits ahead of main. Such a claim was invisible: the agent took 100.64.0.0/20, the kernel went on sending that range to the other tunnel, and the node registered and reported healthy while no peer was reachable. From agent 0.4.111 every routing table is read, so a partial claim is dodged properly — and where the other product claims the whole of 100.64.0.0/10, the agent reports the pool as fully claimed instead of taking a slice it could never use. It will not carve inside another VPN's range, because that would hijack that product's own peers. From agent 0.4.112 such a node comes up anyway, without an overlay: peers are unreachable, which is what the condition means, but the control channel, command, file, the shared drive and nobgp status all keep working — so the machine can be fixed remotely, which 0.4.111 alone could not be, since it exited on this verdict and stayed down. nobgp status names the reason under network.overlay. See Peers Are Unreachable on a Machine Running Another Overlay VPN.
DNS is the other place two overlays meet. Where the agent answers every query on the host, it forwards the ones that are not its own to the resolvers the machine already had — and it drops any of those that belong to an overlay, because two forwarders holding each other as upstream is a query loop that answers SERVFAIL and takes name resolution on the box down with it. Tailscale drops noBGP's resolver for the same reason. Through agent 0.4.78 only Tailscale's IPv4 MagicDNS address (100.100.100.100) was recognised, so a host where Tailscale had installed its IPv6 resolver instead (fd7a:115c:a1e0::53) could reach exactly that loop; from agent 0.4.79 the whole fd7a:115c:a1e0::/48 range is excluded, the way 100.64.0.0/10 always was.
Excluding the loop is not the same as having somewhere to forward to, and agent 0.4.81 closes the case where it is not. On a host whose only other resolver belongs to an overlay, dropping it leaves the agent with no upstream at all: it answered "not my name" and the resolver it declined to ask had noBGP as its upstream and nothing else, so the machine resolved nothing — including the router's own hostname. 0.4.79 turned that from an endless query loop into an immediate double failure, which is better and is still a box with no DNS. From 0.4.81 the agent measures before it decides: while any of the resolvers it declined to forward to can still resolve the router's name, "not my name" is a working answer and nothing changes — this is the ordinary Tailscale case, and it must keep working, because a MagicDNS name answered by a public resolver would come back as no such host rather than falling through to Tailscale. Only once none of them can answer does the agent forward out-of-zone queries to public resolvers (1.1.1.1, 8.8.8.8) — the state where nothing is being taken away, because nothing was resolving. It follows the machine in both directions: when the other resolver recovers, the agent goes back to leaving those names alone. On a healthy host the measurement never runs and costs no queries.
A name this machine already reaches is left to whatever reaches it, from agent 0.4.116. Before answering a bare name, the agent asks its own hosts file and the machine's own nameservers — never its own zone — and where they answer, noBGP's zone says not found so your resolver falls through and uses that path. On a host running a second overlay that means a name its resolver answers wins locally, including an address elsewhere in 100.64.0.0/10 where that product's peers live; only an address inside noBGP's own slice is refused as evidence, so noBGP's answer can never satisfy the check that decides whether to give it up. Other nodes' names are never given up this way — see A name this machine reaches itself.
If a node running Tailscale reports DNS failures for the router's own hostname, see Node Is Online but Every Command and File Call Fails.
Still stuck?
Run nobgp status. The agent reports interference in three different places, and which one is populated tells you what kind of problem you have:
| Where | Field | Means |
|---|---|---|
router | transport | What is actually carrying traffic (quic or wss). |
router | tls_intercepted | Something re-signed the control channel — antivirus HTTPS scanning or a corporate proxy. Names the certificate's owner. |
environment | tunnels | Another product's active VPN adapter, with the address it holds — the usual route thief. |
environment | security_products | Third-party antivirus or firewall registered with the OS. |
network | route | missing means overlay traffic is not going through the noBGP interface (Windows: another product's route is winning). |
transport answers for the process running right now. For what happened while nobody was watching, read the log: since agent 0.4.115 every successful registration writes one line naming the transport that carried it — control channel registered over wss (<address>) — so nobgp service logs shows, with a timestamp, when a node moved onto the fallback.
The environment block is deviation-only: it is omitted entirely when nothing was detected, so on a clean machine you will not see it at all. Its absence is a healthy result, not a missing field.
Stock Windows Defender is filtered out of security_products deliberately — this is a report of deviations from a normal machine, not an inventory of everything installed.
If the node shows online but a peer is unreachable, run nobgp status on both ends — the interference is usually on exactly one of them.