#!/bin/bash key_dir='#ETCDIR#/simple-pki/cb' if [ -r '#ETCDIR#/simple-pki/cb.conf' ]; then . '#ETCDIR#/simple-pki/cb.conf' fi me=$(readlink -e "$0") cd / hosts=$( find '#ETCDIR#/nginx/' \ -name keys -prune , \ -name sites-available -prune , \ \( -type f -o -type l \) \ -exec sed -n ' s/^\s*// /^server_name\s.*;/ p /^server_name[^;]*$/,/;/ p ' {} \; 2>/dev/null \ | tr '\n' ' ' \ | sed ' s/\s\+/ /g s/;\s*/;\n/g '"$( printf 's/\\s%s\\(;\\|\\s\)//\n' "${ignore_hosts[@]}" )"' ' \ | sed -n ' s/^server_name // T s/;$// T p ' \ | sort -u ) host_key_files=$( printf '%s\n' "${hosts}" \ | cut -d' ' -f1 ) if [ "$(whoami)" != "${certificate_user}" ]; then if [ "$(whoami)" = 'root' ]; then chown -R "${certificate_user}" "${key_dir}" su "${certificate_user}" -s /bin/bash -c "${me}" \ || exit $? updated_something=false for host_key_file in ${host_key_files}; do if [ -f "${key_dir}/${host_key_file}.key.new" ] \ && [ -f "${key_dir}/${host_key_file}.crt.new" ] \ && [ -f "${key_dir}/${host_key_file}.chain.new" ]; then mv "${key_dir}/${host_key_file}.key"{.new,} mv "${key_dir}/${host_key_file}.crt"{.new,} mv "${key_dir}/${host_key_file}.chain"{.new,} updated_something=true fi done if ${updated_something}; then systemctl try-restart nginx fi exit $? fi >&2 printf 'only root can su %s\n' "${certificate_user}" exit 1 fi if trap \ | grep -q ' EXIT$'; then >&2 echo 'outer EXIT trap set - this will be forgotten!' exit 1 fi if ! tmp_dir=$(mktemp -d "${webserver_dir}"'/tmp.XXXXXXXXXX'); then >&2 printf 'failed to create temporary directory - does %s have sufficient permissions on "%s"?\n' \ "$(whoami)" \ "${webserver_dir}" exit 1 fi trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT printf '%s\n' "${hosts}" \ | while read -r host other_hosts; do if [ -f "${key_dir}/${host}.key.new" ] \ && [ -f "${key_dir}/${host}.crt.new" ] \ && [ -f "${key_dir}/${host}.chain.new" ]; then continue fi if [ -f "${key_dir}/${host_key_file}.key" ] \ && [ "$(stat -c%Y "${key_dir}/${host_key_file}.key")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ] \ && [ -f "${key_dir}/${host_key_file}.crt" ] \ && [ "$(stat -c%Y "${key_dir}/${host_key_file}.crt")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ] \ && [ -f "${key_dir}/${host_key_file}.chain" ] \ && [ "$(stat -c%Y "${key_dir}/${host_key_file}.chain")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ]; then continue fi SAN=$( printf ',DNS:%s' \ "${host}" \ ${other_hosts} \ | sed 's/^,//' ) \ CN="${host}" \ openssl req -new \ -config '#ETCDIR#/simple-pki/server-ssl.conf' \ -keyout "${key_dir}/${host}.key.new" \ -out "${tmp_dir}/${host}.csr" { printf 'http' if [ -f "${key_dir}/${host}.key" ] \ && [ -f "${key_dir}/${host}.crt" ] \ && [ -f "${key_dir}/${host}.chain" ]; then printf 's' fi printf '://%s/.csr/%s/%s.csr\n' \ "${host}" \ "${tmp_dir##*/}" \ "${host}" } \ >> "${tmp_dir}/commands" done if [ ! -s "${tmp_dir}/commands" ]; then >&2 echo 'nothing to do.' exit fi cd "${tmp_dir}" ssh -T "${ca_host}" \ < 'commands' \ | tar -xzf - for host_key_file in ${host_key_files}; do if [ ! -f "${tmp_dir}/${host_key_file}.crt" ] \ || [ ! -f "${tmp_dir}/${host_key_file}.chain" ]; then continue fi cat "${tmp_dir}/${host_key_file}.crt" \ > "${key_dir}/${host_key_file}.crt.new" cat "${tmp_dir}/${host_key_file}.chain" \ > "${key_dir}/${host_key_file}.chain.new" done