[SOLVED] I had to open ports 80 and 443 (maybe 1 was enough, idk) while renewing certs ! Now its time to learn how to do it without opening ports (:
Hey guys, I have nginx proxy manager running in docker container on my home server. I don’t have any ports open (other than wireguard) and I was using custom local domain .tride to access my services. Everything works fine, I can use https://portainer.tride, https://homeassistant.tride, etc.
I want to get rid of warnings about the risk that I have to accept to continue. Not a big deal for Firefox on desktop, but its kinda annoying on Android. Also I think it stops me from using some services that require SSL certs (like floccus). I tried to create a LetsEncrypt certificate using DNS challenge and DuckDNS in NPM. I also tried to download certs and import to Android, CA cert is added successfully, but didn’t work.
Now I bought example.com domain from porkbun.com and trying to set it up:
- Created CNAME on porkbun - *.example.com pointing to my example.duckdns.org
- Created cert using same procedure (DNS challenge and DuckDNS in NPM) with hosts *.example.com and example.com
- Created Local DNS records in PiHole
Now I get strange behavior, sometimes I can open portainer.example.com with no problem, no warning, perfect. Then sometimes it doesn’t load at all and it says “Server Not Found”. Some services open normally, but like bookstack.example.com opens broken page and if I click anywhere it redirects me to my old bookstack.tride (still exists in NPM and PiHole) and asking to accept the risk.
I’m trying to use services from local network or wireguard only, at least for now.
I am also using the same domain for my e-mail at mailbox.org if that matters. Not sure what I’m doing wrong, but I’m sure there is something. I’m happy to listen any suggestion, and sorry for being noob <3
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
Fewer Letters More Letters DNS Domain Name Service/System HTTP Hypertext Transfer Protocol, the Web IP Internet Protocol PiHole Network-wide ad-blocker (DNS sinkhole) SSL Secure Sockets Layer, for transparent encryption VPN Virtual Private Network nginx Popular HTTP server
6 acronyms in this thread; the most compressed thread commented on today has 6 acronyms.
[Thread #79 for this sub, first seen 24th Aug 2023, 13:25] [FAQ] [Full list] [Contact] [Source code]
I use nginx proxy manager with dns challenge to get a *.example.com cert that I then use to host services internally. I just checked, it supports dns challenge for porkbun, you may want to give it a try again. Also, you shouldn’t really need to forward dns to duckdns. You can have public dns records point to an internal ip.
This is what I do, I have example.com (dns registered with cloudflare but should work the same with porkbun) I then create an a record for portainer.example.com to 192.168.0.5.
Internally my nginxproxymanager is running at 192.168.0.5 and portainer is running at https://192.168.0.6:9443
Then in nginxproxymanager I create a dns challenge (you’ll have to look up some videos on how to do this, it’s not very difficult it usually just takes a api key and secret key) then I create a new proxy host for portainer.example.com pointing to https://192.168.0.6:9443 and you select the *.example.com as your ssl cert for the proxy host
Now internally go to https://portainer.example.com and it should work.
Thank you! It does support porkbun, but I don’t have any “porkbun service” running on my server, but I do have duckdns (using it for VPN). Is that kind of service even necessary here? I tried using porkbun api key and it didn’t help, but opening ports did. I opened ports 80 and 443 and closed them after cert (with duckdns challenge tho). Also I made A record *.example on porkbun, seems better for my needs.
You can have public dns records point to an internal ip.
I tried pointing *.example.com to my local IP 192.168.0.40 but porkbun doesn’t allow me that, maybe I misunderstood this part. I sorted out the problem, thank you anyway <3
So the opening of ports works, but it’s not the most secure or best way to do it imo… what happens is the certbot registers with letsencrypts api and attempts to request a cert via http challenge, it then hosts a small website with a code from letsencrypt to prove that you do in fact own the domain and are who you say you are. Let’s encrypt then goes to the url, verifies it sees the text, and issues a cert to the certbot. The problem here is you have to open these ports to the internet, and they need to be open when certificates are renewed (let’s encrypt only issues a 90 day cert)… if you want to leave those ports open that’s not exactly a safe practice, and manually doing it every 3 months is less than ideal…
With dns challenge, the certbot uses the api of your dns provider (cloudflare or porkbun), the process is similar, it talks with letsencrypt, let’s encrypt gives it a string and a dns record it expects to see, then certbot talks to your dns, makes a txt record with the string provided, then let’s encrypt checks for that dns record, if it finds it, it issues a cert to the certbot. In this scenario, certbot is connecting out to your dns provider and making the record for you, no opening of ports. And if you leave the api key active, it will auto renew on a schedule so you don’t have to really worry about it.
I highly recommend looking into dns challenge some more, watch some videos on it there are lots on YouTube.
As for the dns record, not sure if it’s not allowing the wildcard record or what but I wouldn’t use *.example.com, make an entry for the actual host/service you are hosting, like portainer.example.com.
Thank you for explaining this, its much more clear now. I’ll definitely look more into dns challenge and hopefully be ready before next renewal :D Have a nice day mate
here is a good video on how to do it: https://piped.video/watch?v=qlcVx-k-02E
pretty much exactly what you’re trying to do.
Oh amazing, this is exactly what I need! Im gonna try it today. Thank you again ❤️
Thanks all for many useful tips. Sorry, I had some crap going on today so I need to postpone this for tomorrow. Didn’t want to be rude by not replaying to your comments. Cya tomorrow <3
Maybe you could also try to generate your one SSL certificate and add it to your Android/Linux/Windows devices as root certificate 🤷🏼♂️.
That’s only a possibility, of you’re willing to do this to every single device that should be able to connect to your services
I am willing to do that for every single device I use, but how can I do that? I have 3 options to install (android 12): CA certificate, VPN & app user certificate and Wi-Fi certificate
I can download cert from NPM, I get 4 files, but only one can be installed (at least the way I tried)
This is what I do only because cryptography it’s a big weakness of mine so I wanted to work through it to understand it. I ended up setting up a raspberry pi with Debian and went at it with guidance from a YouTube video. Notice I said guidance, to get started. From there, I built my own CA server and issue certs to my services, upload the certs to NPM and apply them to the services I need.
Documented every step of the way and made templates out of config files.
It’s not the sexiest solution BUT I have a way better handle on cryptography than I did before.
Thanks! This sounds like approach I would prefer, but tbh I’m overwhelmed with information and I’m happy my setup is working for now. I will defo look into local CA server when I get more familiar with everything.
Don’t shy away from it based on how difficult you THINK it is. It’s really not that complicated once the concept and the different parts of what makes that lock icon appear on your browser are explained in detail. I was in your exact position, paralyzed by the thought of tackling such a topic. If you have the time, have a look at the video I linked. Everything is explained really well (although it is a bit dry and long at the beginning but it’s worth it). After that, if you have questions, dm me (if that’s a thing in Lemmy).
I would say I would give you my templates/instructions if you’d like but that would do you more harm than good.
Thank you my friend, so kind of you. I will watch that video for sure and let you know if I have more questions
Here is an alternative Piped link(s): https://piped.video/nOSl4dmywe8?si=XxBLwPNlq-wt2swR
Piped is a privacy-respecting open-source alternative frontend to YouTube.
I’m open-source, check me out at GitHub.
Actually, had no idea this existed. Good bot
I’m not sure about anything you’re running but I would look into certbot.
Either using the basic web plugin or DNS plugin. Nginx would be simpler, you’d just have to open your web ports on certificate generation to pass the challenge.
I know some proxy tools have let’s encrypt support, such as traefik.
Thanks! I’m lost a bit honestly, but your comment sounds useful. Do I just open port 443 before I generate certificate and then close the port right after? That would make sense, but not sure is that the way. I’m not getting any error when doing the same with closed ports. Is there a way to check if cert passed the challenge?
I was reading about certbot, but all guides are for CLI. I use NPM with GUI and I’m just confused how these 2 talk to each other. I have to point SSL to each host I make in NPM afaik.
I don’t mind trying traefik if thats a suggestion, but prefer not if possible since I’ll probably need to remove NPM first.
Ports 80 and 443.
The cli is easy and you could just Cron (scheduled task) a bunch of commands to open the firewall, renew cert and close the firewall. It’s how I do it for some internal systems.
Thanks. Opening ports solved the problem, but cron job cant open ports on router right? They are usually closed on my router and opened in firewall.
I think you’d need to open port 80 since certbot needs to be able to “see” your site to verify you own it before generating the certificate. Once it does its thing you can close the ports from public access (leaving it open on your LAN) again though
Thanks a lot! This worked. I actually opened both 80 and 443, renewed cert, opened few hosts, closed the ports and viola, its working. It seems bit inconvenient, I had to reopen ports to add more hosts. Renew didn’t help every time, but I could just open that service and then close ports again. It’s working and I’m happy! I guess I just have to open ports again in November (when cert is expiring) and renew. How much risk is there if I open ports for like 2 min?
Nice, congrats on getting it working and learning new stuff in the process!
As for why you have to open port 80: I don’t know if this is (still) how certbot works, but back before certbot was a thing, you setup an SSL certificate by adding an HTML tag to your site’s header. That way, when the certificate issuer loaded your site from their end they could see that you did indeed have access to that site (otherwise you wouldn’t be able to add the requisite tag). Once the verification was complete, you could remove the tag. I assume certbot is automating a process similar to this (maybe at the proxy level even), and that’s why you have to open port 80 - so that certbot’s issuer can “see” your site from their connection and verify that you do indeed have access and therefore ownership of it.
To renew your cert, I don’t know if you will need to re-open the ports or not, but I would not be surprised if you did need to. You should be able to run certbot with a dry run flag that will do everything except actually implement a new certificate. You could try doing that with the ports closed and see if it succeeds or fails. If it fails, you probably need the ports open. If it succeeds, you probably don’t need them open. Either way, you’ll find out in November when the automatic renew takes place. Worse case scenario, you get a security warning when you go to the site on your LAN indicating that the cert is expired. You’d then open the ports, renew, and close them again.
As for the risk of having the ports opened for a couple minutes, I think that would be negligible unless you’re hosting something that is inherently insecure. Someone would have to know your public ip and hit it at just the right time to see your site on the open ports. Then they would have to do whatever attacks they want to within the amount of time it takes for you to renew the cert. If you’re hosting something that doesn’t use a secure login page and could be used as a jump box to other devices in your network - that’s probably no bueno. But if you’re running something that’s secured your risk shouldn’t be too bad. Bonus points if you setup your gateway to block outbound connections from your server except for ports 80 and 443, but that’s assuming your server doesn’t need to use other ports of course. It all depends what you’re hosting there, hopefully that makes sense.
Edit: This forum post indicates that access is required for certificate renewal, meaning you would indeed need to open the ports to renew. There is also another style of ownership verification mentioned in that thread which would not require you to open the ports, because it uses DNS to check for ownership. This would essentially require you to add a DNS text record to prove that you own the site’s domain. I am less familiar with this process, but it may be an option for you if you are willing to research it.
Thanks again. It make sense, but I will try to set it up with dns challenge since I prefer not opening ports. I’m happy it works for now and I also have some good material to read in free time. cheers
For your local PiHole DNS, where are your records for your domain pointing? I believe you should have an A record for
*.example.com
that points to the IP of your NPM server and then an MX which points to the IP of your mail server. If this is already the case then you can ignore this.Also, if you are using DHCP do not have it assign your public domain to any of your hosts because that could screw up name resolution as well.
I did try A record *.example.com but back then I didn’t open ports on router so It didn’t work. Later on a switched to manually adding DNS records in pihole GUI 1 by 1. I might try A record another time. Thanks.
I have set static local IP for my server so I guess I’m safe, but thank you for tips <3