#!/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 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 if [ "$(stat -c%Y "${key_dir}/${host_key_file}.key.new")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ] \ && [ -f "${key_dir}/${host_key_file}.key" ] \ && [ "$(stat -c%Y "${key_dir}/${host_key_file}.crt.new")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ] \ && [ -f "${key_dir}/${host_key_file}.crt" ] \ && [ "$(stat -c%Y "${key_dir}/${host_key_file}.chain.new")" -ge "$(($(date +%s)-60*60*24*key_min_duration))" ] \ && [ -f "${key_dir}/${host_key_file}.chain" ]; then continue fi 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 chown -R "${certificate_user}" "${key_dir}" exec su "${certificate_user}" -s /bin/bash -c "${me}" fi >&2 printf 'only root can su %s\n' "${certificate_user}" exit 1 fi if [ -n "$(trap)" ]; then >&2 echo 'outer traps set - those will be forgotten!' exit 1 fi tmp_dir=$(mktemp -d "${webserver_dir}"'/tmp.XXXXXXXXXX') 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 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 'https://%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