Author: Alessandro Marchioro - Written and Published on 2024-08-11 14:14

Everything encrypted on your homelab/local network using a selfhosted Certificate Authority

Hi everyone!

Have you ever wondered how can you make sure you're encrypting all your traffic on your local network or homelab instance, without selling a kidney nor losing your precious patience and sanity?

Here I have found an easy and simple solution for you, and it's called Smallstep CA!

It's a self-hostable Certificate Authority that supports you in making sure your business or network is fully secured and encrypted, by using certificates the proper way, via HTTPS TLS certificates, SSH certificates and more.

For this article, we're gonna setup a local CA server that can request local TLS certificates via Certbot client for Nginx-proxied local services on our network.

So, without further ado, let's dive in!

Prerequisites

The software that make it work is divided into two parts, server and client, step-ca and step-cli respectively.

So, before we get started, we need a dedicated machine (or docker container) for installing these components.

Phase 1: Configuring the server

For the purpose of this demonstration, we're gonna use a Debian 12 (Bookworm) instance with 1GB of RAM and 1 core, 20GB of disk and nothing more; that will be enough for our usage, but feel free to increase your specs as you'd like.

Once we have installed the operating system, be it virtualized or physical, we apt update && apt upgrade -y it and then run these two commands from a root shell for installing the certificate authority server stack:

wget https://dl.smallstep.com/cli/docs-ca-install/latest/step-cli_amd64.deb
wget https://dl.smallstep.com/certificates/docs-ca-install/latest/step-ca_amd64.deb
dpkg -i step-cli_amd64.deb
dpkg -i step-ca_amd64.deb
rm step-cli_amd64.deb step-ca_amd64.deb -y

Now that we have both programs installed, we run the following commands for setting up the certificate authority. The program will ask some questions, be sure to insert proper values so you can get notified if something goes wrong!

IMPORTANT: in the first step, make sure to save the fingerprint and the password somewhere safe, they will be needed for joining your CA network from clients and request proper certificates, other than running the CA server.

step ca init # For setting up the Certificate Authority (save the fingerprint and the password!)
step ca provisioner add acme --type ACME # For adding ACME support to this CA
step-ca $(step path)/config/ca.json # For running the CA server ()

You will now have a proper local certificate authority ready to get ACME requests for HTTPS certificates generation!

If you want to change the default 24h certificate expiration, make sure to edit the config file as described here with your likings: click here.

Phase 2: Connecting the server

To make this work, we need to login via SSH to a root session on your other server that has a webserver with needed TLS certificates, and run the following commands:

step ca bootstrap --ca-url [CA URL] --fingerprint [CA fingerprint] # Fill out the URL of your CA as per previously requested data on the Phase 1
step certificate install $(step path)/certs/root_ca.crt # This installs the root certificate on the local server, making sure all connections regarding this certificate and the intermediate and final certificates are properly made, verified and secured

Now that we have correctly installed the root certificate for using and requesting our new certificates, we have two ways of requesting certificates:

step ca certificate SERVICE_URL CERTNAME.crt CERTNAME.key
sudo REQUESTS_CA_BUNDLE=$(step path)/certs/root_ca.crt certbot --nginx -d SERVICE_URL --server https://CA_SERVER_URL/acme/acme/directory

IMPORTANT: Make sure to substitute SERVICE_URL, CERTNAME and CA_SERVER_URL with your previously set values!

Phase 3: Making sure it all works!

Check your service and check if your browser correctly identifies the new certificate!

If it shows a warning, you need to install the step-cli client in your machine and do the two initial steps at Phase 2 to properly accept your new local certificate authority as trusted.

Note: If you're in a business environment, I'd suggest in linking the root certificate automatically on your domain so you can ignore installing step-cli on each client and derive it from the Domain Controller via Group Policies, or something similar for macOS and Linux hosts!

Conclusions

Nice, now you have a fully protected service deployment!

With this simple setup, we just scratched the surface; we can also work with SSH clients, databases encryption, certificate document signing, and so on!

I hope it helped someone as it always has helped me in my work and homelab projects!


If you fancy see what I'm working on, have a look at my GitHub or write me an email!