Private access and GRC · Part 1 of 2

Comparing who can reach what with Twingate and NetBird

Getting onto my lab network was only half the question. I wanted to explain which person or device could reach a particular service, and why. Twingate and NetBird gave me two ways to think about that boundary.

Getting onto my lab network was only half the question. I wanted to be able to explain which person or device could reach a particular service, and why. Twingate and NetBird gave me two ways to think about that boundary, and running both made the difference between them easier to see.

Both are running in my lab record of 8 November: the Twingate connector in LXC 208 and NetBird in LXC 204. The groups, resources and ports below are from that record. The denied cases are marked as examples until I run them, because I describe a boundary as enforced only after testing both sides of it.

Two models of the same question

Twingate starts from the user. A signed-in person on an enrolled device asks for a named Resource, such as the Proxmox console. A Resource policy and the groups granted to that Resource decide whether the client offers a route at all. The Connector inside the lab makes outbound connections only, so nothing on the WAN side has to listen.

NetBird starts from the device. Each machine is an enrolled peer, and policies say which peer groups may talk to which. A routing peer can forward traffic to networks behind it, so a destination does not need NetBird installed. That is the difference worth drawing carefully: a service on the peer itself and a resource behind a routing peer are reached in different ways.

Twingate access
  1. Remote laptopenrolled client · Example
  2. WANISP, behind CGNAT · Configured
  3. Laptop uplinkonboard NIC · Configured
  4. WAN bridgevmbr0 · Configured
  5. Sophos FirewallVM 102 · Running
  6. LAN bridgevmbr1 · untagged · Configured
  7. TwingateLXC 208 · Running
  8. Proxmox web UITCP 8006 · Running
Lab map · addresses and hostnames left out

The connector’s outbound session to Twingate crosses Sophos. The last hop, from the connector to the Proxmox UI, stays on the LAN bridge and never meets the firewall, so the grant itself is the control.

Open the full lab console

Allowed and denied, on purpose

A boundary only means something once both answers have been tried. For each tool I keep one request that should succeed and one that should not, so I can show the reason for each.

Two ways to answer “who can reach what, and why”. Groups, resources and ports are from my lab record; each denied case is marked as an example until I run it.

Twingate

User to Resource, through a Connector

  1. Admin laptopsigned-in user
  2. Homelab-ADMINgroup grant
  3. ConnectorLXC 208 · outbound only
  4. Proxmox web UITCP 8006 · UDP, ICMP blocked

Member of Homelab-ADMIN

Connected · from my record

The group is granted the Proxmox resource on TCP 8006, and I confirmed the UI loads through the client. Sophos web admin on TCP 4444 is granted the same way.

NetBird

Enrolled peer to resource, through a routing peer

  1. Admin laptoppeer in Admin-Devices
  2. Access policyTCP 8006 and 4444 only
  3. Routing peerLXC 204 · masquerade on
  4. Proxmox web UITCP 8006

Peer in Admin-Devices

Connected · from my record

A one-way policy lets Admin-Devices reach the Proxmox and Sophos web UIs on TCP 8006 and 4444 through the routing peer. I confirmed browser access from outside home.

Switch each card between the allowed and the denied example. The denied NetBird request only stays denied once the broad default policy, which lets every peer reach every other peer, has been removed.

Open the full lab console

The NetBird default policy is the trap I watch for. A fresh setup allows all peers to reach all peers, which is convenient while enrolling devices and quietly undoes any boundary drawn on a diagram. In my record it is disabled, and the Admin-Devices policy allows only TCP 8006 and 4444, so ping failing is expected rather than a fault.

Keeping the paths apart

There are three different kinds of path in this lab, and I keep them on separate lines so none gets credit for what another does:

  • Joining a network, which is what 802.1X would decide on Wi-Fi.
  • Reaching a private service, which is what Twingate and NetBird decide.
  • Reaching the public journal, which goes through Cloudflare’s WAF and a named tunnel to the DMZ.
NetBird access
  1. Remote laptopenrolled client · Example
  2. WANISP, behind CGNAT · Configured
  3. Laptop uplinkonboard NIC · Configured
  4. WAN bridgevmbr0 · Configured
  5. Sophos FirewallVM 102 · Running
  6. LAN bridgevmbr1 · untagged · Configured
  7. NetBirdLXC 204 · Running
  8. Proxmox web UITCP 8006 · Running
Lab map · addresses and hostnames left out

NetBird’s path ends at the routing peer, which masquerades the traffic onto the LAN, so the Proxmox UI sees the peer’s LAN address rather than the remote laptop’s.

Open the full lab console

What I learned

Running both tools side by side taught me to describe access as a sentence with three parts: who (a user in a group, or a peer in a group), what (a named resource and port), and why (the grant or policy that allows it). Twingate makes me write the who as a person; NetBird makes me write it as a device. The NetBird default policy was the lesson in one line: a boundary drawn on a diagram means nothing while an allow-all rule sits underneath it.

Takeaway: for every private resource, keep three pieces of evidence together: the grant that allows it, a request that succeeded, and a request from outside the grant that failed. The first two show that access works; only the third shows the boundary exists.

Further reading: Twingate Resources · Twingate Resource policies · NetBird access policies · How NetBird routing peers work

Skills used

  • User-based and device-based access models
  • Testing an allowed and a denied request
  • Spotting a default allow-all policy

All skills, grouped by what job postings ask for

Tools in this entry

Every tool and its documentation