Can't get local Let's Encrypt SSL to work with NGINX Reverse Proxy and Namecheap domain reddit / selfhosted ---------------------------------------------------------------------- MachoSmallface · 2023-11-21 19:11 First post so hopefully it'll make sense. I've been fighting this for days and am giving up and asking for help from the Internet. I'm not new to networking and server management, but am relatively new to self-hosting/docker. I am trying to work toward local only home automation with Home Assistant and while building a ESP32 microphone was advised that it'll only work if I'm using SSL. So here we go. After watching several YouTube tutorials, for example [https://www.you tube.com/watch?v=qlcVx-k- 02E&t=377s](https://www.youtube.com/watch?v=qlcVx-k-02E&t=377s), I figured I could give it a go with a domain, NGINX Proxy Manager, and a Let's Encrypt cert. I want to set up internal subdomains for my services using the reverse proxy to bypass both the "unsecure" error as well as CORS errors when trying to use service APIs (for example Portainer or Pihole autologin from Homer, proxmox stats, etc.) which *should* also allow me to use SSL with Home Assistant. Also, I want it to be internal access only (no port forwarding from my WAN) so my internal URLs would look like this: * proxy.home.mydomain.com -> 192.168.1.100:81 (NPM admin page) * portainer.home.mydomain.com -> 192.168.1.100:9443 (Portainer console) * proxmox.home.mydomain.com -> 192.168.1.200:8006 * and so on I can get things set up with no errors, but the reverse proxy entries just never work. Below are the steps I've taken/configuration. Any help would be greatly appreciated. **External DNS Setup:** * Registered mydomain.com (example) with Namecheap * A record - host: mydomain.com, value: 192.168.1.100 * A record - host: home, value: [192.168.1.100](https://192.168.1.100) * CNAME - Host: \*, value: mydomain.com **Internal network setup:** * Docker/Portainer set up on 192.168.1.100 with standard ports * nginx-proxy-manager (from jc21) container up and running with 80/443/81 directly mapped * Internal DNS is provided by 2x local PiHoles, though I don't think this should be a problem? **NPM docker-compose.yml:** `version: '3.8'` `services:` `app:` `container_name: nginx-proxy-manager` `image: 'jc21/nginx-proxy-manager:latest'` `restart: unless-stopped` `ports:` `- '80:80'` `- '81:81'` `- '443:443'` `volumes:` `- ./nginx-proxy-manager/data:/data` `- ./nginx-proxy-manager/letsencrypt:/etc/letsencrypt` `networks:` `default:` `name: nginx-proxy-manager` At this point the container works I can login to npm at 192.168.1.100:81, and a normal request to 192.168.1.100 shows the "Congratulations" NPM default page. Good so far. However, I feel like at this point, accessing home.mydomain.com from my internal network should also display the "Congratulations page," right? My DNS request to Namecheap should respond with the internal IP in the A Record for home.mydomain.com but it doesn't. I get a "This site can't be reached" with a DNS\_PROBE\_FINISH\_NXDOMAIN error which I suspect may be the problem, perhaps something to do with how I have my Namecheap DNS records set up, but I don't know how to fix it. **Let's Encrypt Certificate creation:** Domain Names: home.mydomain.com \*.home.mydomain.com Email address: \[my email\] Use DNS Challenge Namecheap with correct username and API token The cert generates fine. From here I can create my proxy hosts, eg. proxy.home.mydomain.com and map them to the correct IP/ports as well as select the SSL cert with Force SSL and HTTP/2 Support options checked, but nothing works. Any help is greatly appreciated. ​ ---------------------------------------------------------------------- Flipdip3 · 2023-11-21 19:41 When you say you are pointing your A records to 192.168.1.100 do you mean that literally? It needs to be pointing to your external IP address and you need to have your router forward the ports to 192.168.1.100(or whatever machine is hosting NginxProxyMan) ---------------------------------------------------------------------- MachoSmallface · 2023-11-21 19:45 Yes, right now the external DNS record is pointed at my internal IP because that's what I want my clients to look at. I was assuming the DNS server would return that IP which directs local clients to it but anyone else's requests would fail. The port forwarding would expose my internal services externally, i.e. anyone on the Internet could have access to my self hosted services which I absolutely DO NOT want. ---------------------------------------------------------------------- Fair_Helicopter_8531 · 2023-11-21 20:18 Instead of going through all of this why now create a local DNS server with something such as pi-hole, and add the entries above. Then configure your network to prioritize using the local DNS first then whatever it currently uses. That way local clients get the same benefit. You never have to even show what services that are running on your network (i.e. [portainer.your-domain.com](https://portainer.your- domain.com) shows you are running portainer). I mean it just seems a lot easier to set up your own. Get adblock from said pi-hole and you are not clogging up your namecheap dns with dozens of entries. I mean if you wanted this accessed outside I could understand going through a public DNS. That is my two cents at least. Also, if you are keen on keeping the path you are going have you checked what your dns currently returns when you ping or do whatever with it. (i.e. is it actually returning said 192.168.1.100). ---------------------------------------------------------------------- Flipdip3 · 2023-11-21 20:19 Sorry, I just read closer and watched the link you posted. I think I have a better idea what you are trying to do now. Are you forwarding ports 80/81/443 from your router to NPM? If not NPM is never getting the request and can't forward you to the services behind it. ---------------------------------------------------------------------- MachoSmallface · 2023-11-21 20:24 That is my current setup. Right now everything points to my piholes so my internal names eg. portainer.lan or some such work fine which was good enough for me for a long time. However, Pihole can't do SSL certs/reverse proxy which I need to be able to use the Home Assistant voice/wakeword features. For that I need a valid SSL cert. This whole thing is a real kick in the teeth, particularly because every video I watch "it just works." On the flipside, perhaps I'm just stupid. ---------------------------------------------------------------------- MachoSmallface · 2023-11-21 20:32 I'm not forwarding those from the router because that would allow external access to the services. I only ever want this to be accessible from machines on my internal network. What I think *should* be happening is: Internal client requests portainer.home.mydomain.com -> namecheap responds with 192.168.1.100 -> client goes to 192.168.1.100 (npm) on port 80 -> npm reverse proxies it to [192.168.1.100:9443](https://192.168.1.100:9443) over SSL. ---------------------------------------------------------------------- [deleted] · 2023-11-21 20:53 [removed] ---------------------------------------------------------------------- Fair_Helicopter_8531 · 2023-11-21 21:18 yeah you can use nginix proxy manager to manage SSL certs and acts as a proxy (I believe you had that listed before), but just have your pi- hole redirect all entries to your nginx proxy manager (this will send it to the proper corresponding ports (important as you will need this for such things as 9443 for portainer) as well as give the SSL cert. For a valid cert you will have to do the DNS challenge to make it a valid SSL cert but after that you should not see any errors. Please let me know if I am misunderstanding anything though in your goal. It seems like to me at least you are just trying to locally use your domain trusted SSL certs and providing a reverse proxy on top of it. ---------------------------------------------------------------------- pvanryn · 2023-11-21 21:29 Read [this link,](https://selfhostedhome.com/reverse-proxy-with-https- without-opening-ports/) this exactly what I do; no forwarded ports. All you want to do is get your certs so you have ssl. The tutorial is a few years old, but the info is still good. It refers to digital-ocean, but you can use the provider of your choice, I use cloudflare. And the image is no longer letsencrypt, it is called [SWAG](https://hub.docker.com/r/linuxserver/swag) now. 50 million pulls can't be wrong. ---------------------------------------------------------------------- Flipdip3 · 2023-11-22 00:20 Yes, you don't port forward your individual services. But you need port 80 and 443 forwarded from the router to the NPM host machine. If you don't forward those ports your router won't know where to send those requests. ---------------------------------------------------------------------- Johannesboy1 · 2023-11-22 02:15 Not an answer but please dont use duckdns. It has a 600 ms ping and very frequent outages. Using cloudflare is free and is insanely fast and reliable ---------------------------------------------------------------------- ratudio · 2023-11-22 02:25 i have no issue using duckdns on my pfsense with combination linuxserver/swag docker container ---------------------------------------------------------------------- ProbablePenguin · 2023-11-23 15:39 Start diagnosing with nslookup. Instead of putting internal IPs in your public DNS you can just add them to PiHole. It won't affect anything about SSL. ---------------------------------------------------------------------- MachoSmallface · 2023-12-02 21:42 **\[SOLVED\]** First of all, thanks for all of the help/suggestions! I got it working, though if I'm honest, I'm not 100% sure if it's the best solution. And shoutout to u/ProbablePenguin whose suggestion led me to the answer. Essentially I did end up using my PiHole (choose your favorite internal DNS server) to intercept the requests. It's more work, but less than I thought. It does, however require the use of an internal DNS server. So, how I finally made internal SSL work with a real domain with internal network only access is below. If anyone has any suggestions on how to make it better, I'd love to hear. ​ 1. Register a domain EX: "homenet.com". I used NameCheap, but wouldn't recommend it because getting API access was a huge pain with them. I hear Cloudflare is much easier. I then pointed it at my public IP, but that's actually irrelevant to this example. 2. Set up NGINX Proxy Manager (NPM) (example IP 192.168.1.100) 3. Create a Let's Encrypt cert in NGINX Proxy Manager with domains "homenet.com" and "\*.homenet.com" 4. Create an NPM Proxy Host for each service you want to use, ex: jellyfin.homenet.com and map it to the server's IP and port making sure you select correct scheme http/https 5. On your PiHole, you need to do two things 1. Create a DNS record for Domain: homenet.com IP address your NPM server 2. EX: Domain: homenet.com IP address: 192.168.1.100 3. FOR EACH service create a CNAME record with Domain [service.homenet.com](https://service.homenet.com) and target of your TLD 1. EX: Domain: jellyfin.homenet.com Target: [homenet.com](https://homenet.com) 6. VOILA! It works! No more insecure messages and all services show the locked padlock in the browser. Additionally, Home Assistant no longer fails out due to lack of SSL. For the sake of discussion, I'm still not sure why my initial setup didn't work. In theory the DNS server should return the internal IP to my client which, while useless to anyone outside my network, should mean something to my internal clients. For some reason though, it would just never resolve. I didn't try it with the DuckDNS solution as shown on the linked YT video above, so maybe DuckDNS has a provision for such things? Anyway, thanks again for everyone's help and I hope this helps someone.