Forum archive
HTTPS, Internal LAN Services, and Me (or You)
Ok, so this one isn't strictly a "How do I do X?" question itself. I'm hoping for some thoughts, suggestions, and discussion. And yes, some how-to's. So let's cover the network configuration real quick.
Router: pfsense- This router nominally serves three functions besides being the router/firewall for the network.
- It performs LetsEncrypt cert acquisition/renewal via ACME for my domain, getting a wildcard cert for my needs.
- It runs HAProxy, which allows access for a couple services that are public.
- It serves as the VPN server (OpenVPN).
DNS: Piholes- Two piholes on network with identical configurations. These also have the local DNS resolutions for my internal services (so no hairpin NAT). This is also my helpful guide if I forget which IP address is which server.
Services: A half dozen services run as VM instances. All are Turnkey builds or setup on Turnkey Core, except one. (That one service is the only one publicly accessible via HAProxy and performs its own cert work so can be ignored for the purposes of this discussion).
Desired outcome: A sensible/repeatable, durable, easily-maintained solution for getting https for all my turnkey services from within the LAN for local users and users VPN'd into the network. Ideally, this is done leveraging the existing certs being fetched by the router.
By easily-maintained, I mean the architecture is simple and readily visible. No change config file X here, and config file Y over there when a service changes IP addresses.
ie right now, if I wanted to spool up a second Nextcloud server (ie test upgrading to PHP 7.4 from 7.3), I can clone my existing nextcloud instance and change its static IP, make a new DNS entry in my piholes (nextcloud2.domain.local) pointing to this new IP, and work on the clone until I've successfully made the upgrade.
Then I go to my piholes and switch the IP addresses nextcloud.domain.local and nextcloud2.domain.local point to and live test it. If its still all good, delete nextcloud2 and offline the old VM. Most of this process is GUI guided/prompted.
I like one throat to choke. Or in the case of redundant systems like the piholes, identical throats to choke. When something breaks in 8 months, no matter my documentation, it is much easier to have the least complicated tool chain possible to work through when something breaks.
I also like repeatable. When something new catches my eye to try out, I don't want to be puzzling how to integrate it into this system a year later. A system where I can copy a config and change the obvious details is nice. 12 step CLI process is not.
Progress so far:
I have read and explored a number of solutions posts and blogs. Most address this question from the standpoint of outside coming in using a proxy server (like nginx), often to a single endpoint. I've started down this road two or three times today but these examples are often absurdly simplistic and extremely short on details that would help me understand how to adapt to above needs/wants.
I believe I have managed to setup the pfsense ACME package to perform a shell command to dump the certs on the TKL Core Nginx server I am messing around with. And that was a pita, as again, people are grossly simplistic and explain next to nothing about how the process works to run without pw using keyfile and most are running this using pfsense root and a passphrase-less key file, which seems like a terrible idea, even if this is my internal network. I figured out how to using good ole scp. I think. It works in shell anyway. I don't like it because it relies on CLI configuration steps in pfsense that are not backed up. The appliance eats a brick, I'll be digging in my notes for the how to. And if I find I want to use another appliance instead?
I think I'd like a solution where all the servers are setup to copy the cert from a "cert-holder" server. But that sounds like it will obscure the setup process. 8 months from now, will I be able to repeat the user scp setup easily or will I be scratching my head?
This is, in part, where I like using the piholes for DNS resolution vs other solutions like my router. For one, at least one of the piholes is a VM instance. Backup is as easy as can be and testing/drilling myself on how to restore from back up is equally easy (and equally easy to undo if I screw up). Second, DNS setup is straight forward and simple. If I had to manually set it up again, it'll be as easy as the first time I blindly did it w/ no guidance.
Its also where I like using Turnkey, even just Core, for test projects and explorations. The CLI menu makes performing some steps very easy and low hassle (like slapping together a quick server to test something and using the menu to give it a static IP).
So there you have it. This isn't just about how-to's but hopefully a helpful discussion on solutions and why one would pick them.
First up, I have zero experience with pfSense, Pihole or HAProxy, so am working more from my general knowledge rather than claiming any sort of expertise here. So it's quite possible I'm missing relevant details.
Assuming that you are using your own domain, I think that support for valid external and internal HTTPS access should be quite doable (for simplicity I'd probably be inclined to suggest a subdomain per service but ultimately it shouldn't matter). But as per always though, the devil is in the details...
Before i move on, please note that I haven't tested any of this, or even pondered it deeply. This is very much off the top of my head and I am essentially thinking out loud. Hopefully I've covered everything of relevance to you, but please feel free to bump me on anything I haven't addressed.
TBH, my first thought is to just keep it simple and allow direct public access to your server(s) - i.e. via firewall forwarder. Obviously if you do that and you have more than one server, you'll need a reverse proxy (I've got plenty of experience with Nginx, but there are lots of other options - if you're already familiar with HAproxy, perhaps just use that?). If you allow public access to port 80, then the reverse proxy could even get it's own cert, further simplifying things.
You did mention that you like the idea of a central cert location. You could do that, but IMO it doesn't actually provide any value. IMO it just complicates your setup. If you were using your own certs (i.e. use your own CA cert to generated your own certs) then a centralized place to manage them would make sense (i.e only one CA cert to load on all your devices, that rarely, if ever changes). But it could be argued, that Let's Encrypt already is a centralized location for certs! :)
At the end of the day though, it's what works best for you.Regardless, I digress...
Traffic between the reverse proxy and the backend sever could either be plain http, or use a self signed https cert. To use a self signed cert, either load the CA cert on your reverse proxy (so it trusts the cert), or disable cert authentication between the proxy and backend. Both these options are supported by Nginx and Apache, not sure about HAProxy.
Additionally or perhaps alternatively, something that may be relevant here and of interest, is that a community member has been working on a Confconsole Let's Encrypt integration improvement; namely support for getting certs via DNS-01 challenge (so no public access to port 80 required). Once that's live then you could leverage that to allow each server to get it's own cert. So connect directly to the server when within your home network, or via the reverse proxy when out and about. If you like that idea but don't want to wait, then there are alternate ACME implementations that support DNS-01 challenges.
I'd also like to share my perspective on your note re passphrase-less SSH keys. Whilst it's certainly not as secure as a keypair with a passphrase (essentially 2 factor auth; something you have and something you know), IMO it could be argued that it's still more secure than just a passphrase/password (with no key). Passphrases/passwords can be socially engineered, brute forced, or attacked via other vectors. These are all much harder with a key! The only way for it to be hacked (at least at this point in time) would be to physically steal the key! Also, particularly for specific server to server connection, generating specific keypairs for specific connections (i.e. not reusing keys) and locking the remote end in a limited user account also mitigates security issues (use a service, cron job, or other triggering method to act on uploaded files, you can include validation if there is further security concerns about the risk of compromised keys.
Re-reading that, it seems like a fair bit of waffle, without a lot of clarity. I hope that it's not too bad on your end. Hopefully it's of some value... If you have further questions and/or would like me to elaborate on anything please ask.