Routing blog.huislab.app through Nginx Proxy Manager
/ 2 min read
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.apptells Cloudflare this is a request forblog.huislab.app, which matches the Worker route configured in Cloudflare DNS proxy_ssl_server_name onenables SNI so the TLS handshake uses the correct hostnameproxy_ssl_name blog.huislab.appsets 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
bitsandbytesWorker → returns the blog
This works identically from:
- Local network ✅
- WireGuard VPN ✅
- Public internet (via Cloudflare directly) ✅