#!/bin/bash # # letsencrypt-tools # https://git.stack-source.com/msb/letsencrypt-tools # Copyright (c) 2024 Matthew Saunders Brown # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # # must be root if [ "$USER" != "root" ]; then exec sudo -u root $0 $@ fi help() { thisfilename=$(basename -- "$0") echo "$thisfilename" echo "Create a Let's Encrypt certificate and enable dovecot/apache configs." echo "" echo "Usage: $thisfilename domain -d [-t] [-n] [-h]" echo "" echo " -h Print this help." echo " -d Domain (hostname) to create certificate for." exit } # set options while getopts "hd:" opt; do case "${opt}" in h ) help exit;; d ) # domain name (hostname) to create cert for domain=${OPTARG,,} # basic but good enough domain name regex validation if [[ ! $domain =~ ^(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then echo "ERROR: Invalid domain name: $1" exit 1 fi ;; \? ) echo "Invalid option: $OPTARG" 1>&2 exit;; : ) echo "Invalid option: $OPTARG requires an argument" 1>&2 exit;; esac done # check for domain (hostname) if [[ -z $domain ]]; then echo "domain (hostname) is required" exit 1 fi # check for existing pem file if [[ -f /etc/ssl/letsencrypt/$domain.pem ]]; then echo "pem file for $domain already exists" exit 1 fi # check that letsencrypt-deploy.path is enabled if [[ ! systemctl --quiet is-enabled letsencrypt-deploy.path ]]; then echo "letsencrypt-deploy.path is not enabled." exit 1 fi dnscheck=false ips=(`ip -4 -o addr show | awk '{ print $4 }' | cut -d / -f 1`) # check dns for domain dns=`host -t A $domain|grep 'has address'|awk '{ print $4 }'` if [[ " ${ips[@]} " =~ " ${dns} " ]]; then command="$command -d $domain" dnscheck=true fi # check dns for www subdomain dns=`host -t A www.$domain|grep 'has address'|awk '{ print $4 }'` if [[ " ${ips[@]} " =~ " ${dns} " ]]; then command="$command -d www.$domain" dnscheck=true fi # copy above www subdomain section and modify as desired to # automatically check for and add additional subdomains to cert # check common additional mail subdomains if [[ $domain = mail.* ]]; then # check for imap subdomain dns=`host -t A ${domain/mail./imap.}|grep 'has address'|awk '{ print $4 }'` if [[ " ${ips[@]} " =~ " ${dns} " ]]; then command="$command -d ${domain/mail./imap.}" dnscheck=true fi # check for smtp subdomain dns=`host -t A ${domain/mail./smtp.}|grep 'has address'|awk '{ print $4 }'` if [[ " ${ips[@]} " =~ " ${dns} " ]]; then command="$command -d ${domain/mail./smtp.}" dnscheck=true fi # check for pop subdomain dns=`host -t A ${domain/mail./pop.}|grep 'has address'|awk '{ print $4 }'` if [[ " ${ips[@]} " =~ " ${dns} " ]]; then command="$command -d ${domain/mail./pop.}" dnscheck=true fi fi # check if any of the dns lookups passed if [[ "$dnscheck" = "false" ]]; then echo "All dns checks failed, can't create cert." exit 1 else # check for letsencrypt-deploy.path dir # should be redundant as we already checked if letsencrypt-deploy.path is running # and letsencrypt-deploy.path ensures dir exists if [[ -d /var/tmp/letsencrypt/ ]]; then # touch file, letsencrypt-deploy.path will take care of the rest touch /var/tmp/letsencrypt/$domain echo "Task handed off to Let's Encrypt Deploy, cert should be created and enabled in less than a minute." else echo "Let's Encrypt Deploy path dir does not exist." echo "There is an issue with letsencrypt-deploy.path." exit 1 fi fi