I'm asking this question, with a clear mind, 170 days after my last internal-only Let's Encrypt certificate expired. I'm frustrated at the difficulty level involved - along with the 90-day expiration date, requiring automation (that seems to break regularly and is not easy to set-up for internal-only systems) or a lot of manual work. Did I mention I'm frustrated?
I have a Netgate SG-3100 firewall. I can configure the system via the web control panel or via the command line.
What I want is a CA-signed certificate from Let's encrypt that will work exclusively on my Internal network. My firewall's internal IP address is 192.168.10.1. So I believe this is technically the common name? I know I have forward DNS for my firewall externally and internally, but I don't manage my firewall from the outside. Just the inside.
I don't want to keep running around to all of my devices, and all of the browsers, updating site exceptions for self-signed certificates. It's annoying.
My question is this: is there a simple walkthrough, how-to, that would allow me to successfully generate (and renew) these internal-use-only (LAN) certificates in pfsense? Am I the only person trying to do this?
Problem: Let's Encrypt can't talk to my internal network, and the weird DNS verification system never worked for me. I have full control over my domain name on the DNS side (amarand.org), but I think Let's Encrypt gets confused by the fact that I have a domain (external), and wants to verify that? But I'm 100% not using Let's Encrypt for my home firewall. I need to keep my domain (amarand.org, which is a blog, and is hosted by a different service provider) and my home firewall.
Is this ever going to work for me?
My domain is: Internal Only (192.168.10.1)
I ran this command:
It produced this output:
My web server is (include version): Netgate SG-3100 21.05.1-RELEASE (arm)
The operating system my web server runs on is (include version): FreeBSD 12.2-STABLE
My hosting provider, if applicable, is: WOW
I can login to a root shell on my machine (yes or no, or I don't know): Yes
I'm using a control panel to manage my site (no, or provide the name and version of the control panel): Yes - Built-in pfsense
The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
No, you're not. This is quite a common scenario in (enterprise) networks. Solving this might not be entirely straightforward though - more below.
Let's Encrypt is a publicly trusted certificate authority. That means that certificates issued by Let's Encrypt are trusted pretty much anywhere in the internet. This also means that LE has the responsibility for ensuring that you're in control of the server(s) or domains - and those must be unique.
For example, you cannot issue a publicy trusted certificate for the IP address 192.168.10.1* - because this is from the private IP address space that a) cannot be routed outside from LAN's, b) is not unique - in fact, this is my routers IP address! You're stealing my IP!
So, what options are there for retrieving publicy trusted certificates from Let's Encrypt? There are currently three different methods available for validation:
HTTP-01 - Works by connecting to your server(s) and retrieves a shared token for validation. Requirements are that you need a domain pointing to some server that can be reached from anywhere in the internet. This gets exponentially more difficult the more "internal" "behind firewall" your devices are, up to the point where it's impossible. It also requires one or more public IP addresses.
TLS-ALPN-01 - Pretty similar to HTTP-01, but uses the TLS protocol for validation. We can consider it's requirements similar to HTTP-01.
DNS-01 - This does not require your devices to be accessible at all, which makes this interesting for isolated or offline devices. This type of validation ("challenge") works entirely within DNS. You submit a domain name you want to get a certificate for, say example.amarand.org and LE gives you a challenge to submit a DNS TXT record _acme-challenge.example.amarand.org in your global DNS. This can then be retrieved from the internet, without ever connecting to your machine(s).
So, reviewing our three options, we see that DNS-01 is your best option for more or less isolated devices. However, this doesn't mean that DNS-01 is your solution. Because DNS-01 also has quite significant requirements:
You need an (automated) way to add and remove DNS TXT records at your DNS provider. How difficult this is, depends on your ACME client and your DNS provider. Many people struggle with this, it's not uncommon.
You should also setup an automated way of installing the certificate(s). This might involve distributing the certificates from the machine where the ACME client runs to another machine, which should use the certificate. Then the new certificate must be imported in this machine. As Let's Encrypt certificates are always 90 days valid, this really should be automated - you do not want to do this manually in the long run. This often requires you to script your own solutions, unless someone else has written code for your exact setup already.
There is however an entirely different approach:
Remember how I spoke of publicy trusted certificates? For an internal LAN, where you own or control the devices, there really is no need for a certificate from Let's Encrypt - instead you can be your own certificate authority!
What you can do is generating a so-called root certificate, which you then install onto your client devices once. This certificate can be valid for 30+ years (you decide!), so it's not a process you must do regularly.
Then, you issue server "leaf" certificates from your root certificate, which can be valid for anything you want: Non-existent domains? Yeah, sure. Internal IP addresses? Why not. Those leaf certificates can also be valid for any time period you want: A bunch of years? Sure. This takes away the pain of repeatedly installing certificates manually: You pretty much do this once for every server you want.
Once all your clients (probably mostly browsers) have installed your "enterprise" Root CA, they will automatically trust all leaf certificates - no more browser warnings. (And significant better security, because just clicking "OK" on a certifcate warning gives away all authentication)
This is the enterprise approach that you will find often in corporate networks. It does require some initial setup, but once it's done you can proudly say - you're your own CA. You can get really sophisticated and roll your own CA with automation and HSM's and whatnot, or you can start small and keep things slightly more simple.
I use this "enterprise" approach for all LAN's I own. For small LANs I often use xca for the creation of the certificates. There's also software out there that does things in a more automated way, for example smallstep.
*Note: At this time, Let's Encrypt doesn't issue certificates for IP's, but may do so in the future - but never for private spaces, for the reasons above.
PS: With the enterprise CA, there's one thing you should be aware of: The CA certificates (the root and possibly an intermediate, if you generated one) must be kept as safe as possible. If this gets into the hand of an attacker, they can use your own certificates for attacking you.
As @Nummer378 said, the common approach to your scenario is installing a private or self-signed certificate.
If you wanted to use LetsEncrypt, the easiest method is to use the DNS-01 challenge to prove ownership and have DNS for a hostname on your domain point to the local IP. You must periodically install the certificate manually, use one of the post-deploy hooks in Certbot to upload the certificate, or write a tool that will invoke Certbot and then upload the certificate onto the device.
The latter options are doable, but will take more overall effort than updating the certificate manually.
This is why most people will opt for a private/self-signed CA.
So it seems like the only on-board solution requires adjusting my DNS entries every 60-90 days, which I suspect my firewall probably can't do. Or if it can do it, it's going to be a mess figuring out how to make pfsense integrate with my service provider's DNS protocols.
The primary solution that most people are offering really isn't a solution that works with Let's Encrypt, which is the whole reason why I posted here in the first place. "Don't use Let's Encrypt." (Which is what you're saying when you say I should make up my own CA and sign my own certificates.)
So, let's focus on the Let's Encrypt solution: is there a way for my pfsense firewall to talk to my service provider to perform the automated and regular DNS updating procedure?
Have you even looked? pfSense can update many DNS providers; here are just some of them:
At one point, back 170-ish days ago, I did look at that list. Saw that my previous provider (SiteGround) wasn't on the list. Then I switched over to InMotion Hosting, which is also not on the list. Sadly.
I reinstalled the acme plugin, created an account key, registered it, switched over to Certificates tab and pulled down the current list. Nothing there about "InMotion".
OK, so you switched your Hosting Service Provider (HSP).
But who is your DNS Service Provider (DSP)?
HSPs and DSPs are not mutually inclusive.
For instance, you could quite easily switch to use Cloudflare DNS (as your DSP only).
[you aren't forced to use their CDN - think: without ever changing any of your IPs]
I see: DNS-Cloudflare on the list.
The company that provides my web-site, and email, also provides my DNS. I pre-paid for the service for three years. I really don't want to switch my DNS to a different company just so I can sign into my firewall without a warning message.
Let me see if I understand you correctly...
You've pre-paid for three things (that can be consumed individually) for three years.
And you don't want to switch one of those three things out (for another such, and free, thing) because you don't want to do it only for the benefit of sign into your firewall without a warning message.
OK, I can see how the effort may be more than the reward.
Understand that I only presented the choice to you so that you could make an informed decision.
And in the event more things start to show similar lack of use, you can bring that to the attention of your DSP, OR switch to/from any other similar service provider (you can even use more than one at a time).
[which is to say that you don't even need to replace your current DSP - you can simply add another to it]
Unfortunately, my views at impartial; As I almost live and breathe DNS packets - LOL
Here is an example of such... work: nslookup -q=ns beer4.work
So this almost seems trivial to me.
I also wish it could be as easy for everyone else
I've bought many things in the past and found better alternatives that forced me to abandon what I purchased. When that happened, I considered what I spent a sunk cost. The money has already been spent and can't be recovered thus there's no point considering it in future decisions.
If I was in this situation I would consider the sum paid for DNS hosting a sunk cost and move on to a better, free service that will do what you want to do easier.