Deploying Step CA: Your Own Certificate Authority for Internal Services

Short version: install Smallstep’s step-ca, initialize a Root + Intermediate CA, move it under /etc/step-ca, and run it securely with systemd on port 443.


What you’ll build

A private PKI with:

  • Root CA (keep key offline or tightly protected)
  • Intermediate CA (online, used for daily issuance)
  • step-ca listening on :443 (mTLS-friendly), managed by systemd

This article focuses on standing up the CA service. Issuing server/client certs and device templates are intentionally out of scope.


Prerequisites

  • Ubuntu (24.04 recommended)
  • DNS: stepca.maksonlee.com → your CA host
  • Shell access with sudo

  1. Install step-ca and step-cli
sudo apt-get update && sudo apt-get install -y --no-install-recommends curl vim gpg ca-certificates

sudo 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' \
  | sudo tee /etc/apt/sources.list.d/smallstep.list

sudo apt-get update && sudo apt-get -y install step-cli step-ca

  1. Initialize the CA (Root + Intermediate)

Run the initializer and answer as below:

step ca init
  • PKI mode: standalone
  • Name: Maksonlee.com Root CA
  • DNS name: stepca.maksonlee.com
  • Address: :443
  • Provisioner name: admin
  • Password: changeme (use a strong one in real life)

step ca init creates Root/Intermediate certs+keys under ~/.step/ by default:

  • certs/root_ca.crt, secrets/root_ca_key
  • certs/intermediate_ca.crt, secrets/intermediate_ca_key

Store the CA password in a file for the service:

echo "changeme" > ~/.step/password.txt

  1. Move PKI to /etc/step-ca and set permissions
# Allow binding to port 443 (CAP_NET_BIND_SERVICE)
sudo setcap CAP_NET_BIND_SERVICE=+eip "$(command -v step-ca)"

# Create service user and path
sudo useradd --user-group --system --home /etc/step-ca --shell /bin/false step
sudo mkdir -p /etc/step-ca

# Move initialized PKI from ~/.step to /etc/step-ca
sudo mv "$(step path)"/* /etc/step-ca

# Update paths in config
sudo sed -i "s|$HOME/.step|/etc/step-ca|g" /etc/step-ca/config/ca.json

# Ownership
sudo chown -R step:step /etc/step-ca

  1. Create a hardened systemd unit
sudo tee /etc/systemd/system/step-ca.service >/dev/null <<'UNIT'
[Unit]
Description=step-ca service
Documentation=https://smallstep.com/docs/step-ca
Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=30
StartLimitBurst=3
ConditionFileNotEmpty=/etc/step-ca/config/ca.json
ConditionFileNotEmpty=/etc/step-ca/password.txt

[Service]
Type=simple
User=step
Group=step
Environment=STEPPATH=/etc/step-ca
WorkingDirectory=/etc/step-ca
ExecStart=/usr/bin/step-ca config/ca.json --password-file password.txt
ExecReload=/bin/kill --signal HUP $MAINPID
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
StartLimitInterval=30
StartLimitBurst=3

; Process capabilities & privileges
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
SecureBits=keep-caps
NoNewPrivileges=yes

; Sandboxing
ProtectSystem=full
ProtectHome=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
PrivateTmp=true
PrivateDevices=true
ProtectClock=true
ProtectControlGroups=true
ProtectKernelTunables=true
ProtectKernelLogs=true
ProtectKernelModules=true
LockPersonality=true
RestrictSUIDSGID=true
RemoveIPC=true
RestrictRealtime=true
SystemCallFilter=@system-service
SystemCallArchitectures=native
MemoryDenyWriteExecute=true
ReadWriteDirectories=/etc/step-ca/db

[Install]
WantedBy=multi-user.target
UNIT

Start and enable:

sudo systemctl daemon-reload
sudo systemctl enable --now step-ca
sudo systemctl status step-ca
sudo journalctl -u step-ca -f

Next

  • Export the Root CA to devices/clients that must trust your private PKI.
  • When you’re ready, follow issuance workflow (server certs, client certs, IoT templates/provisioners) in a separate guide.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top