Reverse Proxy SSL on Lan with Cloudflare Tunnels for external access

Uninvited Guest@lemmy.ca to Selfhosted@lemmy.world – 3 points –

Hello! I finally decided to tackle a problem I've been putting off for some time, and got myself part of the way there but am now stuck, and hoping to find some assistance/information/nudge in the right direction.

The Goal

I am looking to have my services reached at the same url on both my internal network and externally (e.g. https://sub.domain.com).

The Setup

  • Proxmox Host
    • LXC running NPM with its own IP
    • LXC running Docker with its own IP, and services each have a different port
    • VM for Home Assistant
  • SBC running Pihole + unbound

The current workflow looks like:

  1. Router points to Pihole as the DNS server for all network devices.
  2. Pihole has local DNS records that redirect specific subdomains to the NPM LXC (I don't use a wildcard *.domain.com because some subdomains are hosted outside of my network, though they are outside the scope of this post).
  3. NPM has Proxy Hosts that are set up using HTTP to the Docker services on the 2nd LXC.
  4. Cloudflare tunnels are set up to point the same subdomains, when accessed externally, to the NPM LXC. As a bonus Cloudflare tunnels also handles the DDNS, zero trust (2FA) applications, and SSL.

The Problem

The current set up results in internal access taking place over HTTP while external access takes place over Cloudflare tunnels' HTTPS. This causes problems for some phone applications that require spelling out the connection type during set up, or even some applications that only allow access over HTTPS even when it's on the same network (looking at you Quillpad and Nextcloud Cookbook).

The Ask

I am not familiar with the steps that would be required to adjust my current set up such that all services accessed on my home network would connect over HTTPS. I am aware that external access over Cloudflare tunnels causes some wrinkles in using NPM's standard Let's Encrypt certificate & DNS challenge, which I believe means I need to use a certificate provided by Cloudflare. However, between Edge/Client/Origin/etc certificates, I am not sure what would get used and how that needs to be configured in NPM.

Any advice, reading material, video walkthroughs, etc is most welcome. Thank you in advance for any help!

1

Thanks so much to u/DSM-20 on the self-hosted Reddit for taking the time to connect and walk me through the Cloudflare setup (and then some!). The solution is:

  1. In NPM, set up a wildcard Let's Encrypt certificate (e.g. *.domain.com), using a DNS challenge with Cloudflare as the DNS provider and an API token that is created in your Cloudflare profile that provides Zone:DNS:Edit permissions.

  2. In Cloudflare's Zero Trust Dashboard, when setting up a public hostname (e.g. sub.domain.com) to point to the LAN IP of your reverse proxy (e.g. https://192.192.192.2), the "Additional Application Setting -> TLS -> Origin Server Name" needs to be set the same as the public hostname you are setting up (e.g. sub.domain.com)

And that was it! After saving that application setting, the set up I had worked instantly.

There are some additional settings that can be included in the NPM Proxy Host config that expose the IP of the connected user instead of Cloudflare's proxy IP.

set_real_ip_from ;

real_ip_header CF-Connecting-IP;