skip to content
BitsAndBytes
Table of Contents

The Problem

blog.huislab.app is hosted on Cloudflare Workers (via bitsandbytes.huislab.workers.dev). It worked fine from the public internet and the local network, but failed when connected via WireGuard VPN.

The root cause: WireGuard uses my UniFi gateway (192.168.1.155) as its DNS server, and the huislab.app zone is locally overridden so every *.huislab.app subdomain resolves to Nginx Proxy Manager. NPM didn’t have a proxy host configured for blog.huislab.app, so the request died there before ever reaching Cloudflare.

There was no clean DNS-only fix. Adding 1.1.1.1 as a secondary DNS in WireGuard would route around the split-horizon, but then local hostnames like z2m.huislab.app stopped resolving.

The Solution

Route blog.huislab.app through Nginx Proxy Manager (running at 192.168.1.155) — the same way all other *.huislab.app subdomains are handled. This makes resolution consistent regardless of whether the client is local or on VPN.

Nginx Proxy Manager Config

Details tab:

  • Domain Name: blog.huislab.app
  • Scheme: https
  • Forward Hostname: bitsandbytes.huislab.workers.dev
  • Forward Port: 443
  • Cache Assets: on
  • Block Common Exploits: on
  • Websockets Support: on
  • Access List: Publicly Accessible

SSL tab:

  • SSL Certificate: *.huislab.app (wildcard, already existed)
  • Force SSL: on

Advanced tab:

proxy_set_header Host blog.huislab.app;
proxy_ssl_server_name on;
proxy_ssl_name blog.huislab.app;

Why the Advanced Config Matters

Without these directives, nginx sends the wrong Host header to Cloudflare. Cloudflare uses the Host header to route requests to the correct Worker. Without it:

  • Default behavior sends the forward hostname (bitsandbytes.huislab.workers.dev) as the Host header → Cloudflare returns 403 because there’s no Worker route for that domain
  • Setting Host blog.huislab.app tells Cloudflare this is a request for blog.huislab.app, which matches the Worker route configured in Cloudflare DNS
  • proxy_ssl_server_name on enables SNI so the TLS handshake uses the correct hostname
  • proxy_ssl_name blog.huislab.app sets the SNI hostname explicitly

Cloudflare Workers

The .workers.dev URLs (bitsandbytes.huislab.workers.dev) are disabled (set to Inactive) in Cloudflare Workers → Domains. Only the custom domain blog.huislab.app is active. The .workers.dev hostname still resolves (nginx uses it as a forward target), but it won’t serve content if accessed directly in a browser.

Cloudflare DNS

The Cloudflare DNS record for blog.huislab.app remains as-is:

  • Type: Worker
  • Name: blog.huislab.app
  • Content: bitsandbytes
  • Proxy status: Proxied

How It Works Now

  • Browser → blog.huislab.app → resolves to nginx (192.168.1.155) via local DNS
  • Nginx → forwards to Cloudflare Workers over HTTPS with correct Host header
  • Cloudflare → routes to the bitsandbytes Worker → returns the blog

This works identically from:

  • Local network ✅
  • WireGuard VPN ✅
  • Public internet (via Cloudflare directly) ✅