This site is an archive and is no longer updated.
    P1MediumRunbook

    Emergency Certificate Replacement

    Certificate expired or compromised? This runbook gets you back online FAST. Follow these steps to minimize downtime.

    15-30 minutes
    Last Updated: December 2025
    Progress: 0/33 complete0%
    LinkedInX

    When to Use

    • • Certificate has expired and site is showing errors
    • • Certificate needs immediate replacement (not scheduled)
    • • Site is down due to certificate issues

    Do NOT Use For

    • • Private key was compromised (use Key Compromise Response Runbook first)
    • • Scheduled renewal (use Certificate Renewal Runbook for proper planning)

    Quick Reference (TL;DR)

    1. Assess: What broke? Which cert? Expired or compromised?
    2. Get new cert: Let's Encrypt (fastest) or emergency CA issuance
    3. Deploy and reload web server
    4. Verify HTTPS is working
    5. Document what happened

    1Assess the Situation

    Objective: Quickly understand what broke and notify stakeholders

    Check certificate status:

    # Check expiration and issuer
    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
      openssl x509 -noout -subject -issuer -dates
    
    # If connection fails, check what error
    curl -vI https://example.com 2>&1 | head -20

    2Option A: Deploy Backup Certificate

    Objective: If you have a valid backup certificate, deploy it immediately

    Verify backup cert is valid:

    openssl x509 -in backup-cert.pem -noout -dates -subject

    💡 If backup exists and is valid, this is the FASTEST option

    💡 Skip to "Deploy" section with backup certificate

    3Option B: Let's Encrypt (Fastest for Public Sites)

    Objective: Issue a free DV certificate in minutes

    Standalone mode (stop web server first, uses port 80):

    # Stop web server temporarily
    sudo systemctl stop nginx  # or apache2
    
    # Get certificate
    sudo certbot certonly --standalone -d example.com -d www.example.com
    
    # Restart web server
    sudo systemctl start nginx

    Webroot mode (web server keeps running):

    sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com

    Using acme.sh (alternative):

    # Install if needed: curl https://get.acme.sh | sh
    
    acme.sh --issue -d example.com -d www.example.com --webroot /var/www/html
    
    # Or DNS validation (works even if web server is down)
    acme.sh --issue -d example.com --dns dns_cloudflare

    💡 Let's Encrypt issues in under 1 minute

    💡 Rate limits: 50 certs per domain per week, 5 failures per hour

    💡 Certificates are valid for 90 days

    4Option C: Emergency CA Issuance

    Objective: Contact your CA for expedited issuance

    Generate emergency CSR (if needed):

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

    💡 Most CAs offer free reissuance/replacement

    💡 DV certificates can issue in minutes with email/HTTP validation

    💡 OV/EV may take longer unless pre-validated

    💡 Call CA support if portal is slow: DigiCert, Sectigo, GlobalSign all have 24/7 support

    5Deploy Certificate

    Objective: Install the new certificate and get the site back online

    Create certificate bundle:

    cat new-cert.crt intermediate.crt > 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:

    cat new-cert.key bundle.crt > /etc/haproxy/certs/site.pem
    sudo haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl reload haproxy

    IIS (PowerShell):

    # Import PFX
    $password = ConvertTo-SecureString -String "yourpassword" -Force -AsPlainText
    Import-PfxCertificate -FilePath "C:\certs\newcert.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password $password
    
    # Update binding (get thumbprint from import output)
    # Use IIS Manager or: netsh http update sslcert ipport=0.0.0.0:443 certhash=THUMBPRINT appid={APPID}

    6Verify Fix

    Objective: Confirm the site is back online with valid certificate

    Quick verification:

    # Check new certificate
    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
      openssl x509 -noout -dates
    
    # Verify chain is complete
    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
      grep "Verify return code"
    
    # Should show: Verify return code: 0 (ok)

    Full chain check:

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

    7Post-Incident

    Objective: Document and prevent recurrence

    Rollback Procedure

    1. If new certificate causes issues, restore backup certificate
    2. Check web server error logs for specific failure reason
    3. Verify key and certificate match: openssl x509 -noout -modulus -in cert.pem | md5sum && openssl rsa -noout -modulus -in key.pem | md5sum
    4. Contact CA support if certificate appears invalid

    Troubleshooting

    Problem: Let's Encrypt rate limit hit

    Solution: Use staging environment to test, or wait 1 hour (failure limit) / 1 week (certificate limit)

    Problem: Cannot complete domain validation

    Solution: Check DNS propagation, firewall rules, or use DNS-01 challenge instead of HTTP-01

    Problem: Certificate works in browser but API clients fail

    Solution: Check intermediate chain is included, some clients don't fetch missing intermediates

    Problem: Key and certificate don't match

    Solution: Generate new CSR with the new key and reissue - cannot mix keys and certs

    Escalation

    Internal: Contact your security/infrastructure team lead

    CA Support: DigiCert: 1-801-877-2100 | Sectigo: 1-888-266-6361 | GlobalSign: 1-877-775-4562

    After Hours: Follow your organization's on-call escalation procedures