George's blog

It All Starts With Your PKI

29 April 2020

Ok so in my last post I mentioned that one of the first things to do when setting up my homelab was to create a PKI. If you don’t know what that is, I’m not going into great depth.

tl;dr PKI - Public Key Infrastructure - is a bunch of things - people, machines, robots, whatever - which manage digital certificates. In this context, it’s a set of config files, scripts, private keys and x509 certs which I can use to generate and sign new certificates for use in TLS connections. Primarily HTTPS.

Double secret tl;dr when I visit a webapp I’ve got running in my homelab, I want it to be over HTTPS and I want to get the little padlock in my browser which means it’s legit.

Ok so how? Well you could buy a cert for each app. Costly, time consuming, no. There’s LetsEncrypt. They’re doing wildcard certs now I believe. Again a hassle, but at least not costly. Or you could just generate a self-signed cert for each app, and add that to your browser, laptop, whatever. This is cheap, but time consuming and lame. Also, I doubt you’d be able to do it on an iPhone. I haven\t even tried.

So the real answer is that we create our own root and signing certs, issue CSRs and start signing them. We also install that signing and/or root cert on any device we’re going to browse our lab with. That gets rid of the safety warning. There are a bunch of different solutions out there for doing this. Choose one if you like. I’m not claiming the way I chose is the best, it just works for me.

Here’s the dirty little secret: OpenSSL is a pig. Features randomly don’t exist in minor version changes. You may not even actually be using it. If you’re on a mac, unless you’ve taken steps to use actual OpensSSL, you’re probably using LibreSSL. In short, it’s a mess. I arrived at my solution because it allows me to set SAN fields in certs using multiple different versions of OpensSSL. Anyways, I used this as a basis for my PKI, but it didn’t quite work with one version of OpenSSL I use, so I ended up modifying the server.conf file and explicitly adding the SAN line at the end for any given domain using a bash script:

echo "subjectAltName          = DNS:${DOMAIN}" >> etc/server.conf

I won’t regurgitate that article here, it’s fairly straightforward.

Once that was dome, I took my signing-ca.crt and added it to the login keychain of my Macbook pro, and trusted it. Now I can generate certs for any machine in my homelab, and my browser will be happy with them. I also installed them on my iPhone, which is a little bit trickier. Basically run a simple web server on your machine in the folder where your root and signing certs are

$ python -m SimpleHTTPServer

Then point your iPhone browser at that machine and click the links to both the signing and root certs. They will be available as “profiles” in your settings, where you can then add and trust them both. Now your phone, too, can browse things in your homelab without any security issues. Android? I dunno. Tinker. It’s why you got an Android, after all :)