What’s up guys? Welcome — or welcome back — to the blog. In the last blog, we got one of the core services of our environment up and running — DNS. Today, we’re moving on to another critical piece of the puzzle: our certificate authority.

We’ll be using Step CA, a lightweight, modern CA built by the folks at Smallstep. This tool makes it super easy to issue, renew, and manage internal TLS certificates — giving you full control over your internal PKI.

Why This Approach Is Different

I’ve seen a bunch of videos on setting up SSL in a homelab, and while most are solid, I’m taking a slightly different route. My philosophy? Keep things internal first, and only go public after you’ve tested and validated your setup. It might be a little more work upfront, but it gives you peace of mind, time to learn, and a safe space to build and break things without affecting the outside world.

Two-Phase SSL Strategy

This project will be completed in two phases:

Phase 1 (this video):
We’ll set up our internal certificate authority using Step CA. We’ll talk about how SSL works, what certificates really are, and why building your own trust chain matters.

Phase 2 (next video):
We’ll buy a public domain, get a wildcard cert from Let’s Encrypt, and configure an internal reverse proxy to terminate SSL using that cert. We’ll also mirror our public DNS internally so services can resolve names privately — keeping everything sealed off until we're ready to go live.

This setup assumes you already have DNS working. If you haven’t done that yet, hit pause — I have a full video walking you through setting up a DNS server inside your network using BIND9.

What Is PKI and Why Should You Care?

PKI (Public Key Infrastructure) is what secures your communications across the internet and your internal network. When a client (like a browser) connects to a server, it needs to know: "Can I trust this server is really who it says it is?" PKI answers that question using digital certificates signed by a trusted certificate authority (CA).

The Chain of Trust

  1. Root CA — The top-level authority. Usually kept offline for security.
  2. Intermediate CA — Signed by the root. Signs certificates for servers.
  3. Server Certificate — Installed on the actual server. Signed by the intermediate CA.

Each layer vouches for the one below it — that’s the “chain of trust.”

Certificates & Keys

Certificates are tied to key pairs:

  • Private Key — Stays on the server. Used to decrypt data.
  • Public Key — Shared with the world. Used to encrypt data.

Here’s how the handshake works:

  • Client: “Hey server, I want to start a secure session.”
  • Server: “Cool. Here’s my certificate (with my public key).”
  • Client: Verifies the certificate chain.
  • Client: Creates a shared secret → encrypts it with the server’s public key → sends it.
  • Server: Decrypts it using its private key.
  • Both sides now have a session key and use that to encrypt all communication.

Step 1: Create the Container in Proxmox

We’re starting by creating an unprivileged LXC container in Proxmox to run Step CA. Here’s a quick rundown of what we configured:

  • Name: ca1
  • Unprivileged:  (limits root access from container to host)
  • Nesting: (needed for system calls)CPU/Memory: 2 cores, 1 GB (you can go lower — it’s lightweight)
  • Storage: 5-10GB disk
  • Static IP: (Enter IP)
  • DNS: Points to our internal DNS server
  • Template: Ubuntu 20.04 (same as we used for the DNS server)

If you're unfamiliar with LXC templates or Proxmox container setup, check out the DNS video first.

Step 2: Add the CA to DNS

Make sure you add this new container to your DNS server if you do not have dynamic DNS configured. In my case I'm going to add it to my  BIND9 zone files

Step 3: Install Step CA and Step CLI

NOTE: Please use the link below to ensure you’re running the correct command to add the Smallstp repository to your source list and install the required tools. These commands are occasionally updated, so always refer to the documentation linked below for the latest version.

Add the Smallstep repo and GPG key:

The command below is slightly different from the one shown in the video. This version uses the newer and more secure method for adding the GPG key and repository, following current best practices for Debian/Ubuntu systems.

  • apt-get update && apt-get install -y --no-install-recommends curl vim gpg ca-certificates
    curl -fsSL https://packages.smallstep.com/keys/apt/repo-signing-key.gpg -o /etc/apt/trusted.gpg.d/smallstep.asc && \
    echo 'deb [signed-by=/etc/apt/trusted.gpg.d/smallstep.asc] https://packages.smallstep.com/stable/debian debs main' \
    | tee /etc/apt/sources.list.d/smallstep.list
    apt-get update && apt-get -y install step-cli step-ca

Step 4: Initialize Step CA

Before initializing, grab your container’s FQDN:

  • hostname -f

Then run:

  • step ca init

You’ll be asked:

  • What to name your CA (e.g., “KTech Lab”)
  • What FQDN to bind to (e.g., ca1.ktechlab.com)
  • What port to use (:443)
  • What to call the provisioner (admin)
  • Set a strong password for the provisioner

This generates your:

  • Root certificate & private key
  • Intermediate certificate
  • Default config files
  • CA database

Your private key is stored in /root/.step/secrets. Back it up. Do NOT share it.

Step 5: Create a systemd Service for Step CA

We want Step CA to run automatically in the background, start on boot, and recover if it crashes. That’s where systemd comes in.

First, create a password file for the CA to decrypt its private key at boot:

  • nano /root/.step/password.txt

Paste in the provisioner password, save, then lock down permissions:

  • chmod 600 /root/.step/password.txt

Now create the systemd service file:

  • nano /etc/systemd/system/step-ca.service

[Unit]
Description=Step Certificate Authority
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/step-ca /root/.step/config/ca.json --password-file /root/.step/password.txt
WorkingDirectory=/root/.step
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and start the service:

  • systemctl enable step-ca
  • systemctl start step-ca

Check that it’s running:

  • systemctl status step-ca

Wrapping Up: Phase 1, Part 1 Complete

We’ve:

  • Built our CA container
  • Set up DNS records
  • Installed and initialized Step CA
  • Created a systemd service to run it reliably

In the next video, we’ll focus on the server side:

  • Generate private keys and CSRs
  • Sign CSRs with our CA
  • Push certificates to services
  • Lock down encrypted communication end-to-end

If you enjoy this kind of content don’t forget to subscribe, and—as always—stay geeking. Peace!

About the author

Quiet Engineer

A lifelong learner with a passion for tech and soccer. Koroma Tech is where I share my journey and help others along the way. I enjoy taking on challenges and see each one as a chance to learn and grow.

>