This guide enables ACME v2 on an existing Smallstep Step CA deployment, then shows how a host like test.maksonlee.com can trust your private PKI, request/renew TLS certificates with Certbot, and let Certbot’s NGINX plugin automatically enable HTTPS on the default NGINX site.
This version intentionally does NOT install step-cli on the client.
Certbot is enough for issuance/renewal. The only extra step is installing your internal Root CA into Ubuntu’s system trust store so the client can verify stepca.maksonlee.com.
This Post Is Based On
Lab Context
- Step CA host:
stepca.maksonlee.com - Client host:
test.maksonlee.com - OS: Ubuntu 24.04
- Step CA server path:
/etc/step-ca - Step CA config:
/etc/step-ca/config/ca.json - ACME provisioner name:
acme-internal - ACME directory URL:
https://stepca.maksonlee.com/acme/acme-internal/directory
What You’ll Build
- Enable ACME v2 on Step CA
- Install NGINX (default site)
- Use Certbot + NGINX plugin to:
- register an ACME account,
- request a TLS certificate from Step CA,
- and automatically configure NGINX for HTTPS + HTTP→HTTPS redirect
- Confirm Certbot’s auto-renewal timer and test renewal
- Verify the certificate chain and SAN using OpenSSL
Prerequisites
- Step CA is already running and reachable at:
https://stepca.maksonlee.com
- DNS:
test.maksonlee.comresolves to the client host. - This post uses HTTP-01 challenges.
test.maksonlee.commust accept inbound TCP/80 during issuance/renewal.
If you can’t expose port 80, use DNS-01 instead.
- Enable ACME on Step CA
Run on stepca.maksonlee.com:
sudo -i
export STEPPATH=/etc/step-ca
step ca provisioner add acme-internal --type ACME \
--ca-config /etc/step-ca/config/ca.json \
--ca-url https://stepca.maksonlee.com \
--root /etc/step-ca/certs/root_ca.crt \
--password-file /etc/step-ca/password.txt
sudo systemctl kill -s HUP step-caACME Directory URL (clients will use this):
https://stepca.maksonlee.com/acme/acme-internal/directory
- Install Step CA Root CA into Ubuntu Trust Store (Bootstrap Once, No step-cli)
Run on test.maksonlee.com:
# 1) Download Root CA (bootstrap once with -k)
sudo curl -kfsS https://stepca.maksonlee.com/roots.pem -o /tmp/stepca-roots.pem
# 2) Inspect the Root CA (recommended)
openssl x509 -in /tmp/stepca-roots.pem -noout -subject -issuer -fingerprint -sha256
# 3) Install into Ubuntu trust store
sudo install -m 0644 /tmp/stepca-roots.pem \
/usr/local/share/ca-certificates/stepca-root-ca.crt
sudo update-ca-certificatesVerify you no longer need -k:
curl -fsS https://stepca.maksonlee.com/roots.pem | head- Install NGINX
sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginxConfirm HTTP works (default page):
curl -fsS http://127.0.0.1/ | head- Install Certbot + NGINX Plugin
sudo apt update
sudo apt install -y certbot python3-certbot-nginx- Request a Certificate from Step CA and Let Certbot Configure NGINX
This command:
- registers an ACME account (first run),
- requests the certificate from Step CA,
- enables HTTPS in NGINX,
- and configures HTTP → HTTPS redirect.
Replace the email address:
sudo certbot --nginx -n \
-d test.maksonlee.com \
--server https://stepca.maksonlee.com/acme/acme-internal/directory \
--agree-tos --email you@maksonlee.com \
--redirectCertificates are stored at:
/etc/letsencrypt/live/test.maksonlee.com/fullchain.pem
/etc/letsencrypt/live/test.maksonlee.com/privkey.pem
Verify HTTPS:
curl -fsS https://test.maksonlee.com/ | headExpected: HTML for the default “Welcome to nginx!” page.
- Verify Renewal and the Issued Certificate
Confirm Certbot auto-renewal is scheduled (systemd timer)
systemctl status certbot.timer --no-pager
systemctl list-timers | grep certbot || trueExpected: certbot.timer is active (waiting) and has a future trigger time.
Simulate renewal against your Step CA ACME directory
sudo certbot renew --dry-run \
--server https://stepca.maksonlee.com/acme/acme-internal/directoryExpected: “all simulated renewals succeeded”.
Verify the certificate chain (client-side)
sudo openssl verify \
-CApath /etc/ssl/certs \
-untrusted /etc/letsencrypt/live/test.maksonlee.com/chain.pem \
/etc/letsencrypt/live/test.maksonlee.com/cert.pemExpected: cert.pem: OK
Show issuer, validity period, and SAN
sudo openssl x509 -in /etc/letsencrypt/live/test.maksonlee.com/cert.pem \
-noout -issuer -dates -ext subjectAltNameExpected:
- Issuer = your Step CA Intermediate
- SAN includes
DNS:test.maksonlee.com notAftermatches your short-lived policy
Confirm NGINX is presenting the expected certificate
echo | openssl s_client -connect test.maksonlee.com:443 -servername test.maksonlee.com 2>/dev/null | \
openssl x509 -noout -issuer -dates -ext subjectAltNameExpected: same issuer / dates / SAN as the cert.pem output above.
Summary
You now have Step CA acting as an ACME v2 server, a client host that trusts your private PKI, Certbot issuing and renewing certs, and NGINX automatically configured for HTTPS using your Step CA-issued certificate:
https://stepca.maksonlee.com/acme/acme-internal/directory
Did this guide save you time?
Support this site