Skip to content
fixcerts 6.85 KiB
Newer Older
 #!/bin/bash
#####################################################################################
#                                                                                   #
# Syntax: fixcerts DOMAIN                                                           #
#                                                                                   #
# Use: Extend Letsencrypt SSl certificates for commonly grouped services such as    #
#       Apache,Postfix,Dovecot using Certbot. Useful for keeping all client         #
#       applications referencing the same virtual domain name, such as auto-config  #
#       email clients on phones, i.e. mailuser@mydomain.TLD smtp.mydomain.TLD       #
#       imaps.mydomain.TLD instead of mailuser@mydomain.TLD mail.ISPmaildomain.TLD  #
#       Also useful when sending mail through services like Gmail that will         #
#       validate sender through a negotiated TLS encrypted connection.              #
#                                                                                   #
#       Ex: sh fixcerts myhosteddomain.com                                          #
#                                                                                   #
# Prerequisites:                                                                    #
#   - A Letsencrypt certificate for the DOMAIN must already exist                   #
#   - A seperate certificate each for Dovecot and Postfix were previously generated #
#   - All new host names to add MUST  already exist in DNS at least as a CNAME      #
#   - Edit the Dovecot/Postfix conf to use the alternate certificate                #
#   - Set the variable wr_file to a directory that certbot can read and write from  #
#   - Set the dom_cert=,dv_cert=,pf_cert=,dv_file=, and pf_file= variables          #
#                                                                                   #
# In my case, I ran:                                                                #
#   certbot certonly -webroot /usr/local/ispconfig/interface/acme -d dc.hrst.xyz    #
#   certbot certonly -webroot /usr/local/ispconfig/interface/acme -d pf.hrst.xyz    #
#   to create the separate Dovecot and Postscript certificates, then edited and     #
#   ran the script to extend those certificate, once per hosted domain              #
#                                                                                   #
# If you use only one alternate certifcate for both mail services, set both dv_file #
#     and pf_file to the same file name and set one of  _cert files=""  and         #
#     use the other. If you don't wish to add to a particular certificate, set the  #
#     variable ="", such as dom_cert                                                #
# TODO: Pre-validate desired additions as already existing in DNS                   #
#       Generate SRV Records and add to DNS to autoconfig clients                   #
#                                                                                   #
# Author: tad.hasse@gmail.com                                                       #
#                                                                                   #
#####################################################################################

#bail out on error
set -e

# Hostnames to add to the main domain certificate
dom_cert="webmail"

# Hostnames to add to the Dovecot domain certificate
dv_cert="pop3s imap"

# Hostnames to add to the Postfix domain certificate
pf_cert="mail smtp smtps"

# Name of the certificate file that handles Dovecot
dv_file="dc.hrst.xyz"

# Name of the certificate file that handles Postfix
pf_file="pf.hrst.xyz"

# Writeable webroot for certbot (I use ISPConfig,
wr_file="/usr/local/ispconfig/interface/acme"

new_cert=""
nanobot=""
affected_services=""

if [ -z "$1" ]                           # Is parameter #1 zero length?
   then
     echo "-No DOMAIN specified"          # Or no parameter passed.
     exit 1
   fi

#live_check='/etc/letsencrypt/live/'$1
if [[ ! -d '/etc/letsencrypt/live/'$1 ]]; then
    echo "- DOMAIN certificate for \"$1\" not found -"
    exit 1
   fi

if [[ ! -d '/etc/letsencrypt/live/'${dv_file} ]]; then
    echo "- Dovecot/postoffice certificate" ${dv_file}" for \"$1\" not found -"
    exit 1
   fi

if [[ ! -d '/etc/letsencrypt/live/'${pf_file} ]]; then
    echo "- Postfix/mail certificate" ${pf_file}" for \"$1\" not found -"
    exit 1
   fi

# Have certbot generate its current certificate list for use as input
certbot certificates >~/certfile

# Extend base domain certificate which typically only contains the domain.TLD and www.domain.TLD
if [[ ! -z "${dom_cert}" ]]; then
    echo
    new_cert=$(echo $dom_cert| sed -e "s/ /.$1 /g" -e 's/ / -d /g' -e "s/$/.$1 /g" -e 's/^/-d /g')
    echo "Adding" ${new_cert} " to "$1
    nanobot=$(grep -A1 "Certificate Name: "$1 certfile |awk -F': ' '{ {getline}; $1=""; print }'|sed  's/ / -d /g')
    doit_cert=$(echo "certbot certonly --webroot -w ${wr_file}${nanobot} ${new_cert}")
    ${doit_cert}
    affected_services=${affected_services}+"A"
else
    echo "Domain Certificate unaffected"
  fi

# Extend the Dovecot certificate
if [[ ! -z "${dv_cert}" ]]; then
    echo
    new_cert=$(echo $dv_cert| sed -e "s/ /.$1 /g" -e 's/ / -d /g' -e "s/$/.$1 /g" -e 's/^/-d /g')
    echo "Adding" ${new_cert} " to "${dv_file}
    nanobot=$(grep -A1 "Certificate Name: "${dv_file} certfile |awk -F': ' '{ {getline}; $1=""; print }'|sed  's/ / -d /g')
    doit_cert=$(echo "certbot certonly --webroot -w ${wr_file}${nanobot} ${new_cert}")
    ${doit_cert}
    affected_services=${affected_services}+"D"
else
    echo "Dovecot Certificate unaffected"
  fi

# Extend the Postscript certificate
if [[ ! -z "{$pf_cert}" ]]; then
    echo
    new_cert=$(echo $pf_cert| sed -e "s/ /.$1 /g" -e 's/ / -d /g' -e "s/$/.$1 /g" -e 's/^/-d /g')
    echo "Adding" ${new_cert} " to " ${pf_file}
    nanobot=$(grep -A1 "Certificate Name: "${pf_file} certfile |awk -F': ' '{ {getline}; $1=""; print }'|sed  's/ / -d /g')
    doit_cert=$(echo "certbot certonly --webroot -w ${wr_file}${nanobot} ${new_cert}")
    ${doit_cert}
    affected_services=${affected_services}+"P"
else
    echo "Postfix Certificate unaffected"
  fi

  if [[ $affected_services == *"A"* ]]; then
     echo "Remember to restart the httpd service"
   fi
  if [[ $affected_services == *"D"* ]]; then
    echo "Remember to restart the dovecot/postoffice service"
   fi
  if [[ $affected_services == *"P"* ]]; then
    echo "Remember to restart the postfix/sendmail  service"
   fi

echo
echo
echo "Add the following SRV records to DNS for client setup for "$1
  if [[ $affected_services == *"D"* ]]; then
    echo "_imaps._tcp."$1 "SRV 3600  4 60 993 imaps"
    echo "_pop3s._tcp."$1 "SRV 3600  6 60 995 pop3s"
    echo "_imap._tcp."$1 " SRV 3600  8 60 143 imap"
  fi
if [[ $affected_services == *"P"* ]]; then
    echo "_smtps._tcp."$1 "SRV 3600  8 60 465 smtps"
    echo "_smtp._tcp."$1 " SRV 3600 10 60 587 smtp"
  fi