Lawful privacy-focused publishing
Host a website anonymously from home with Cloudflare Tunnel and a VPN
This guide shows how to hide your home IP from visitors by publishing a local site through Cloudflare Tunnel and, if you want, routing cloudflared through a VPN first.
The privacy boundary matters: visitors do not need to learn your residential IP, but Cloudflare still knows your account and a VPN provider can still know that you are connecting to Cloudflare.
It is written for legitimate self-hosting, testing, publishing, and research. It does not support fraud, malware, phishing, harassment, or any other illegal activity.
Table of Content
What this setup actually protects
The practical goal is not to disappear from every provider. The goal is to stop ordinary visitors, scanners, and routine DNS lookups from learning your residential IP or reaching your router directly.
DNS can point at Cloudflare instead of a home address, so casual lookups do not reveal where the site is hosted.
A named tunnel is outbound only, so you do not need inbound port forwarding for the website itself.
Your site can stay on localhost or another private interface while Cloudflare handles public reachability.
This is privacy from visitors, not invisibility from Cloudflare, a VPN provider, or your own account trail.
Who can still identify you
The cleanest way to think about anonymous home hosting is to separate audiences. Each audience learns a different part of the story.
Visitors
- They can see your public hostname, TLS surface, and whatever content, headers, analytics, and cookies you intentionally expose.
- They usually see Cloudflare edge IPs instead of your home IP when DNS only points at the tunnel.
- They can still fingerprint the admin browser if you sign in to the same backend from the same device or browsing profile.
Cloudflare
- Cloudflare knows the account, zone, tunnel UUID, configured hostnames, and tunnel health state.
- Cloudflare also sees the source IP that cloudflared uses to connect, which is either your home IP or the VPN exit IP in front of it.
- A VPN can hide the residential source IP from Cloudflare, but it does not remove the Cloudflare account relationship.
VPN provider
- The VPN provider can still see that your device is maintaining encrypted traffic to Cloudflare.
- If the VPN is tied to your normal email or payment identity, that relationship still exists outside the tunnel.
- A VPN changes which source IP Cloudflare sees. It does not erase the trust you place in the VPN provider itself.
Your broader identity trail
- Domain registrar data, recovery mailboxes, payments, and reused usernames can still connect the project back to you.
- Logging into admin panels from a personal browser profile can correlate the site with your everyday identity.
- In practice, anonymity depends on operational discipline as much as on the tunnel itself.
How the traffic path works
The clean path is simple: the public side terminates at Cloudflare, while the private side remains a local service that only cloudflared can reach.
Requests your hostname and reaches Cloudflare's edge network.
Terminates HTTPS, applies rules, and forwards the request into the named tunnel.
Maintains outbound-only tunnel connections from your Windows machine back to Cloudflare.
Responds on localhost or another private origin address without being directly exposed to the internet.
If cloudflared uses a VPN first, Cloudflare sees the VPN exit IP as the connector source instead of your residential IP. If the VPN drops without a kill switch, cloudflared can reconnect over the normal ISP route.
What cloudflared.exe does on Windows
cloudflared.exe is not a VPN and not an anonymity network. It is the Cloudflare connector that authenticates a tunnel, keeps long-lived outbound connections open, and maps a public hostname to a local service.
You can log in once, create a named tunnel, and reuse it for a stable hostname instead of relying on throwaway links.
Cloudflare documents that each tunnel keeps multiple long-lived connections so the route stays resilient if one path drops.
A config file can send app.example.com to http://localhost:3000 without turning localhost into a public origin.
You can test the tunnel in a terminal first and later convert it into an always-on Windows service.
Cloudflare Tunnel can publish HTTP, HTTPS, TCP, SSH, RDP, and similar private services, but this guide stays focused on websites.
For the exact vendor workflow, compare your setup with Cloudflare local tunnel guide and the Windows service guide.
Windows setup: cloudflared.exe step by step
This path assumes a website already works locally and your domain is already using Cloudflare DNS. The example below uses app.example.com and a local service on port 3000.
Use PowerShell 7 for every command below. Replace the sample hostname, tunnel name, and local service before you copy anything.
Step 1: define the values you will reuse
Start in PowerShell 7 and replace the sample hostname, tunnel name, and local service with your own values before you continue.
$TunnelName = "ghostly-home-site"
$PublicHostname = "app.example.com"
$LocalService = "http://localhost:3000"
$CloudflaredHome = "C:\Cloudflared\bin"
$ConfigPath = "$env:USERPROFILE\.cloudflared\config.yml"Step 2: prepare cloudflared.exe
Rename the downloaded binary, create a dedicated folder for it, and copy the executable into that folder.
Rename-Item "$env:USERPROFILE\Downloads\cloudflared-windows-amd64.exe" "cloudflared.exe"
New-Item -ItemType Directory -Force $CloudflaredHome
Copy-Item "$env:USERPROFILE\Downloads\cloudflared.exe" "$CloudflaredHome\cloudflared.exe"Step 3: switch into the working folder and verify the binary
Move into the folder and confirm that cloudflared.exe starts cleanly before you authenticate anything.
Set-Location $CloudflaredHome
.\cloudflared.exe --versionStep 4: log in and authorize the Cloudflare zone
This opens the browser so you can approve the zone. The account certificate is written into your default .cloudflared directory.
.\cloudflared.exe tunnel loginStep 5: create the named tunnel and save its UUID
Create the tunnel, then paste the UUID from the command output into the variable below so the next commands can reuse it.
.\cloudflared.exe tunnel create $TunnelName
$TunnelId = "<paste-the-tunnel-uuid-from-the-create-output>"Step 6: write config.yml one line at a time
These commands build the local config.yml in your Windows profile so the tunnel knows which public hostname should forward to which local service.
Set-Content $ConfigPath "tunnel: $TunnelId"
Add-Content $ConfigPath "credentials-file: $env:USERPROFILE\.cloudflared\$TunnelId.json"
Add-Content $ConfigPath ""
Add-Content $ConfigPath "ingress:"
Add-Content $ConfigPath " - hostname: $PublicHostname"
Add-Content $ConfigPath " service: $LocalService"
Add-Content $ConfigPath " - service: http_status:404"Step 7: review and validate the configuration
Print the file once so you can check it, then let cloudflared validate the ingress rules before you publish DNS.
Get-Content $ConfigPath
.\cloudflared.exe tunnel ingress validateStep 8: create the DNS route and inspect the tunnel
This tells Cloudflare which hostname should target the named tunnel before you start serving live traffic.
.\cloudflared.exe tunnel route dns $TunnelName $PublicHostname
.\cloudflared.exe tunnel info $TunnelNameStep 9: run the tunnel in the foreground
Keep this PowerShell 7 window open while you test the site from another network. Stop it with Ctrl+C when you are done.
.\cloudflared.exe tunnel run $TunnelNameOnly do this after the interactive tunnel works. Run the commands below in an elevated PowerShell 7 window because the service uses the system profile path and service registry entry.
Service step 1: install the Windows service shell
Open an elevated PowerShell 7 window for this optional step and install the Cloudflared service first.
Set-Location $CloudflaredHome
.\cloudflared.exe service installService step 2: copy cert.pem, credentials, and config into the system profile
The Windows service runs under the system profile, so it needs its own .cloudflared folder with the certificate, tunnel credentials, and config.yml.
$SystemCloudflaredHome = "C:\Windows\System32\config\systemprofile\.cloudflared"
New-Item -ItemType Directory -Force $SystemCloudflaredHome
Copy-Item "$env:USERPROFILE\.cloudflared\cert.pem" "$SystemCloudflaredHome\cert.pem"
Copy-Item "$env:USERPROFILE\.cloudflared\$TunnelId.json" "$SystemCloudflaredHome\$TunnelId.json"
Set-Content "$SystemCloudflaredHome\config.yml" "tunnel: $TunnelId"
Add-Content "$SystemCloudflaredHome\config.yml" "credentials-file: $SystemCloudflaredHome\$TunnelId.json"
Add-Content "$SystemCloudflaredHome\config.yml" ""
Add-Content "$SystemCloudflaredHome\config.yml" "ingress:"
Add-Content "$SystemCloudflaredHome\config.yml" " - hostname: $PublicHostname"
Add-Content "$SystemCloudflaredHome\config.yml" " service: $LocalService"
Add-Content "$SystemCloudflaredHome\config.yml" " - service: http_status:404"Service step 3: point ImagePath at the system config and start the service
Cloudflare's Windows service documentation also requires the Cloudflared ImagePath to reference the system-profile config file.
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Cloudflared" -Name ImagePath -Value "C:\Cloudflared\bin\cloudflared.exe --config=C:\Windows\System32\config\systemprofile\.cloudflared\config.yml tunnel run"
sc.exe start cloudflaredThis mirrors Cloudflare's Windows service flow: copy cert.pem and the tunnel credentials into the system profile, write a system-profile config.yml, then point the Cloudflared service ImagePath at that config.
VPN placement and hardening rules
The tunnel is only as private as the route underneath it. If you want Cloudflare to see a VPN exit IP instead of a residential IP, the VPN has to be part of the connector path before cloudflared starts.
Verify the public IP on the host first. If the machine still shows the ISP IP, Cloudflare will see that same IP when the tunnel connects.
If the VPN drops and there is no firewall enforcement, cloudflared can reconnect over the normal residential route.
Bind the web service to localhost or a private interface when possible so the tunnel remains the only intended public path.
Cloudflare's documentation warns that debug logging can capture request URLs, methods, protocols, content lengths, and headers. Use normal logging in everyday operation.
Optional VPN picks and comparison
Want a quick VPN shortcut or a broader comparison?
If you want a simple starting point, the rotating VPN button below opens one current option. If you want to compare many alternatives first, use the full provider directory instead.
Current rotating pick: Proton VPN
If the tunnel stops while the DNS record remains active, visitors typically see a Cloudflare error until the connector comes back. That is noisy but still better than silently leaking a home IP.
Verification checklist before you trust it
Do not assume the setup is private just because the site loads once. Check the route like an operator, not like a marketer.
A quick external lookup should show Cloudflare-facing records rather than a residential address.
Check the machine's public IP first so you know what Cloudflare will see on the connector side.
Test from mobile data or another external network so you are not fooled by a local routing shortcut.
Simulate the failure case once. If cloudflared reconnects over the ISP route, the privacy model is broken.
When GhostlyShare is the easier route
If you only need a temporary public preview, a quick client demo, or a webhook callback URL, GhostlyShare is the simpler route. It avoids most of the manual Cloudflare dashboard, DNS, and config.yml work.
Use manual cloudflared when you want full control over the tunnel, DNS, service account path, and longer-running home hosting. Use GhostlyShare when speed matters more than infrastructure ceremony.
See GhostlyShareFrequently asked questions about anonymous home hosting
Does Cloudflare still know who I am
Yes. Cloudflare still knows the account, zone, tunnel, and the source IP that reaches its edge. A VPN can replace the residential source IP Cloudflare sees, but it does not remove the Cloudflare account relationship.
Do visitors see my home IP address
Normally they should not if your DNS only points to Cloudflare and you have not exposed the origin in another way. Visitors reach the Cloudflare edge and the public hostname, not the residential IP behind the tunnel.
Do I need router port forwarding
No. Cloudflare Tunnel is outbound only, so the connector reaches out to Cloudflare instead of waiting for inbound traffic from the internet.
Can I run cloudflared.exe only when I need it
Yes. Run the tunnel interactively from PowerShell when you only need the site temporarily. Convert it into a Windows service only when you want the route to stay available after logoff or reboot.
What happens if the VPN drops
Without a kill switch, cloudflared can reconnect over the normal residential route and Cloudflare will then see the home ISP IP. That is why the failure case matters as much as the success case.
Is this enough to make the whole project anonymous
No. Domain registration, payments, recovery emails, browser fingerprints, and admin behavior can still identify you. The tunnel only solves one part of the exposure problem.
Related guides
Read the network layer basics before you depend on a VPN to hide the source IP that Cloudflare sees.
Guide Check Your Online Fingerprint and Tracking ExposureUse the fingerprint page to reduce browser-side clues that can still correlate your admin sessions.
Tool GhostlyShare: share localhost on Windows and LinuxUse the simpler desktop route when you want a public preview link without manually building the full Cloudflare workflow.
Directory VPN providers worldwide: compare audits, privacy, and fitUse the full VPN directory if you want to compare many providers before choosing one for the tunnel route.