Getting a Certificate

Chapter 9
Getting a Certificate — Let's Encrypt & ACME
CSRs, domain validation, the ACME protocol, and automatic renewal

The theory is done — now the practical question: how do you actually obtain a certificate for a domain you own? This chapter covers the request itself (the CSR), how a CA proves you control the domain (validation), and how Let's Encrypt automated the whole thing into a single command via the ACME protocol — the reason HTTPS is now free and ubiquitous.

Step Zero: The Key Pair Never Leaves Your Server

Before anything else, one principle that surprises beginners: you generate your own private key, and it never leaves your server. The CA never sees it. You only send the CA your public key (inside a CSR) plus proof you control the domain; the CA signs a certificate binding that public key to your domain and sends the certificate back. The secret half stays with you the entire time.

The CSR — Certificate Signing Request

A CSR is the formal application you send to a CA. It bundles your public key with the identity you're requesting (the domain), and is signed by your private key to prove you hold it. You can create one with openssl:

# generate a private key, then a CSR for example.com openssl genpkey -algorithm RSA -out example.key openssl req -new -key example.key -out example.csr \ -subj "/CN=example.com" \ -addext "subjectAltName=DNS:example.com,DNS:www.example.com"
The CSR containsThe CSR does NOT contain
your public keyyour private key (never!)
the requested domain(s) — CN & SANthe validity dates (the CA sets those)
a self-signature proving key ownershipthe CA's signature (added on issuance)

Inspect a CSR with openssl req -in example.csr -text -noout — you'll see the same fields as a certificate (Chapter 4) minus the issuer and validity, because those are filled in only when a CA signs it.

Domain Validation: Proving You Control the Domain

A CA won't sign a cert for example.com until you prove you actually control that domain (Chapter 5's DV level). The proof is a challenge: the CA gives you something to place where only the domain's controller could put it, then checks for it.

Challenge typeYou prove control by…Best for
HTTP-01serving a specific token file at http://domain/.well-known/acme-challenge/<token>a single host you run a web server on
DNS-01creating a specific TXT record in the domain's DNSwildcards (*.example.com) & servers not publicly reachable
TLS-ALPN-01presenting a special cert on a TLS connectionenvironments where only port 443 is usable

The logic is identical across all three: only someone who genuinely controls the domain (its web root, its DNS, or its TLS endpoint) could satisfy the challenge. Wildcard certificates specifically require DNS-01, because proving control of one web page doesn't prove control of every possible subdomain — but control of the DNS zone does.

ACME — Automating the Whole Exchange

ACME (Automatic Certificate Management Environment) is the protocol Let's Encrypt introduced to turn that manual back-and-forth into an automated machine-to-machine conversation. A client (like certbot) runs the entire flow:

Account & order
The ACME client registers a key with the CA and requests a cert for your domain(s).
Receive challenge
The CA returns a challenge (e.g. HTTP-01 token) for each domain.
Satisfy challenge
The client places the token file (or DNS TXT record) automatically.
CA validates
The CA fetches the token / checks DNS to confirm domain control.
Submit CSR & receive cert
The client sends the CSR; the CA signs and returns the certificate + chain.

In practice this is one command. Certbot can even configure your web server for you:

# obtain AND install a cert for nginx, fully automated sudo certbot --nginx -d example.com -d www.example.com # or just obtain the cert files, configure the server yourself sudo certbot certonly --webroot -w /var/www/html -d example.com
Let's Encrypt changed the web — free, automated, ubiquitous
Before Let's Encrypt (2015), certificates cost money and were issued through a slow, manual process, so most small sites stayed on plain HTTP. Let's Encrypt is a free, non-profit CA that issues only DV certificates, fully automated via ACME. That combination — zero cost + one command + auto-renewal — is the single biggest reason HTTPS went from "~30% of web traffic" to nearly universal. The short 90-day lifetime (Chapter 4) is only practical because ACME makes renewal automatic.

Renewal: Set It and Forget It

Because Let's Encrypt certs last only 90 days, renewal must be automatic — and certbot installs a timer that does it for you. The renewal re-runs the same validation; nothing manual is required as long as the challenge can still be satisfied:

# certbot installs a systemd timer / cron job that runs this regularly: certbot renew --quiet # it only actually renews certs within ~30 days of expiry; otherwise no-op # test your renewal works WITHOUT using rate limits: certbot renew --dry-run
Two real-world gotchas: rate limits and renewal hooks
First, Let's Encrypt enforces rate limits (e.g. a cap on certificates per domain per week). While developing, use the staging environment (--test-cert / --staging) so failed experiments don't burn your weekly quota — staging certs aren't publicly trusted but exercise the full flow. Second, after a renewal your server is often still using the old cert in memory until it reloads — so a renewal deploy hook (e.g. --deploy-hook "systemctl reload nginx") is needed to pick up the new cert. A silently-not-reloaded server is a classic "why did my cert expire when certbot said it renewed?" bug.

When You'd Use a Commercial CA Instead

Let's Encrypt covers the overwhelming majority of needs, but not all. You'd pay a commercial CA when you need OV/EV validation (vetted organization identity, Chapter 5), longer support contracts, warranties, or certificate types Let's Encrypt doesn't issue. For ordinary "encrypt my website" purposes, though, free DV via ACME is the default choice — and the rest of this course assumes it.

Hands-On Exercises

Exercise 1

Generate a private key and a CSR for a domain with both a CN and a SAN list, then inspect the CSR with openssl req -text -noout. Confirm it contains your public key and requested domains but NOT a private key, issuer, or validity dates — and explain why those three are absent.

📄 View solution
Exercise 2

Explain how the HTTP-01 and DNS-01 challenges each prove domain control, then state which one you MUST use to obtain a wildcard certificate for *.example.com and exactly why the other one can't work for a wildcard.

📄 View solution
Exercise 3

A site's certificate expired even though the admin "set up certbot." List the most likely causes (renewal timer not running, server never reloaded the renewed cert, validation challenge now failing) and describe how certbot renew --dry-run and a deploy hook would have prevented it.

📄 View solution

Chapter 9 Quick Reference

  • You generate your private key; it never leaves your server — the CA only ever sees your public key
  • CSR = public key + requested domains (CN/SAN), self-signed to prove key ownership; no issuer/validity yet
  • Domain validation (DV) proves control via a challenge: HTTP-01 (token file), DNS-01 (TXT record), or TLS-ALPN-01
  • Wildcards require DNS-01 — only DNS-zone control proves authority over every subdomain
  • ACME automates the order → challenge → validate → CSR → issue flow; certbot is the common client
  • Let's Encrypt — free, automated, DV-only CA; the reason HTTPS became ubiquitous
  • 90-day certs ⇒ auto-renewal (certbot timer); test with certbot renew --dry-run
  • Gotchas: rate limits → use staging while testing; reload the server via a deploy hook after renewal
  • Next chapter: configuring HTTPS on a server — nginx/Apache, redirects, HSTS, OCSP stapling, SSL Labs