acme_refresh 3.31 KB
#!/usr/bin/env bash

# скрипт запрашивает новый сертификат с помощью утилиты acme_client
# кладёт его на место старого и перезапускает NGINX

# сертификат выдаётся на 90 дней
# перевыпускать следует раз в месяц

set -e

CONFIGFILE=/etc/acme.conf

# считать настройку из конфига
function readconfig {
  OPTION=$1

  # test file
  if [[ ! -f $CONFIGFILE ]] ; then
          echo "Configuration file $CONFIGFILE not found!"
          exit 1
  fi
  # read option
  readconfig_return_value="$(cat $CONFIGFILE \
	  | grep -v "^[[:space:]]*#" \
          | awk -F "=" '/'$OPTION'/ {print $2}' \
          | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' \
  )"

  # test option
  if [[ -z "$readconfig_return_value" ]] ; then
          echo "Option $OPTION not found in $CONFIGFILE!"
          exit 1
  fi
}

# теперь считываем конфиг
readconfig acme_dir
ACMEDIR=$readconfig_return_value

# выводим дату (для лога)
date

# если нет папки, ничего не делаем
if [[ ! -d "$ACMEDIR" ]] || [[ ! -w "$ACMEDIR" ]]
then
	echo "Check that directory '$ACMEDIR' exists and is writable"
	exit 1
fi

# запускаем клиент для обновления сертификата
set +e && /usr/local/bin/acme_client \
	--account-key $ACMEDIR/account.key \
	--csr $ACMEDIR/site.csr \
	--acme-dir $ACMEDIR/challenges/ > $ACMEDIR/acme_site.crt
ERRCODE=$?
set -e

# проверяем, получилось ли
if [[ $ERRCODE -ne 0 ]] ; then
	echo "Error '$ERRCODE 'while refreshing the certificate"
	exit 1
fi

# вытащить из сертификата адрес issuer, скачать его и конвертировать в .crt
function get_issuer_cer {
  FROM_CERT=$1
  SAVE_FILENAME_BIN=$2
  SAVE_FILENAME_CRT=$3

  # находим нужное поле в сертификате
  ISSUER_URL=$(/usr/bin/openssl x509 -in $FROM_CERT -noout -text \
        | grep "^ *Authority Information Access: $" -A 5 \
        | grep "^ *CA Issuers - URI:http://" | cut -d ":" -f 2-)
  echo downloading $ISSUER_URL

  # если получилось, скачиваем и конвертируем
  if [[ ! -z $ISSUER_URL ]] ; then
    /usr/bin/curl -fSL $ISSUER_URL -o $SAVE_FILENAME_BIN
    echo converting x509/der

    # пробуем прочесть через x509
    set +e && /usr/bin/openssl x509 -inform der -in $SAVE_FILENAME_BIN -out $SAVE_FILENAME_CRT
    ERRCODE=$?
    set -e

    # если не вышло, пробуем pkcs7
    if [[ $ERRCODE -ne 0 ]] ; then
        echo x509/der failed, try pkcs7/der instead
        openssl pkcs7 -print_certs -inform der -in $SAVE_FILENAME_BIN -out $SAVE_FILENAME_CRT
    fi
  fi
}

# получаем промежуточный сертификат
get_issuer_cer $ACMEDIR/acme_site.crt $ACMEDIR/intermediate.der $ACMEDIR/intermediate.crt

# получаем корневой сертификат
get_issuer_cer $ACMEDIR/intermediate.crt $ACMEDIR/root-ca.der $ACMEDIR/root-ca.crt

# записываем в файл
cat $ACMEDIR/acme_site.crt > $ACMEDIR/site.crt
cat $ACMEDIR/intermediate.crt >> $ACMEDIR/site.crt
cat $ACMEDIR/root-ca.crt >> $ACMEDIR/site.crt

# дёргаем nginx
/usr/bin/env nginx -s reload