Windows 8.1, Cloudflare DNS, and Caddy as a reverse proxy

So I’ve been attempting to set up Caddy to reverse proxy to various services that I’m running on my PC.

The general setup is that I’m always running a VPN on the machine, but I want to still reverse proxy to my services using Caddy for remote access. Because of this, I have to use port 10443 instead of 443, since the VPN can only port forward on numbers higher than 2048. Also, I have a domain name from Google Domains, and I’m using Cloudflare DNS.

Here are the general instructions I followed:

Here is my Caddyfile (note that some line items are commented out):

Here is my common.conf file (note that some line items are commented out):
https://pastebin.com/dQDXKpux

For whatever reason I’m not able to remotely connect to the URLs specified at the bottom of the instructions. Any ideas on what might be set up improperly? Additionally, my goal is for renew on the HTTPS SSL cert to work automatically in the future. Hence why I’m trying to verify it through the DNS challenge (since I’m on port 10443 and not 443).

Config mostly looks good to me, instructions are pretty straightforward. Without spinning up a Windows VM, a VPN, and replicating the instructions, I’m not sure off the top of my head what might be going awry.

What’s the problem, exactly? Can you give us some output or an error message? Are you getting timeouts here (no connectivity) or some error from Caddy (or your VPN)?

What kind of output is Caddy giving you when you start it up? Does it make it through the cert request and DNS verification OK?

So checking it on my phone (when it’s off the home network), I get the following errors:

https://[domain_name]/sonarr – “Error 525 SSL handshake failed”
https://www.[domain_name]/sonarr – “This site can’t be reached. [domain_name]'s server DNS address could not be found. DNS_PROBE_FINISHED_NXDOMAIN”
https://[domain_name]:10443/sonarr – “This site can’t be reached. [domain_name] took too long to respond. ERR_TIMED_OUT”
https://www.[domain_name]:10443/sonarr – “This site can’t be reached. [domain_name]'s server DNS address could not be found. DNS_PROBE_FINISHED_NXDOMAIN”

I’m not visually seeing any feedback from Caddy or my VPN - how do I best go about checking for errors within them specifically?

So now that Caddy is installed as a Windows service, I don’t see any feedback/output in a command prompt. If I was to manually start Caddy via the ‘cd c:\caddy’ and ‘caddy’ commands, I see the following:

Activating privacy features… done.
https://[domain_name]
https://[domain_name]:10443
http://localhost
http://[domain_name]

Then a few moments later:
-0400 [ERROR 502 /json] dial tcp 127.0.0.1:8112: connectex: No connection could be made because the target machine actively refused it.

OK, there’s a bit here to unpack, so bear with me. I will use example.com to refer to your domain.

This site can't be reached. [domain_name]'s server DNS address could not be found. DNS_PROBE_FINISHED_NXDOMAIN

The common factor I’m seeing with this error is that you’re trying to connect to www.example.com instead of example.com. Does your www subdomain have a valid A record? If you only set it recently, it may take a while for DNS resolvers to propagate the update. As it is, your phone doesn’t think there’s a DNS entry for it.

Error 525 SSL handshake failed

This is a CloudFlare specific error, indicating that CloudFlare’s proxy server couldn’t connect to your origin server because it couldn’t successfully negotiate TLS with it. This could indicate some issue with Caddy. At the moment, CloudFlare will impede further attempts to learn more (by hiding the actual issue with 525 errors), so you should “grey-cloud” the A record for example.com and try again (connecting directly to Caddy instead of through CloudFlare’s proxy network).

This site can't be reached. [domain_name] took too long to respond. ERR_TIMED_OUT

This error is occuring on requests on port :10443. Since example.com is covered by CloudFlare’s proxy network (indicated by an “orange-cloud” DNS record), you’re not actually connecting to your own server, you’re connecting to CloudFlare (who then connect to your server on your behalf). CloudFlare does not proxy or even respond on ports other than :80 and :443. Again my recommendation is to “grey-cloud” your DNS records and try again.

I see from your configuration that you are proxying to Deluge at 127.0.0.1:8112. An actively refused connection could be a zealous firewall, a misconfigured Deluge instance, or something else.

There may or may not be logs available from your VPN provider. Caddy can be configured to log access attempts and errors to files of your choosing. Checking your common.conf, it looks like it’s trying to log to /caddy/logs/access.log and /caddy/logs/error.log, which I believe will fail on a Windows system (this directory structure is *nix-specific). You should change them - perhaps to C:\caddy\access.log and C:\caddy\error.log or similar. You can then open the files with something like Notepad and read the log entries.

2 Likes

At the moment, no. I’m still very new to all of this, so I just created the one A record for [domain_name].com that points to my external IP (in my case the external IP of my VPN, which is always on). Do I just need to set up a new A record for www.[domain_name].com that points to the same external IP? Or do I just put ‘www’ in the ‘name’ column of that new A record?

Would you be able to elaborate on how I connect directly through Caddy? I’ve just grey-cloud’ed the A record I have in Cloudflare - does it take a while to propogate? Apologies for my “new-ness” on all of this.

Well you’re right about it failing on a Windows system. I ended up using the following lines in my common.conf file (if you check the common.conf again, you’ll notice that the lines you reference are commented out). I believe the lines I have un-commented are working, as both a log and error file are being generated in C:\caddy\

I appreciate your help on this!

You can cheat a little to keep things simple - make a CNAME record, with the name www, and use example.com for the value. Then if your VPN ever changes, you only need to change the A record for example.com, and www will update with it.

I regularly use random subdomains on a whim, so I personally have a CNAME of * (a wildcard, matches any) with a value of example.com, so any subdomain I haven’t already specified defaults to the same server (the one I usually test stuff on). That covers my www.

Yes - while a record has an orange cloud, CloudFlare DNS does not actually give people the IP address you give CloudFlare. Instead, CloudFlare hands out their own IP address, then they connect to you from their own server. This usually has significant security and bandwidth benefits, but obviously masks issues that might arise.

Changing between orange and grey cloud records takes the same amount of time as a normal DNS propagation, because that’s exactly what they’re doing - swapping back from their own IP to your actual IP. Once the DNS has updated (and CloudFlare starts handing out your actual IP address for DNS requests), you will be connecting directly to your VPN, which should connect you straight to Caddy, and any errors you’ll be getting will be straight from Caddy, too.

Can’t believe I missed that, whoops! Yep, those two files are the ones you’ll want to watch if you’re not seeing expected behaviour.

Got it.

I currently have two records in Cloudflare now. Both are grey-clouds.

Type: A, Name: [domain_name].com, Value: Points to [VPN External IP], TTL: Automatic
Type: CNAME, Name: www, Value: is an alias of [domain_name].com, TTL: Automatic

I’ll give them some time to propagate, but do I need to do anything further inside Google Domains? In the DNS settings inside Google Domains, I currently still have it using the custom name servers from Cloudflare, and the only line item under ‘Registered Hosts’ is:
Host Name: [domain_name].com, IPV4 Address: [VPN External IP], IPV6 Address: [Blank]

I’ve left everything blank under ‘Custom Resource Records’ inside Google Domains, since I added those records inside Cloudflare instead. DNSSEC and Synthetic Records are both blank inside Google Domains.

As for further Cloudflare settings, SSL is set to ‘Full (Strict)’, but I have not done anything with Edge or Origin Certificates. HSTS is disabled, Authenticated Origin Pulls is Off, Opportunistic Encryption is On, Auto HTTPS Rewrites is Off. Security level is Medium.

Also, if the logs would help diagnose, any way I can DM them to you? I think they contain API keys for some of my services.

No, the only records that matter for your registrar are the nameservers. Every other record (other than glue records, a whole other story) only matters in your CloudFlare configuration.

Since your records are now grey-clouded, CloudFlare’s SSL settings do not come into play.

I should note that I personally never orange-cloud a Caddy server, because it introduces a number of problems with the certificate requisition process. As one example, if your Caddy server is serving a new site for the first time and has no certificates, it has to tell LetsEncrypt to connect to it. But the domain connects to CloudFlare instead. CloudFlare must then connect to Caddy, but Caddy has no certificate yet. It’s a catch-22, because Caddy has no certificate it cant get one. Without CloudFlare’s proxy in the middle, things become much simpler in a number of ways.

Possibly, but I’d hold off on that for now. With your DNS records grey-clouded, and the correct records for example.com and www.example.com, and presumably the correct ports available through your VPN, the issues you’ve posted earlier should all be resolved, I think. Give it another shot and tell me what problems you run into.

I’m getting close! These are the results I now get:

Outside the VPN forcing me to use port 10443, do you have any thoughts on why the www won’t resolve? Again, this is what my Cloudflare DNS page looks like:

I do have one idea!

Your Caddyfile has labels for example.com and example.com:10443, but doesn’t have a label for www.example.com. This means it’s not managing certificates for www.

When you make a connection to Caddy for a hostname it isn’t configured to serve, it will try to tell you that it has no such site available. When you do this over HTTPS, however, it has to complete the TLS negotiation before it can send you anything - so it offers you the first certificate it can find, which in your case would be for example.com. Since your browser notices the certificate isn’t for www.example.com, it errors out with ERR_CERT_COMMON_NAME_INVALID.

You can avoid this issue by only using example.com (without www) to connect to your services, or you can fix it by adding the www permutations of your domain to your Caddyfile i.e. example.com www.example.com example.com:10443 www.example.com:10443.

That worked! Thanks for all your help and patience!

So I’m fairly certain the answer is no, but is there anyway to add a record to the Cloudflare DNS settings (or change something somewhere else) that would redirect https://example.com/sonarr to https://example.com:10443/sonarr ?

The reason I ask is that it would potentially allow for someone trying to remotely connect to only have to type the following:
https://example.com/sonarr

Instead of typing this:
https://example.com:10443/sonarr

It’s a small nit, but something I was just thinking about. Having to type in ‘:10443’ is a small price to pay for an always-on VPN.

Not with your current setup. CloudFlare has Page Rules you could use to configure some basic functionality along these lines, but they require you orange-cloud your DNS records, and then :10443 won’t work anyway.

If you’re not opposed to making some changes to your infrastructure, though, I would go about your setup a little differently. Instead of having clients connect through your VPN to Caddy, I would put Caddy in front, publicly internet-facing, and have it proxy backwards through the VPN to your services.

Here’s how I’d do it:

  1. Buy a tiny $2.50/mo VPS from Vultr or similar, running Ubuntu
  2. Install unattended-upgrades, fail2ban, and Caddy
  3. In the Caddyfile, use labels www.example.com and example.com
  4. Substitute the server’s IP address on the VPN for 127.0.0.1 for all proxy directives

Benefits:

  1. All the usual ports are now available as required, and you can make allowances for closed ports (like :443 on your VPN) “behind the scenes” between the public Caddy and your private server
  2. Secures your private server somewhat by having clients connect to your VPS rather than your VPN endpoint directly
  3. Having a public webserver vastly simplifies the process of requesting and managing certificates

Yea, I’m starting to realize that layering a VPN on top of everything else is probably not the smartest way to do things. I’m actually in the early stages of planning an actual home server build later this year, so that I’m not running my desktop PC as a psuedo-server for much longer.

I’ve been eyeing unRAID, which will allow me to just have Deluge and the VPN on their own docker. I don’t really need the VPN for anything else, so I’m thinking that might be the long term strategy for me to go with.

I appreciate all the back and forth help you’ve given me! If I end up going away from the unRAID idea, I’ll definitely keep your VPS suggestion in mind!

I run an unRAID server too! Can recommend it, if you’re not specifically looking for the experience of setting up and configuring Docker, samba, storage etc., they’ve got a good product that makes things really straightforward. I run Caddy on both my unRAID server and my VPS.

Nothing wrong with a VPN. Just having it be your endpoint is the major downside when it’s limited on port availability.

Oh nice! Yea, it seems really easy to use compared to straight Linux. In a perfect world, I’d just deep dive and teach myself Linux, but I seem to work 50-60 hour weeks these days, so I’m trying to keep the head bashing at home with a server to a minimum, haha. I might have to pick your brain some more when I get closer to finalizing an unRAID build!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.