#!/bin/bash path="$( cd "$(dirname "$0")" ; pwd -P )" ############# # variables acme_dir=/docker/certs/acme-challenge/.well-known/acme-challenge opt_dir=/docker/certs/.opt account_key=$opt_dir/account.key acme_tiny=$opt_dir/acme_tiny.py openssl_conf=$opt_dir/openssl.conf ############# # script main() { # stop script if receive SIGINT (ctrl-c) trap "exit" INT #print starting date echo "Cert renew script: $(date)" # check if needed files are provided if [ $# -eq 0 ]; then echo "No arguments provided." echo "Usage: $0 [folder]" exit 1 fi if [ ! -d "$opt_dir" ]; then echo "opt dir doesn't exists!" exit 1 fi if [ ! -d "$acme_dir" ]; then echo "acme directory ($acme_dir) doesn't exists!" exit 1 fi if [ ! -s "$account_key" ]; then echo "Account Key doesn't exists!" exit 1 fi if [ ! -s "$acme_tiny" ]; then echo -n "Python script acme_tiny.py is missing. Downloading... " wget -qO "$acme_tiny" https://raw.githubusercontent.com/diafygi/acme-tiny/4.1.0/acme_tiny.py if [ $? != 0 ]; then echo -ne "\nCould not download acme_tiny.py script.\n" rm -f "$acme_tiny" exit 1 fi echo -ne "Finished\n" fi acme_dir=${acme_dir%/} opt_dir=${opt_dir%/} # check if python is installed command -v python >/dev/null 2>&1 || { echo >&2 "Python is required but it's not installed. Aborting."; exit 1; } counter=0 for arg in "$@" do process_renewal if [ $? == 0 ]; then echo "Certificate successfully created!" counter=$((counter+1)) fi done echo "$counter new certificates created!" } process_renewal() ( arg="$path/${arg%/}" if [ ! -d "$arg" ]; then echo "Folder $arg doesn't exists!" return 1 fi if [ ! -s "$arg/domain.conf" ]; then echo "Configuration file doen't exists!" return 1 fi # load configuration variables source "$arg/domain.conf" # check domain.conf variables if [ -z "$NAME" ]; then echo "No name given for domain \"$arg\"". return 1 fi echo "Processing certificate \"$NAME\"..." if [ ${#DOMAINS[@]} -eq 0 ]; then echo "No domains given for \"$NAME\"." return 1 fi # domain key key="$arg/$NAME.key" if [ ! -s "$key" ]; then echo "Domain key doesn't exists. Generating..." openssl genrsa 4096 > "$key" #openssl ecparam -out "$key" -name secp384r1 -genkey fi # domain csr csr="$arg/$NAME.csr" if [ ! -s "$csr" ]; then echo "Domain csr file doesn't exists. Generating..." if [ ${#DOMAINS[@]} -eq 1 ]; then # single domain openssl req -new -sha256 -key "$key" -subj "/CN=$DOMAINS" > "$csr" else # multi domain # expand domain array with ",DNS:" read -r DOMAINS < <( printf "%s,DNS:" "${DOMAINS[@]:0:$((${#DOMAINS[@]} - 1))}"; echo "${DOMAINS[@]: -1}"; ) san_string="[SAN]\nsubjectAltName=DNS:$DOMAINS" openssl req -new -sha256 -key "$key" -subj "/" -reqexts SAN -config <(cat "$openssl_conf" <(printf "$san_string")) > "$csr" fi fi if [ $? != 0 ]; then echo "Creating csr/key files FAILED for \"$NAME\"!" return 1 fi # get certificate python "$acme_tiny" --quiet --account-key "$account_key" --csr "$csr" --acme-dir "$acme_dir" > "$arg/tmp.pem" if [ $? != 0 ]; then rm -rf $arg/tmp.pem echo "Getting certificate for \"$NAME\" FAILED!" return 1 fi if [ -s "$arg/tmp.pem" ]; then mv -f "$arg/tmp.pem" "$arg/$NAME.pem" else echo "New certificate for \"$NAME\" doesn't exists or is empty" rm -rf "$arg/tmp.pem" return 1 fi return 0 ) main "$@"; exit