SSL certificates keep your website safe. They encrypt data between visitors and your server. But certificates expire. When they do, visitors see scary warning messages. This guide shows you how to renew your Nginx SSL certificates with Certbot. You will learn every step. From checking your setup to fixing problems. No more stress about expired certificates.
Quick Reference: Nginx SSL Renewal Checklist with Certbot
Use this checklist before, during, and after renewal. Print it or bookmark this page.
Pre-Renewal Verification Items
| Check Item | Command | Expected Result |
|---|---|---|
| Certbot installed | certbot –version | Version number shows |
| Nginx running | systemctl status nginx | Active (running) |
| Certificate exists | ls /etc/letsencrypt/live/ | Your domain folder listed |
| Disk space enough | df -h | At least 100MB free |
Renewal Execution Steps
- Run dry-run test: certbot renew –dry-run
- Execute renewal: certbot renew
- Reload Nginx: systemctl reload nginx
- Verify new certificate: openssl s_client -connect yourdomain.com:443
Post-Renewal Validation Checks
| Validation | How to Check | Success Indicator |
|---|---|---|
| Certificate date | openssl command or browser | New expiry date (90 days) |
| HTTPS works | Visit https://yourdomain.com | Lock icon in browser |
| SSL Labs grade | ssllabs.com/ssltest | Grade A or A+ |
Prerequisites for Nginx SSL Renewal with Certbot
Before you start, make sure your system is ready. These steps prevent problems later.
Required System Packages and Versions
You need these tools installed on your server:
- Certbot: Version 2.0 or newer. Check with: certbot –version
- Nginx: Version 1.18 or newer. Check with: nginx -v
- Python 3: Version 3.6 or newer. Check with: python3 –version
- Systemd: For automatic renewal timers
If Certbot is not installed, run: sudo apt install certbot python3-certbot-nginx (for Ubuntu/Debian) or sudo yum install certbot python3-certbot-nginx (for CentOS/RHEL).
Nginx Configuration Backup Procedure
Always backup before making changes. This saves you if something goes wrong.
- Create backup folder: sudo mkdir -p /root/nginx-backup-$(date +%Y%m%d)
- Copy Nginx config: sudo cp -r /etc/nginx /root/nginx-backup-$(date +%Y%m%d)/
- Copy certificates: sudo cp -r /etc/letsencrypt /root/nginx-backup-$(date +%Y%m%d)/
- Verify backup: ls -la /root/nginx-backup-*/
Keep backups for at least 30 days. Delete old ones to save space.
Certificate Storage Location Verification
Certbot stores certificates in /etc/letsencrypt/live/. Each domain has its own folder. Check your certificates:
- List certificates: sudo ls -la /etc/letsencrypt/live/
- View certificate details: sudo openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem -text -noout
- Check expiry date: sudo openssl x509 -enddate -noout -in /etc/letsencrypt/live/yourdomain.com/cert.pem
Pre-Flight Checks Before Nginx SSL Renewal with Certbot
These checks catch problems before renewal starts. Do them every time.
Verify Certbot Timer Status
Certbot uses a timer to check for renewal automatically. Make sure it is working:
- Check timer status: systemctl status certbot.timer
- If not active, start it: sudo systemctl enable –now certbot.timer
- View timer schedule: systemctl list-timers certbot.timer
The timer runs twice daily. It only renews if the certificate expires in less than 30 days.
Check Current Certificate Expiration Dates
Know when your certificates expire. This helps you plan renewal:
- Check all certificates: sudo certbot certificates
- Look for “Expiry Date” in the output
- Note which certificates expire soon (within 30 days)
Certbot shows certificate paths, domains, and expiry dates. If you see “INVALID” status, fix it immediately.
Validate Nginx Configuration Syntax
Bad Nginx config breaks your website. Test before renewal:
- Test configuration: sudo nginx -t
- Look for “syntax is ok” and “test is successful”
- If errors appear, fix them in /etc/nginx/nginx.conf or site configs
- Reload after fixes: sudo systemctl reload nginx
Review Renewal Hooks and Scripts
Hooks run commands before and after renewal. Check if you have them:
- List hook folders: ls -la /etc/letsencrypt/renewal-hooks/
- Check deploy folder: ls -la /etc/letsencrypt/renewal-hooks/deploy/
- View hook contents: cat /etc/letsencrypt/renewal-hooks/deploy/*.sh
Common hooks reload Nginx after renewal. If missing, Nginx won’t use the new certificate.
Step-by-Step Nginx SSL Renewal with Certbot
Follow these steps to renew your certificate. Each step has a clear purpose.
Step 1: Run Certbot Renewal Dry-Run Test
A dry-run tests renewal without changing anything. It finds problems early:
- Run the test: sudo certbot renew –dry-run
- Wait for the test to complete (takes 30-60 seconds)
- Look for “Congratulations, all simulated renewals succeeded”
- If it fails, read the error message carefully
Dry-run uses Let’s Encrypt’s staging server. It does not affect your real certificate. Always do this first.
Step 2: Execute Certificate Renewal Command
Now run the actual renewal:
- Renew all certificates: sudo certbot renew
- Or renew one domain: sudo certbot renew –cert-name yourdomain.com
- Watch the output for “new certificate deployed” messages
- Note which certificates were renewed
Certbot only renews certificates expiring within 30 days. If your certificate is new, it says “not yet due for renewal.”
Step 3: Reload Nginx After Successful Renewal
Nginx must reload to use the new certificate:
- Reload Nginx: sudo systemctl reload nginx
- Check Nginx status: sudo systemctl status nginx
- Look for “Active: active (running)”
- If reload fails, test config: sudo nginx -t
Reloading does not stop your website. It keeps serving visitors while loading new config.
Step 4: Force Renewal for Urgent Cases
Sometimes you need to renew immediately. Maybe your certificate expires today:
- Force renewal: sudo certbot renew –force-renewal
- This renews even if not due yet
- Use sparingly. Let’s Encrypt has rate limits (5 certificates per domain per week)
- Reload Nginx: sudo systemctl reload nginx
Only force renewal when necessary. Normal renewal works for most cases.
Post-Renewal Verification for Nginx SSL with Certbot
After renewal, verify everything works. Do not skip these checks.
Verify New Certificate Installation
Confirm Nginx uses the new certificate:
- Check with OpenSSL: echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates
- Look for the new “notAfter” date
- Or visit your site in a browser and click the lock icon
- View certificate details to see the new expiry date
Test SSL/TLS Configuration Online
Use free online tools to test your SSL setup:
- Go to ssllabs.com/ssltest/
- Enter your domain name
- Wait for the test (takes 2-5 minutes)
- Aim for Grade A or A+
- Fix any warnings or errors shown
SSL Labs checks protocol support, key exchange, and cipher strength. It gives detailed reports.
Confirm Certificate Chain Completeness
The certificate chain links your certificate to a trusted root. Missing links cause browser warnings:
- Check chain: openssl s_client -connect yourdomain.com:443 -showcerts
- You should see multiple certificates (your cert + intermediate + root)
- If only one certificate shows, the chain is incomplete
- Fix by ensuring Certbot created the fullchain.pem file
Check Security Headers and HSTS
Security headers add extra protection. Check if they are set:
- Test headers: curl -I https://yourdomain.com
- Look for “Strict-Transport-Security” header
- Check for “X-Content-Type-Options: nosniff”
- Verify “X-Frame-Options: DENY” or “SAMEORIGIN”
Add missing headers in your Nginx config file. Reload Nginx after changes.
Troubleshooting Nginx SSL Renewal with Certbot
Problems happen. Here are common errors and how to fix them.
Common Error: “Failed to Renew Certificate”
Symptom: Certbot says “Failed to renew certificate” with an error message.
Solutions:
- Check internet connection: ping letsencrypt.org
- Verify domain DNS points to your server: dig yourdomain.com
- Check firewall allows port 80 and 443: sudo ufw status
- View detailed logs: sudo cat /var/log/letsencrypt/letsencrypt.log
- Try with verbose output: sudo certbot renew –verbose
Common Error: “Nginx Reload Failed”
Symptom: Certificate renewed but Nginx won’t reload.
Solutions:
- Test Nginx config: sudo nginx -t
- Check error messages in the output
- Common issue: wrong certificate path in Nginx config
- Verify paths: ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
- Check file permissions: sudo ls -la /etc/letsencrypt/live/yourdomain.com/
- Fix config errors and reload: sudo systemctl reload nginx
Common Error: “Domain Validation Failed”
Symptom: Certbot cannot verify you own the domain.
Solutions:
- Ensure domain points to your server IP: dig yourdomain.com +short
- Check web server responds on port 80: curl http://yourdomain.com
- Verify .well-known folder is accessible: curl http://yourdomain.com/.well-known/acme-challenge/test
- Remove redirects from HTTP to HTTPS for validation (temporarily)
- Check firewall allows Let’s Encrypt servers
Rollback Procedure for Failed Renewals
If renewal breaks your site, rollback to the previous certificate:
- Find previous certificate: sudo ls -la /etc/letsencrypt/archive/yourdomain.com/
- Note the previous cert number (e.g., cert1.pem, cert2.pem)
- Update symlinks: sudo ln -sf /etc/letsencrypt/archive/yourdomain.com/cert1.pem /etc/letsencrypt/live/yourdomain.com/cert.pem
- Do the same for privkey.pem and fullchain.pem
- Reload Nginx: sudo systemctl reload nginx
- Or restore from backup: sudo cp -r /root/nginx-backup-*/letsencrypt/* /etc/letsencrypt/
Automating Nginx SSL Renewal with Certbot
Automation saves time and prevents expired certificates. Set it up once, forget about it.
Configure Systemd Timer for Auto-Renewal
Certbot installs a systemd timer by default. Verify it works:
- Check timer exists: systemctl list-timers | grep certbot
- View timer details: systemctl cat certbot.timer
- Enable if needed: sudo systemctl enable certbot.timer
- Start the timer: sudo systemctl start certbot.timer
- Check next run time: systemctl list-timers certbot.timer
The timer runs twice daily. It only renews certificates expiring within 30 days.
Set Up Deploy Hooks for Nginx Reload
Deploy hooks run after successful renewal. Use them to reload Nginx:
- Create hook file: sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
- Add this content: #!/bin/bash
systemctl reload nginx - Make it executable: sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
- Test the hook: sudo /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Now Nginx reloads automatically after every renewal.
Create Pre and Post Renewal Scripts
Pre-renewal scripts run before renewal. Post-renewal scripts run after:
- Create pre-hook: sudo nano /etc/letsencrypt/renewal-hooks/pre/stop-services.sh
- Add: #!/bin/bash
echo “Starting renewal at $(date)” >> /var/log/certbot-renewal.log - Create post-hook: sudo nano /etc/letsencrypt/renewal-hooks/post/notify.sh
- Add: #!/bin/bash
echo “Renewal completed at $(date)” >> /var/log/certbot-renewal.log - Make both executable: sudo chmod +x /etc/letsencrypt/renewal-hooks/pre/*.sh /etc/letsencrypt/renewal-hooks/post/*.sh
Implement Email Alerts for Renewal Status
Get email notifications when certificates renew or fail:
- Install mail utility: sudo apt install mailutils (Ubuntu) or sudo yum install mailx (CentOS)
- Create notification script: sudo nano /etc/letsencrypt/renewal-hooks/post/email-alert.sh
- Add content: #!/bin/bash
echo “Certificate renewed for $RENEWED_DOMAINS” | mail -s “SSL Renewal Success” admin@yourdomain.com - Make executable: sudo chmod +x /etc/letsencrypt/renewal-hooks/post/email-alert.sh
- Test email sending: echo “Test” | mail -s “Test” admin@yourdomain.com
Monitoring and Alerting for Certbot SSL Renewals
Monitoring catches problems before they affect visitors. Set up alerts for peace of mind.
Set Up External Uptime Monitoring
External services check your site from multiple locations:
- UptimeRobot: Free plan checks every 5 minutes. Sign up at uptimerobot.com
- Pingdom: Paid service with detailed reports
- Healthchecks.io: Monitors cron jobs and renewal scripts
Configure alerts for HTTPS failures. You get notified immediately if SSL breaks.
Configure Certificate Expiry Alerts
Get warned before certificates expire:
- Create monitoring script: sudo nano /usr/local/bin/check-cert-expiry.sh
- Add content to check expiry and send alerts if within 14 days
- Set up cron job: sudo crontab -e
- Add line: 0 9 * * * /usr/local/bin/check-cert-expiry.sh
- This runs daily at 9 AM and emails you if certificates expire soon
Log Renewal Events for Audit Trail
Keep records of all renewal activities:
- Certbot logs are in /var/log/letsencrypt/
- View recent logs: sudo tail -f /var/log/letsencrypt/letsencrypt.log
- Set up log rotation to prevent disk space issues
- Create summary reports: sudo grep “renewal” /var/log/letsencrypt/letsencrypt.log | tail -20
Multi-Server Renewal Tracking
If you manage multiple servers, track all renewals in one place:
- Use a central logging server (ELK Stack or Grafana Loki)
- Send renewal logs to central server using rsyslog
- Create dashboard showing all certificate expiry dates
- Set up alerts for any server with certificates expiring soon
Security Hardening After Nginx SSL Renewal with Certbot
After renewal, strengthen your SSL configuration. Protect against known vulnerabilities.
Verify TLS Protocol Versions
Only allow secure TLS versions. Disable old, insecure ones:
- Edit Nginx config: sudo nano /etc/nginx/nginx.conf
- Find or add: ssl_protocols TLSv1.2 TLSv1.3;
- This disables TLS 1.0 and 1.1 (insecure)
- Reload Nginx: sudo systemctl reload nginx
- Test with: openssl s_client -connect yourdomain.com:443 -tls1
- Should show “no protocols available” (good!)
Check Cipher Suite Configuration
Cipher suites encrypt your data. Use strong ones only:
- Add to Nginx config: ssl_ciphers ‘ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384’;
- Add: ssl_prefer_server_ciphers on;
- Reload Nginx: sudo systemctl reload nginx
- Test with SSL Labs to verify strong ciphers are used
Audit SSL Configuration with SSL Labs
SSL Labs provides comprehensive security audits:
- Visit ssllabs.com/ssltest/
- Enter your domain
- Review the detailed report
- Fix any issues marked as red or yellow
- Aim for Grade A+ with no warnings
- Run tests quarterly to maintain security
Review OCSP Stapling Settings
OCSP stapling speeds up SSL handshakes. Enable it:
- Add to Nginx config: ssl_stapling on;
- Add: ssl_stapling_verify on;
- Add: resolver 8.8.8.8 8.8.4.4 valid=300s;
- Add: resolver_timeout 5s;
- Reload Nginx: sudo systemctl reload nginx
- Verify with: openssl s_client -connect yourdomain.com:443 -status
- Look for “OCSP Response Status: successful (0x0)”
FAQ: Nginx SSL Renewal with Certbot
How Often Should I Renew SSL Certificates with Certbot?
Let’s Encrypt certificates last 90 days. Certbot renews them automatically 30 days before expiry. You don’t need to renew manually. The systemd timer checks twice daily. If renewal fails, you get 60 days to fix it before the certificate expires. Most people never renew manually. Just ensure the timer is running.
Can I Renew Certbot SSL Without Downtime?
Yes. Certificate renewal has zero downtime. The process works like this:
- Certbot gets the new certificate in the background
- Nginx reload loads the new certificate without stopping
- Visitors see no interruption
- The reload takes less than 1 second
Only manual configuration errors cause downtime. Always test with “nginx -t” before reloading.
What Happens If Certbot Renewal Fails?
If renewal fails, your current certificate keeps working until it expires. You have time to fix the problem. Common causes include:
- DNS changed and domain no longer points to your server
- Firewall blocks port 80 or 443
- Nginx configuration has errors
- Disk space is full
Check logs at /var/log/letsencrypt/letsencrypt.log for detailed error messages. Fix the issue and run “sudo certbot renew” manually.
How Do I Renew Multiple Domain Certificates at Once?
Certbot renews all certificates with one command:
- Run: sudo certbot renew
- Certbot checks all certificates in /etc/letsencrypt/live/
- It renews any certificate expiring within 30 days
- Each renewed certificate triggers the deploy hook
- Nginx reloads once after all renewals complete
For specific domains, use: sudo certbot renew –cert-name domain1.com –cert-name domain2.com
Summary: Key Takeaways and Next Steps
You now know how to manage Nginx SSL renewal with Certbot. Here are the key points:
- Always backup before making changes
- Test with dry-run before actual renewal
- Verify after renewal with OpenSSL and SSL Labs
- Automate with systemd timer to prevent manual work
- Monitor certificates with external services
- Harden security by using TLS 1.2+ and strong ciphers
Your next steps:
- Run through the quick reference checklist now
- Set up the deploy hook for automatic Nginx reload
- Configure email alerts for renewal status
- Test your SSL with SSL Labs and aim for Grade A+
- Schedule quarterly security audits
SSL certificates protect your visitors. Keep them renewed and your website secure. Check back to this guide whenever you need help with Nginx SSL renewal with Certbot.
