I use a mesh VPN to connect my devices. Each device gets an IP address in the VPN’s IP range, and the mesh VPN cryptographically guarantees that any packet to/from an IP address will only go to/from the respective device. I use my hosts file to associate these IP addresses with human-readable hostnames (laptop, desktop, server, etc.).
This has worked very well and let me avoid dependence on centralized cloud infrastructure. However, I am starting to run into more and more browser annoyances which arise from lack of TLS support. There is currently no browser which supports unencrypted HTTP/2, and the HTTP3/QUIC specs completely lack support for unencrypted connections; additionally, Firefox has an annoying “insecure site” warning popup that interferes with my password manager and is no longer possible to disable.
I don’t need any of the TLS security guarantees. How are other people solving this problem? Is it possible to install a self-signed certificate that can only be used for a hardcoded set of domains, to trick Firefox into enabling the features it is locking behind TLS?
My security model considers my Nix configuration to be public (and this certificate would need to be installed on less-trusted edge devices), so I want to avoid having this certificate be able to spoof any domain outside of my intranet.
I don’t know if this helps, but instead of self-signed in my homelab I use step-ca, trust the root CA for it on all of my machines, limit what domains it can issue certificates for (much safer that way, even if someone steals your CA’s private key, they can not impresonate google.com), and then both Caddy (my reverse proxy) and Teleport request certificates from step-ca automagically using ACME.
Thanks for that link! The IP range for my VPN is 10.144.0.0/16, so my plan is to generate a CA that can sign certificates for all IP’s in that range (as well as local IPs):
openssl req -x509 -nodes -days 365000 -newkey rsa:4096 -keyout custom.ca.key -out custom.ca.crt \
-addext "basicConstraints = critical, CA:true, pathlen:0" \
-addext "subjectKeyIdentifier = hash" \
-addext "keyUsage = critical, keyCertSign, cRLSign" \
-addext "nameConstraints = critical, permitted;IP:10.144.0.0/0.0.225.225, permitted;IP:127.0.0.1/0.0.0.225"
Then I will publish both custom.ca.crt and custom.ca.key as part of my Nix config, since I don’t care if an attacker can spoof localhost or any node on my VPN (both of these are already authenticated by other means). custom.ca.crt will be added to the certificate store on all of my devices.
Finally, I will write a derivation for each device that signs a certificate for its hostname using custom.ca.key. The output of this derivation can be fed to nginx.
Are there any obvious security problems with this plan? I know that I am forgoing the security benefits of TLS by publishing the private key for the root CA, but I would be perfectly happy if I am no less secure than I currently am by using http over my secure tunnels.
I wouldn’t do that, but that’s because I already have sops-nix set up, so private key (or rather the passphrase to decrypt it) goes into sops. But I guess it is required in your case to have the key available in your Nix store, as you want to use it in derivations.
Mesh VPN I understand, but how does localhost get authenticated in your case?
Not a security expert, so I will refrain from making any strong statement one way or another!
1 Like
I wouldn’t do that, but that’s because I already have sops-nix set up, so private key (or rather the passphrase to decrypt it) goes into sops. But I guess it is required in your case to have the key available in your Nix store, as you want to use it in derivations.
Yeah, I handle secrets as state. My hope is that by doing it this way I don’t need to create any more secrets I need to handle!
Mesh VPN I understand, but how does localhost get authenticated in your case?
The same way it always does—127.0.0.x goes to my loopback device which only local processes can listen on. I’m fine with local processes being able to MITM local services (which is why I use http://localhost, like most people).
Not a security expert, so I will refrain from making any strong statement one way or another!
Me neither. I am hoping one will see this and point out any problems if they are obvious!