110 lines
4.0 KiB
Django/Jinja
110 lines
4.0 KiB
Django/Jinja
#!/usr/bin/env bash
|
|
# The home-server project produces a multi-purpose setup using Ansible.
|
|
# Copyright © 2018 Y. Gablin, under the GPL-3.0-or-later license.
|
|
# Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing.
|
|
|
|
RSH=/usr/local/bin/{{DMZ}}
|
|
ETC_CHANGED_{{hostname}}=
|
|
ETC_CHANGED_{{DMZ}}=
|
|
|
|
etckeeper_hook() {
|
|
if [ -n "$ETC_CHANGED_{{hostname}}" ]; then
|
|
etc_stop_local 'ACME update'
|
|
fi
|
|
if [ -n "$ETC_CHANGED_{{DMZ}}" ]; then
|
|
$RSH "etc_stop_local 'ACME update'"
|
|
fi
|
|
}
|
|
|
|
trap etckeeper_hook EXIT
|
|
|
|
deploy_challenge() {
|
|
local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
|
|
|
|
printf '%s' "$TOKEN_VALUE" >"$WELLKNOWN/$TOKEN_FILENAME"
|
|
}
|
|
|
|
clean_challenge() {
|
|
local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
|
|
|
|
rm -f "$WELLKNOWN/$TOKEN_FILENAME"
|
|
}
|
|
|
|
# $1: force|test; $2: KEYFILE; $3: CERTFILE; $4: FULLCHAINFILE; $5: CHAINFILE; $6: TIMESTAMP
|
|
deploy_exim() {
|
|
if [ "$1" == test ] \
|
|
&& $RSH 'test -f /etc/mail/exim.pem && test -f /etc/mail/exim.crt' \
|
|
&& $RSH 'find /etc/mail/exim.{pem,crt} -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q ..' ${6%.*}; then
|
|
return 0
|
|
fi
|
|
local copy='cat >$1; chown exim $1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1'
|
|
$RSH "$copy" /etc/mail/exim.pem $6 <"$2"
|
|
$RSH "$copy" /etc/mail/exim.crt $6 <"$4"
|
|
systemctl -M {{DMZ}} reload exim.service
|
|
ETC_CHANGED_{{DMZ}}=1
|
|
}
|
|
|
|
# $1: force|test; $2: KEYFILE; $3: CERTFILE; $4: FULLCHAINFILE; $5: CHAINFILE; $6: TIMESTAMP
|
|
deploy_prosody() {
|
|
if [ "$1" == test ] \
|
|
&& $RSH 'test -f /etc/prosody/certs/{{net_soa}}.key && test -f /etc/prosody/certs/{{net_soa}}.crt' \
|
|
&& $RSH 'find /etc/prosody/certs/{{net_soa}}.{key,crt} -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q ..' ${6%.*}; then
|
|
return 0
|
|
fi
|
|
local copy='cat >$1; chown prosody $1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1'
|
|
$RSH "$copy" /etc/prosody/certs/{{net_soa}}.key $6 <"$2"
|
|
$RSH "$copy" /etc/prosody/certs/{{net_soa}}.crt $6 <"$4"
|
|
systemctl -M {{DMZ}} reload prosody.service
|
|
ETC_CHANGED_{{DMZ}}=1
|
|
}
|
|
|
|
# $1: force|test; $2: KEYFILE; $3: CERTFILE; $4: FULLCHAINFILE; $5: CHAINFILE; $6: TIMESTAMP
|
|
deploy_haproxy() {
|
|
if [ "$1" == test ] \
|
|
&& $RSH 'test -f /etc/haproxy/tls.pem' \
|
|
&& $RSH 'find /etc/haproxy/tls.pem -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q .' ${6%.*}; then
|
|
return 0
|
|
fi
|
|
local copy='cat >$1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1'
|
|
cat "$4" "$2" | $RSH "$copy" /etc/haproxy/tls.pem $6
|
|
systemctl -M {{DMZ}} reload haproxy.service
|
|
ETC_CHANGED_{{DMZ}}=1
|
|
}
|
|
|
|
deploy_cert() {
|
|
local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
|
|
|
|
deploy_exim force "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
deploy_prosody force "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
deploy_haproxy force "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
}
|
|
|
|
unchanged_cert() {
|
|
local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="$(find "$2" -printf '%T@')"
|
|
|
|
deploy_exim test "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
deploy_prosody test "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
deploy_haproxy test "$KEYFILE" "$CERTFILE" "$FULLCHAINFILE" "$CHAINFILE" "$TIMESTAMP"
|
|
}
|
|
|
|
invalid_challenge() {
|
|
local DOMAIN="${1}" RESPONSE="${2}"
|
|
|
|
printf 'Failed ACME challenge for DOMAIN=%s: RESPONSE=%s\n' "$DOMAIN" "$RESPONSE" >&2
|
|
}
|
|
|
|
request_failure() {
|
|
local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}"
|
|
|
|
printf 'Failed %s request for ACME: STATUSCODE=%s (%s)\n' "$REQTYPE" "$STATUSCODE" "$REASON" >&2
|
|
}
|
|
|
|
exit_hook() {
|
|
return 0
|
|
}
|
|
|
|
HANDLER="$1"; shift
|
|
if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|deploy_cert|unchanged_cert|invalid_challenge|request_failure|exit_hook)$ ]]; then
|
|
"$HANDLER" "$@"
|
|
fi
|