Skip to content

Instantly share code, notes, and snippets.

@ogero
Last active December 2, 2018 22:22
Show Gist options
  • Save ogero/9f68582b04efc6e17df65764db8a8bdf to your computer and use it in GitHub Desktop.
Save ogero/9f68582b04efc6e17df65764db8a8bdf to your computer and use it in GitHub Desktop.
Let's Encrypt Certbot util script for auto registration and renewal of ssl certs
#!/bin/bash
# ######################################################################################## #
# LET'S ENCRYPT CERTBOT UTIL SCRIPT FOR AUTO REGISTRATION AND RENEWAL #
# AUTHOR: GERÓNIMO OÑATIVIA <[email protected]> #
# VERSION: 1.0.0 #
# REQUIREMENTS:
# - CERTBOT (https://certbot.eff.org/) #
# ######################################################################################## #
# ######################################################################################## #
# EXAMPLE VHOST :433 ##################################################################### #
# ######################################################################################## #
# # OPTIONAL BLOCK (not tested)
# SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA
# SSLProtocol All -SSLv2 -SSLv3 -TLSv1
# SSLHonorCipherOrder On
#
# # MANDATORY BLOCK (https://certbot.eff.org/docs/using.html#where-are-my-certificates)
# # See domain_homedirs
# SSLEngine on
# SSLCertificateFile /home/user/cert.pem
# SSLCertificateKeyFile /home/user/privkey.pem
# SSLCertificateChainFile /home/user/chain.pem
#
# # OPTIONAL BLOCK (not tested)
# <FilesMatch "\.(cgi|shtml|phtml|php)$">
# SSLOptions +StdEnvVars
# </FilesMatch>
#
# # OPTIONAL BLOCK (not tested)
# BrowserMatch "MSIE [2-6]" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
# BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
# ######################################################################################## #
# ######################################################################################## #
# EXAMPLE OF .htaccess ################################################################### #
# ######################################################################################## #
# # Force HTTPS and REMOVE www
# RewriteEngine On
# RewriteRule .* - [E=MY_HTTP_HOST:%{HTTP_HOST}]
# RewriteCond %{ENV:MY_HTTP_HOST} ^www\.domain1\.com$ [NC,OR]
# RewriteCond %{HTTPS} !=on [OR]
# RewriteCond %{SERVER_PORT} 80
# RewriteRule ^(.*)$ https://domain1.com/$1 [R=301,L]
# ######################################################################################## #
# ######################################################################################## #
# CONFIGURATION ########################################################################## #
# ######################################################################################## #
CERTBOT_BIN="/usr/bin/certbot"
GOT_RENEW_HOOK="service apache2 restart && service webmin restart"
declare -A domain_webroots
declare -A domain_users
declare -A domain_homedirs
declare -A domain_extra_domains
# Webroots used by letsencrypt to place a token for domain validation
domain_webroots=(
["domain1.com"]="/home/domain1/public_html"
["domain2.com"]="/home/domain2/public_html"
)
# Certs will be chown to this value:value when renew/register
domain_users=(
["domain1.com"]="domain1"
["domain2.com"]="domain2"
)
# Certs pem files will be copied here when renew/register
domain_homedirs=(
["domain1.com"]="/home/domain1"
["domain2.com"]="/home/domain2"
)
# Space separated extra domains to register for the cert (when unregistered)
domain_extra_domains=(
["domain1.com"]=""
["domain2.com"]="www.domain2.com hello.domain2.com bye.domain2.com"
)
# ######################################################################################## #
# Register not registered certs
for DOMAIN in "${!domain_webroots[@]}"
do
WEBROOT="${domain_webroots[$DOMAIN]}"
EXTRA_DOMAINS="${domain_extra_domains[$DOMAIN]}"
if [ ! -f /etc/letsencrypt/live/$DOMAIN/cert.pem ]; then
echo "Domain $DOMAIN is not registered!"
DOMAINS="-d $DOMAIN"
for EXTRA_DOMAIN in $EXTRA_DOMAINS
do
DOMAINS="$DOMAINS -d $EXTRA_DOMAIN"
done
echo "Fetching cert for $DOMAIN using webroot $WEBROOT and domains param $DOMAINS"
$CERTBOT_BIN certonly --non-interactive --expand --agree-tos --keep-until-expiring --webroot -w $WEBROOT $DOMAINS
fi
done
# Renew previously registered certs (if any and if expired)
$CERTBOT_BIN renew
TRIGGER_RENEW_HOOK=false
echo ""
# Test pems modify time (recently modified = recently renewed/registered)
for DOMAIN in "${!domain_webroots[@]}"
do
HOMEDIR="${domain_homedirs[$DOMAIN]}"
USER="${domain_users[$DOMAIN]}"
EXTRA_DOMAINS="${domain_extra_domains[$DOMAIN]}"
if [ -f /etc/letsencrypt/live/$DOMAIN/cert.pem ]; then
if [[ /etc/letsencrypt/live/$DOMAIN/cert.pem -nt $HOMEDIR/cert.pem ]]; then
echo "Domain $DOMAIN cert was recently renewed/registered!"
echo "Copying pem files to $HOMEDIR"
cp /etc/letsencrypt/live/$DOMAIN/cert.pem $HOMEDIR
cp /etc/letsencrypt/live/$DOMAIN/chain.pem $HOMEDIR
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $HOMEDIR
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $HOMEDIR
echo "Changing owner of pem files to $USER:$USER"
chown $USER:$USER $HOMEDIR/cert.pem
chown $USER:$USER $HOMEDIR/chain.pem
chown $USER:$USER $HOMEDIR/fullchain.pem
chown $USER:$USER $HOMEDIR/privkey.pem
echo "Changing permissions of pem files to 0700"
chmod 0700 $HOMEDIR/cert.pem
chmod 0700 $HOMEDIR/chain.pem
chmod 0700 $HOMEDIR/fullchain.pem
chmod 0700 $HOMEDIR/privkey.pem
TRIGGER_RENEW_HOOK=true
else
echo "Domain $DOMAIN cert wasn't renewed/registered recently. Skipping!"
fi
else
echo "Domain $DOMAIN has no cert. Error!"
fi
done
echo ""
if [ "$TRIGGER_RENEW_HOOK" = true ] ; then
echo 'At least one domain was renewed/registered. Executing hook!'
$GOT_RENEW_HOOK
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment