Virtualization, Cloud, Infrastructure and all that stuff in-between

My ramblings on the stuff that holds it all together

Tag Archives: homelab

A low-cost UniFi-to-Azure WireGuard VPN for CGNAT and dual-WAN failover

I wanted a straightforward, low-cost VPN between my UniFi network and Azure, but my home Internet connection is behind carrier-grade NAT (CGNAT). I have published the resulting deployment scripts and configuration guide on GitHub.

Why CGNAT changes the VPN design

CGNAT means the ISP shares one public IPv4 address between multiple customers. My router receives a private address inside the ISP network, and there is another NAT boundary controlled by the ISP. I cannot forward an inbound port through that outer NAT or depend on having a public address that identifies my connection.

That rules out the conventional site-to-site IPsec design I was replacing, because it expects the home VPN endpoint to have a directly reachable and stable public IP address. Even on a connection that supplies public IPv4, an address assigned by DHCP may change and make an IP-based peer definition unreliable. Some IPsec products support NAT traversal or dynamic peers, but both ends must support the necessary design.

WireGuard avoids that dependency here because the UniFi gateway initiates the tunnel outbound to a static public endpoint in Azure. The return traffic follows the NAT state created by that outbound connection, so no inbound port forwarding or public IPv4 address is required at home.

The Azure endpoint

The project deploys a small Ubuntu VM with a static Azure public IP, installs WireGuard, configures routing, and generates a WireGuard client profile ready to import into UniFi Network. The VM provides a routed path between the home LAN and private Azure workloads. It is cheaper than an Azure VPN Gateway and offers compatibility with a home connection behind CGNAT.

The tradeoff is that you own the operating system terminating the VPN. You need to be comfortable patching, hardening, monitoring, and troubleshooting the VM throughout its lifetime. The deployment enables unattended security updates, but that does not remove the operational responsibility.

Persistent keepalive maintains the NAT mapping, while WireGuard endpoint roaming allows the Azure peer to learn the latest public source address and UDP port used by the UniFi gateway.

Restricting Internet exposure

Only the WireGuard UDP port needs to be reachable from the Internet. The deployment restricts it in the Azure Network Security Group to public source networks supplied for the relevant ISPs.

A single /32 is the best option for a static address. With DHCP or CGNAT, that address may change, so use the narrowest stable public range that the ISP confirms it may assign. This is broader than one address but substantially better than exposing the VPN port to the whole Internet.

SSH is opened to the deploying computer only during bootstrap and is removed automatically afterward. Once the tunnel is configured, SSH is available over the VPN only. The appliance is deliberately disposable: if recovery is not possible through the VPN or Azure management tools, it can be deleted and redeployed.

Configuring the UniFi side

The deployment creates a pre-generated configuration file containing the keys, tunnel addresses, Azure endpoint, and Azure routes. The repository documentation shows how to import it as a UniFi WireGuard VPN Client and create a basic policy route.

Importing the profile establishes the tunnel, but it cannot decide how every home network should use it. You still need to understand and adapt your LAN-side routing, including which clients or VLANs may reach Azure, firewall and isolation policies, return paths, and overlapping private address ranges.

Primary and secondary Internet failover

The same design works with UniFi primary and secondary WAN failover. In my case the primary service is symmetric gigabit fibre and the backup is a 200 Mbit cable broadband connection in the UK.

When UniFi detects that the primary WAN has failed, it moves outbound traffic to the backup. WireGuard sends a new handshake through that connection, and the Azure peer learns the new translated endpoint. The VPN profile does not need separate peer definitions for each WAN, but the Azure NSG must allow the possible public egress range of both ISPs.

Testing failover

I tested this by running a continuous ping from the home LAN to a private address in Azure, then disabling or physically unplugging the primary Internet connection. UniFi selected the backup connection, WireGuard re-established the tunnel, and only a few pings were lost during the transition.

The exact interruption depends on UniFi health-check timing and the two Internet services. After failover, the WireGuard handshake and transfer counters on the Azure VM provide a useful confirmation that traffic is using the new endpoint. Restoring the primary connection lets you repeat the same check in the other direction.

Scripts and full configuration

The generic deployment scripts, refreshed architecture and failover diagrams, security guidance, UniFi configuration steps, and troubleshooting notes are available in the public repository:

github.com/vinfnet/unifi-azure-vpn-vmbased