MediumRunbook

Certificate Renewal Runbook

Standard operating procedure for certificate renewal. Follow these steps to renew SSL/TLS certificates safely and completely.

30-60 minutes
Last Updated: December 2025
Progress: 0/38 complete0%

When to Use

  • Certificate expiration is approaching (30-90 days out)
  • Scheduled certificate renewal during maintenance window
  • Upgrading certificate type (e.g., RSA to ECC)

Do NOT Use For

  • Certificate has already expired (use Emergency Replacement Runbook)
  • Private key may be compromised (use Key Compromise Response Runbook)

Quick Reference (TL;DR)

  1. Generate new CSR with correct details
  2. Submit to CA and complete validation
  3. Deploy certificate with full chain
  4. Verify deployment and update documentation

1Pre-Renewal Checklist

Objective: Gather all required information before starting the renewal process

Check current certificate details:

# View certificate from live server
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
  openssl x509 -noout -subject -issuer -dates -ext subjectAltName

# View certificate from file
openssl x509 -in current-cert.pem -noout -text | head -30

2Generate New CSR

Objective: Create a new private key and Certificate Signing Request

RSA 2048-bit key and CSR:

openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.csr \
  -subj "/CN=example.com/O=Your Organization/L=City/ST=State/C=US"

ECC P-256 key and CSR (recommended):

openssl ecparam -genkey -name prime256v1 -out example.com.key
openssl req -new -key example.com.key -out example.com.csr \
  -subj "/CN=example.com/O=Your Organization/L=City/ST=State/C=US"

CSR with multiple SANs (using config file):

# Create openssl.cnf with:
# [req]
# distinguished_name = req_distinguished_name
# req_extensions = v3_req
# [req_distinguished_name]
# [v3_req]
# subjectAltName = @alt_names
# [alt_names]
# DNS.1 = example.com
# DNS.2 = www.example.com
# DNS.3 = api.example.com

openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.csr \
  -config openssl.cnf -subj "/CN=example.com"

Verify CSR contents:

openssl req -in example.com.csr -noout -text

💡 ECC P-256 provides equivalent security to RSA 3072 with better performance

💡 Always generate a NEW private key - do not reuse keys across renewals

3Submit to CA

Objective: Submit CSR to Certificate Authority and complete validation

💡 DV validation methods: HTTP file, DNS CNAME/TXT, or email

💡 For faster renewal, use the same validation method as original issuance

💡 Always download the FULL CHAIN, not just the end-entity certificate

4Deploy Certificate

Objective: Install the new certificate on all target systems

Create certificate bundle:

# Concatenate in this order: cert, intermediate, root (optional)
cat example.com.crt intermediate.crt > example.com-bundle.crt

nginx - test and reload:

sudo nginx -t && sudo systemctl reload nginx

Apache - test and reload:

sudo apachectl configtest && sudo systemctl reload apache2

HAProxy - test and reload:

# HAProxy needs key + cert in single file
cat example.com.key example.com-bundle.crt > /etc/haproxy/certs/example.com.pem
sudo haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl reload haproxy

5Post-Renewal Verification

Objective: Confirm the new certificate is serving correctly

Quick certificate check:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
  openssl x509 -noout -subject -dates

Verify chain is complete:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
  grep -E "(depth|verify)"

Check with curl:

curl -vI https://example.com 2>&1 | grep -A5 "Server certificate"

6Update Documentation

Objective: Record the renewal and schedule the next one

Troubleshooting

Problem: CSR validation fails at CA

Solution: Check CSR format (ensure proper line breaks) and verify domain ownership is confirmed

Problem: Certificate chain incomplete after deployment

Solution: Ensure intermediate certificates are included in the bundle in correct order

Problem: Server config test fails

Solution: Check file paths, permissions (key should be 600), and certificate format (PEM)

Problem: Old certificate still showing after reload

Solution: Clear browser cache, check all load balancer nodes, verify correct config file is loaded