From a34b13a9ba3a11721a3adf2ae5325bf260a56c42 Mon Sep 17 00:00:00 2001 From: Matthew Saunders Brown Date: Tue, 26 Mar 2024 15:09:12 -0700 Subject: [PATCH] new bin/letsencrypt-add.sh --- bin/letsencrypt-add.sh | 126 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100755 bin/letsencrypt-add.sh diff --git a/bin/letsencrypt-add.sh b/bin/letsencrypt-add.sh new file mode 100755 index 0000000..dd66f71 --- /dev/null +++ b/bin/letsencrypt-add.sh @@ -0,0 +1,126 @@ +#!/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