Published 2026-07-28 by TechNet New England
WireGuard is fast, small, and easy to deploy, until it isn't. A tunnel that shows steady outbound traffic but zero bytes received is one of the most common and most frustrating states to land in. This guide covers the correct way to install WireGuard as a Windows service, how to handle the config file securely after import, and how to methodically diagnose a missing handshake without chasing symptoms.
Installing WireGuard as a Managed Windows Service
The WireGuard Windows client can run interactively per user, but for endpoints where the tunnel should be always on and survive reboots, it should be installed as a Windows service. This is the same mechanism the WireGuard GUI uses internally, exposed as a command line switch.
Open PowerShell or Command Prompt as Administrator and run:
& "C:\Program Files\WireGuard\wireguard.exe" /installtunnelservice "C:\Path\To\Client.conf"
Start the tunnel:
Start-Service "WireGuardTunnel$TunnelName"
Verify it is running:
Get-Service "WireGuardTunnel$TunnelName"
Remove it later:
& "C:\Program Files\WireGuard\wireguard.exe" /uninstalltunnelservice TunnelName
The service name always follows the pattern WireGuardTunnel$<TunnelName>, where <TunnelName> matches the base filename of the .conf you imported. Reference: WireGuard for Windows documentation.
What Happens to the .conf File After Import
A common concern from security minded operators is whether the original .conf file needs to stay in place after installation. The answer is no, and it should not.
Once /installtunnelservice runs, WireGuard imports the configuration into its protected configuration store at:
C:\Program Files\WireGuard\Data\Configurations\
The imported configuration is stored as an encrypted .conf.dpapi file. That location is protected by NTFS permissions and the Windows Data Protection API (DPAPI), which binds the encryption to the machine account. Reference: Microsoft DPAPI documentation.
After confirming the tunnel service exists, securely delete the original plaintext .conf:
Remove-Item "C:\Path\To\Client.conf" -Force
Do not manually copy the plaintext .conf into the Configurations directory. Use the installtunnelservice command so WireGuard performs the DPAPI wrap correctly.
The Silent Handshake Problem
After a correct install, the tunnel may appear active but never complete a handshake. Running wg show reveals the signature:
0 B received
2.02 KiB sent
The client is transmitting handshake initiations. The server is not responding. This is almost always a network path issue, not a WireGuard configuration issue. Before touching the tunnel config again, prove where the packets are actually dying.
Rule Out the Client Network First
Move the client to a completely independent uplink, such as a mobile hotspot, then restart the tunnel:
Restart-Service 'WireGuardTunnel$TunnelName'
Start-Sleep 10
wg show
If the tunnel handshakes on the hotspot, the client's normal network is blocking UDP 51820 outbound. This is common on guest Wi-Fi, hotel networks, corporate segments with strict egress filtering, and some residential ISPs that block non-standard UDP ports.
If it still shows zero bytes received on the hotspot, the problem is upstream at the WireGuard server or somewhere along the return path.
Confirm Packets Reach the Server
The definitive test is a packet capture on the WireGuard server's WAN interface while the client attempts to reconnect. If the server runs on pfSense:
- Navigate to Diagnostics > Packet Capture.
- Interface: WAN
- Address Family: IPv4
- Protocol: UDP
- Host Address: the client's public IP
- Port: 51820 or your configured listen port
- Packet Count: 50
- Level of Detail: Normal
- Start the capture, then restart the client tunnel from the client.
- Stop and review the capture.
The equivalent from the pfSense shell:
tcpdump -ni <WAN_INTERFACE> "udp port 51820 and host <CLIENT_PUBLIC_IP>"
Replace <WAN_INTERFACE> with the actual interface name, such as vtnet0. Reference: pfSense packet capture documentation.
Interpreting the Capture
No packets from the client appear: the traffic never reaches the server. The client's network, the client's ISP, or an upstream firewall is dropping outbound UDP 51820. Confirm the server's WAN IP has not changed and that UDP 51820 is allowed inbound on the WAN interface firewall rules.
Packets from the client arrive but the server does not reply: the traffic reaches pfSense but WireGuard is either not listening on the expected port, the peer configuration does not match the client's public key, or the tunnel is disabled. Check the WireGuard service status on the server and verify the peer's public key exactly matches what the client is presenting.
Packets arrive and the server replies but the client still shows 0 B received: the return path is broken. Something between the server's WAN and the client is dropping the reply. This is often stateful firewall behavior at the client's edge router, an aggressive endpoint security suite (some EDR products silently drop unsolicited UDP), or asymmetric routing at the ISP.
ICMP ping to the server's public IP is not a valid test. Most WAN configurations either block ICMP or rate limit it, so a failed ping tells you nothing about whether UDP 51820 is reachable.
Testing RDP Through the Tunnel
Once the handshake completes, verify that expected services are reachable. To test Remote Desktop connectivity with PowerShell without opening the client:
Test-NetConnection <RDP_HOST_IP> -Port 3389 -InformationLevel Detailed
The key line in the output is:
TcpTestSucceeded : True
If that returns False despite a working handshake, the tunnel is up but routing or ACLs are preventing traffic to that host. Check AllowedIPs on the client, routing tables on the server, and any firewall rules on the destination subnet.
Trace the path to see where traffic is going:
Test-NetConnection <RDP_HOST_IP> -TraceRoute
Launch an actual RDP session:
mstsc /v:<RDP_HOST_IP>
Reference: Microsoft Test-NetConnection documentation.
Prevention: Ship VPN Endpoints With a Deployment Runbook
Most silent handshake incidents are not WireGuard problems. They are visibility problems. The technician does not know whether the tunnel packets are leaving the client, reaching the server, or being answered. Every remote worker VPN deployment should ship with:
- A documented listen port and the specific outbound firewall rule required at the client site.
- A one command hotspot test the user can run without support.
- Server side packet capture procedures documented for whoever owns the perimeter.
- A rule to never modify a working client config as a first response. Prove where packets die first, then change the smallest number of things possible.
When to Call a Professional
If a WireGuard tunnel fails to handshake, packet captures on both ends confirm packets flowing in both directions, and the client still shows zero bytes received, the fault is almost certainly in a stateful device between the two endpoints. Enterprise firewalls, upstream ISP CGNAT, and endpoint security products can all produce this behavior in ways that are not obvious from the client. If you are past the basic diagnostics and the tunnel still will not come up, a fresh set of eyes on the network path is faster than more guesswork.
TechNet New England deploys and manages secure remote access for small and mid-sized businesses across Massachusetts and New England. If your VPN is unreliable, silent failing, or has never been properly documented, contact us for a review.