QuickZTNA User Guide
Home WireGuard WireGuard Tunnel Functioning

WireGuard Tunnel Functioning

What We’re Testing

Once machines are enrolled, they should automatically form WireGuard tunnels. This chapter verifies the full lifecycle:

  1. Registration — Machine registers with the control plane and gets a tailnet IP
  2. Tunnel establishment — WireGuard session starts between peers
  3. Peer visibility — Each machine can see the others via ztna peers
  4. DERP relay selection — Which DERP node is chosen for relay, and why
  5. End-to-end connectivity — Traffic flows from Win-A → Win-B via the mesh

Your Test Setup

All three machines enrolled and online. Dashboard → Machines shows all three with status online.


ST1 — Machine Registration and Tailnet IP Assignment

What it verifies: After enrollment, each machine has a unique tailnet IP in the 100.64.0.0/10 range.

Steps:

  1. On Win-A , check the assigned tailnet IP:
ztna ip
  1. On Win-B :
ztna ip
  1. On 🐧 Linux-C :
ztna ip
  1. Confirm in the dashboard: Machines page → each machine row shows IP column.

Expected output:

Win-A:   100.64.0.1   (example — your actual IPs will differ)
Win-B:   100.64.0.2
Linux-C: 100.64.0.3

All IPs must be:

  • In the 100.64.0.0/10 range (CGNAT block)
  • Unique — no two machines share the same IP
  • Persistent across restarts

Pass: All three machines have distinct IPs in 100.64.0.0/10, matching the dashboard.

Fail / Common issues:

  • ztna ip shows nothing → machine may not be connected; run ztna up
  • IP not in 100.64.0.0/10 → unusual configuration; check org settings in dashboard

ST2 — Peer Visibility (All Machines See Each Other)

What it verifies: Each machine’s peer table contains the other two machines.

Steps:

  1. On Win-A , list peers:
ztna peers
  1. On 🐧 Linux-C :
ztna peers

Expected output on Win-A:

NAME                 TAILNET IP      DERP REGION  DIRECT?  ROUTES  ENDPOINT
Win-B                100.64.0.2      lon1         relay    —       [DERP]
Linux-C              100.64.0.3      blr1         relay    —       [DERP]

Expected output on Linux-C:

NAME                 TAILNET IP      DERP REGION  DIRECT?  ROUTES  ENDPOINT
Win-A                100.64.0.1      blr1         relay    —       [DERP]
Win-B                100.64.0.2      lon1         relay    —       [DERP]

Pass: Both machines’ peer tables show all other enrolled machines as online.

Fail / Common issues:

  • A peer shows as offline → check if that machine has ztna up running
  • A peer is missing entirely → check if it’s enrolled in the same org; run ztna switch --list to confirm
  • Peer count is 0 → org may have only 1 machine; verify all 3 are enrolled

ST3 — DERP Relay Selection

What it verifies: When direct P2P isn’t possible (both machines behind NAT), traffic routes through the nearest DERP node. QuickZTNA has 4 DERP nodes: blr1 (Bangalore), nyc1 (New York), lon1 (London), sfo3 (San Francisco).

Steps:

  1. On Win-A (India), check which DERP is selected for the Win-B peer:
ztna peers
# Note the "Relay" column for Win-B
  1. On Win-B (Europe), check which DERP is selected for Win-A:
ztna peers
# Note the "Relay" column for Win-A
  1. Check DERP health (from any machine):
curl -s https://login.quickztna.com/api/derp-health | python3 -m json.tool

Expected output:

Win-A (India) peer table:
  Win-B via relay: blr1.derp.quickztna.com   ← nearest DERP to Win-A

Win-B (Europe) peer table:
  Win-A via relay: lon1.derp.quickztna.com   ← nearest DERP to Win-B

Note: Each side may pick a different DERP — this is normal. Traffic flows: Win-A → blr1 → lon1 → Win-B (relay-to-relay forwarding).

Pass: A DERP node appears in the Relay column. The node name roughly matches the geography of the machine (blr1 for India, lon1 for Europe, etc.).

Fail / Common issues:

  • Relay column is empty and Direct is false → tunnel may be establishing; wait 30s and check again
  • DERP health returns 500 → DERP nodes may be down; check login.quickztna.com/api/health

ST4 — End-to-End Ping Through the Mesh

What it verifies: Win-A can actually send traffic to Win-B through the WireGuard mesh, via DERP or direct.

Steps:

  1. On Win-A , get Win-B’s tailnet IP (from ST1 or ztna peers).

  2. Ping Win-B:

ztna ping 100.64.0.2 --count 5
  1. Ping Linux-C:
ztna ping 100.64.0.3 --count 5
  1. From 🐧 Linux-C , ping both Windows machines:
ztna ping 100.64.0.1 --count 5
ztna ping 100.64.0.2 --count 5

Expected output:

PING Win-B (100.64.0.2)
  probe 1: 52ms (tunnel)
  probe 2: 48ms (tunnel)
  probe 3: 55ms (tunnel)
  probe 4: 51ms (tunnel)
  probe 5: 49ms (tunnel)
5/5 probes succeeded, avg latency: 51ms (via tunnel)

PING Linux-C (100.64.0.3)
  probe 1: 14ms (tunnel)
  probe 2: 15ms (tunnel)
  probe 3: 13ms (tunnel)
  probe 4: 16ms (tunnel)
  probe 5: 14ms (tunnel)
5/5 probes succeeded, avg latency: 14ms (via tunnel)

Latency will vary by distance and whether traffic is relayed or direct.

Pass: 0% packet loss to all peers. Response times are reasonable (under 300ms for relay, under 50ms for same-region).

Fail / Common issues:

  • 100% packet loss → check ztna up is running on the target machine
  • High latency (> 500ms) → check which DERP is selected; may be routing suboptimally
  • ztna ping: command not found → update ztna to v3.0+

ST5 — Direct P2P vs DERP Relay

What it verifies: Linux-C has a public IP. When Win-A connects to Linux-C, WireGuard may be able to form a direct P2P tunnel (bypassing DERP) since one side has a public IP.

Steps:

  1. On Win-A , check the peer entry for Linux-C:
ztna peers
# Look at Direct column for Linux-C
  1. Wait 30–60 seconds after initial connection (direct connection may take a moment to establish):
# Ping to generate traffic (helps NAT hole-punch)
ztna ping 100.64.0.3 --count 10
ztna peers
# Check Direct column again

Expected output:

# Initial state (DERP relay):
NAME                 TAILNET IP      DERP REGION  DIRECT?  ROUTES  ENDPOINT
Linux-C              100.64.0.3      blr1         relay    —       [DERP]

# After NAT hole-punch succeeds:
NAME                 TAILNET IP      DERP REGION  DIRECT?  ROUTES  ENDPOINT
Linux-C              100.64.0.3      blr1         direct   —       178.62.x.x:41641

Pass: DIRECT? column shows direct for Linux-C and ENDPOINT shows a public IP:port. Win-A ↔ Win-B stays relay (both behind NAT).

Fail / Common issues:

  • Direct never establishes → some NAT types block incoming UDP even when the other side has a public IP; DERP relay is the correct fallback
  • Both peers show direct=false and relay → acceptable if NAT blocks direct; measure latency with ztna ping to verify relay is working

Summary

Sub-testWhat it provesPass condition
ST1Tailnet IPs assignedEach machine has unique IP in 100.64.0.0/10
ST2Peer visibilityAll peers appear in each machine’s peer table
ST3DERP relay selectionDERP node shown in Relay column, matches geography
ST4End-to-end ping0% packet loss to all peers via mesh
ST5Direct P2P vs DERPLinux-C (public IP) shows direct=true from Win-A