Automating SSL Certificate Renewal with Certbot and Nginx

SSL (Secure Sockets Layer) certificates are a crucial component of web security, encrypting data transmission between clients and servers. However, SSL certificates have an expiration date, after which they become invalid and must be renewed. SSL certificate renewal can be a tedious and error-prone task, especially for websites with multiple domains and subdomains. Fortunately, the open-source Certbot tool automates the SSL certificate renewal process, integrating with popular web servers like Nginx.

In this blog post, we’ll demonstrate how to automate SSL certificate renewal with Certbot and Nginx using a Bash script. The script loops through all Nginx sites configured in /etc/nginx/sites-available and checks if any SSL certificate is due for renewal (within 30 days of expiration). If so, the script runs Certbot with a dry run (to test the certificate fetch process) and then renews the certificates with Certbot (using the –force-renewal flag). Finally, the script restarts Nginx to use the new certificates.

Here’s the Bash script:

#!/bin/bash

# Set the email address to use for renewal and recovery purposes
EMAIL="your-email@example.com"

# Loop through all the Nginx sites configured in /etc/nginx/sites-available
for SITE in $(ls /etc/nginx/sites-available/); do
  # Extract the domain names from the Nginx configuration file
  DOMAINS=$(grep -Po '(?<=server_name )[^; ]+' /etc/nginx/sites-available/$SITE)
  # Check if the certificate for any of the domains is due for renewal (within 30 days of expiration)
  RENEW=false
  for DOMAIN in $DOMAINS; do
    if sudo certbot certificates | grep -q "$DOMAIN"; then
      EXPIRATION_DATE=$(sudo certbot certificates | grep -A 1 "$DOMAIN" | tail -n 1 | cut -d " " -f 4)
      if [[ "$(date -d "${EXPIRATION_DATE}" +%s)" -gt "$(($(date +%s) + 2592000))" ]]; then
        echo "Certificate for $DOMAIN is not due for renewal yet"
        continue 2
      fi
      RENEW=true
    fi
  done
  if ! $RENEW; then
    echo "No certificates to renew for ${DOMAINS[@]}"
    continue
  fi
  # Test the certificate fetch process with a dry run
  DOMAINS_ARG=""
  for DOMAIN in $DOMAINS; do
    DOMAINS_ARG="$DOMAINS_ARG -d $DOMAIN"
  done
  CMD="sudo certbot certonly --nginx --agree-tos --email $EMAIL $DOMAINS_ARG --dry-run"
  echo "Running command: $CMD"
  eval $CMD
  # Check if the dry run succeeded
  if [[ $? -eq 0 ]]; then
    # Renew the certificates for the domains using Certbot
    CMD="sudo certbot certonly --nginx --agree-tos --email $EMAIL $DOMAINS_ARG --force-renewal"
    echo "Running command: $CMD"
    eval $CMD
  fi
done

# Restart Nginx to use the new certificates
CMD="sudo systemctl restart nginx"
echo "Running command: $CMD"
eval $CMD

Before running the script, make sure to replace your-email@example.com with your actual email address (which will be used for renewal and recovery purposes).

You can run the script manually or set up a cron job to run it automatically at regular intervals!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *