Expired SSL Certificate: Renewal and Resolution

An expired SSL certificate shows visitors a security warning and blocks access to the site. The most common problem is that Certbot's automatic renewal has stopped working.

02

Quick diagnosis

bash
# Check certificate expiration for a domain
echo | openssl s_client -connect tuodominio.com:443 -servername tuodominio.com 2>/dev/null \
  | openssl x509 -noout -dates

# Example output:
# notBefore=Jan  1 00:00:00 2025 GMT
# notAfter=Apr  1 00:00:00 2025 GMT   ← this is the expiration

# Or check local certificates
certbot certificates
03

Manual immediate renewal

bash
# Renew all certificates expiring soon (within 30 days)
certbot renew

# Force renewal even if not expiring
certbot renew --force-renewal

# Renew only a specific domain
certbot certonly --force-renewal -d tuodominio.com -d www.tuodominio.com

# After renewal, reload nginx/apache
systemctl reload nginx
# or
systemctl reload apache2

Let's Encrypt limits to 5 identical certificates per week. Don't abuse --force-renewal. Use it only when necessary.

04

Why automatic renewal stopped working

1. Cron / systemd timer is disabled

bash
# Check if Certbot timer is active
systemctl status certbot.timer

# If inactive, enable it
systemctl enable --now certbot.timer

# Verify cron is present (alternative method)
cat /etc/cron.d/certbot

2. Port 80 is blocked

Certbot uses HTTP-01 challenge on port 80. If firewall blocks it or proxy doesn't forward it, renewal fails.

bash
# Verify port 80 responds
curl -I http://tuodominio.com

# Check firewall
ufw status | grep 80
# or
iptables -L INPUT -n | grep 80

3. Webroot changed

bash
# Display certbot configuration
cat /etc/letsencrypt/renewal/tuodominio.com.conf

# The webroot must point to nginx/apache site root
# Correct example: webroot_path = /var/www/html

4. Nginx/Apache not configured for challenge

Add this block to nginx if missing:

nginx
server {
    listen 80;
    server_name tuodominio.com www.tuodominio.com;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    # Rest of HTTP traffic → HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}
05

Renewal with DNS challenge (if port 80 not accessible)

Useful when server is behind NAT or port 80 is blocked by ISP:

bash
# Certbot with manual DNS challenge
certbot certonly --manual --preferred-challenges dns -d tuodominio.com

# Certbot will ask you to add a TXT record to DNS:
# _acme-challenge.tuodominio.com → "generated_value"
# Add the record, wait for propagation (60-120s), then press Enter
06

Verify and test renewed certificate

bash
# Verify new expiration
certbot certificates

# Complete SSL test (grade A+)
# Visit: https://www.ssllabs.com/ssltest/

# Quick local test
openssl s_client -connect tuodominio.com:443 -servername tuodominio.com 2>/dev/null \
  | openssl x509 -noout -dates -issuer
07

Prevention: reliable automatic renewal

Method 1: systemd timer (recommended)

bash
# Verify timer is active
systemctl status certbot.timer

# Run a dry-run to verify it works
certbot renew --dry-run

# Correct output:
# Congratulations, all simulated renewals succeeded

Method 2: Cron with notification

bash
crontab -e
bash
# Check every day at 3:30, renew if needed
# and reload nginx after renewal
30 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx" 2>&1 | mail -s "Certbot renew" admin@tuodominio.com

Method 3: Certbot post-renewal hook for nginx

bash
# Create hook file
cat > /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh << 'EOF'
#!/bin/bash
systemctl reload nginx
EOF
chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

Certbot automatically runs scripts in /etc/letsencrypt/renewal-hooks/post/ after every successful renewal.

08

Let's Encrypt certificate not available (special case)

If server can't reach internet for validation, use a temporary self-signed certificate:

bash
# Generate self-signed certificate (valid 365 days)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/selfsigned.key \
  -out /etc/ssl/certs/selfsigned.crt \
  -subj "/C=IT/ST=Italy/O=DeluxHost/CN=tuodominio.com"

Consider adding the domain to an SSL monitoring service like UptimeRobot or Uptime Kuma with alerts a few days before expiration: it alerts you if automatic renewal fails silently.

DeluxHost, opgericht in 2023, biedt hoogwaardige hostingoplossingen voor diverse digitale behoeften. Wij bieden gedeelde hosting, VPS en dedicated servers met geavanceerde beveiliging en wereldwijde datacenters.

© DeluxHost, Alle rechten voorbehouden. | BTW-nummer: IT17734661006
Alle systemen operationeel