48 lines
1.9 KiB
Bash
48 lines
1.9 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# push-mailcow-cert.sh (runs on Nginx Proxy Manager host)
|
|
# Pushes the npm-5 (mail.wittenberger.us) cert to the mailcow VM when it renews.
|
|
#
|
|
# Requires: an SSH key for a dedicated push user on the mailcow VM (see notes).
|
|
|
|
set -euo pipefail
|
|
|
|
# ---- CONFIG ---------------------------------------------------------------
|
|
NPM_CERT_DIR="/etc/nginx/letsencrypt/live/npm-5" # mail.wittenberger.us cert
|
|
MAILCOW_HOST="<redacted>" # ssh host/alias or IP of mailcow VM
|
|
MAILCOW_SSH_USER="certsync" # dedicated low-priv user on mailcow VM
|
|
SSH_KEY="/root/.ssh/mailcow_certsync" # private key for that user
|
|
REMOTE_STAGING="/home/certsync/incoming" # staging dir on mailcow VM
|
|
# ---------------------------------------------------------------------------
|
|
|
|
SRC_CERT="${NPM_CERT_DIR}/fullchain.pem"
|
|
SRC_KEY="${NPM_CERT_DIR}/privkey.pem"
|
|
|
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
|
|
|
[[ -r "${SRC_CERT}" ]] || { log "ERROR: cert not readable: ${SRC_CERT}"; exit 1; }
|
|
[[ -r "${SRC_KEY}" ]] || { log "ERROR: key not readable: ${SRC_KEY}"; exit 1; }
|
|
|
|
# Track last-pushed fingerprint locally so it only pushes on change.
|
|
STATE_FILE="/var/lib/mailcow-cert-push/last_fp"
|
|
mkdir -p "$(dirname "${STATE_FILE}")"
|
|
|
|
new_fp=$(openssl x509 -noout -fingerprint -sha256 -in "${SRC_CERT}")
|
|
cur_fp=""
|
|
[[ -r "${STATE_FILE}" ]] && cur_fp=$(cat "${STATE_FILE}")
|
|
|
|
if [[ "${new_fp}" == "${cur_fp}" ]]; then
|
|
log "Cert unchanged; nothing to push."
|
|
exit 0
|
|
fi
|
|
|
|
log "Cert changed — pushing to ${MAILCOW_HOST}."
|
|
|
|
# rsync both files into the staging dir. Trailing dot files copied with perms.
|
|
rsync -azL --chmod=F600 \
|
|
-e "ssh -i ${SSH_KEY} -o StrictHostKeyChecking=accept-new" \
|
|
"${SRC_CERT}" "${SRC_KEY}" \
|
|
"${MAILCOW_SSH_USER}@${MAILCOW_HOST}:${REMOTE_STAGING}/"
|
|
|
|
echo "${new_fp}" > "${STATE_FILE}"
|
|
log "Push complete." |