#!/bin/bash # sync-mailcow-cert.sh # Копирует LE-сертификат mail.dttb.ru из NPM (LXC 103) в mailcow (VM 107) # и перезагружает почтовые сервисы ТОЛЬКО при изменении сертификата. # Причина: mailcow с SKIP_LETS_ENCRYPT=y не продлевает cert сам; cert владеет NPM. # История: cert на mail-портах протух 2026-06-02, чинили вручную 2026-06-27. set -euo pipefail NPM_CTID=103 NPM_DIR="/data/compose/2/letsencrypt/live/npm-106" MC_HOST="root@10.0.0.107" MC_KEY="/root/.ssh/mailcow_sync" MC_SSL="/opt/mailcow-dockerized/data/assets/ssl" SSHMC="ssh -i $MC_KEY -o StrictHostKeyChecking=no -o ConnectTimeout=10 $MC_HOST" TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT pct exec "$NPM_CTID" -- cat "$NPM_DIR/fullchain.pem" > "$TMP/cert.pem" pct exec "$NPM_CTID" -- cat "$NPM_DIR/privkey.pem" > "$TMP/key.pem" # sanity-проверки openssl x509 -in "$TMP/cert.pem" -noout >/dev/null 2>&1 || { echo "$(date '+%F %T') ERR: битый cert из NPM"; exit 1; } [ -s "$TMP/key.pem" ] || { echo "$(date '+%F %T') ERR: пустой key из NPM"; exit 1; } CPUB=$(openssl x509 -in "$TMP/cert.pem" -noout -pubkey | openssl md5) KPUB=$(openssl pkey -in "$TMP/key.pem" -pubout 2>/dev/null | openssl md5) [ "$CPUB" = "$KPUB" ] || { echo "$(date '+%F %T') ERR: cert и key не пара"; exit 1; } NEW=$(openssl x509 -in "$TMP/cert.pem" -noout -fingerprint -sha256) CUR=$($SSHMC "openssl x509 -in $MC_SSL/cert.pem -noout -fingerprint -sha256" 2>/dev/null || echo none) if [ "$NEW" = "$CUR" ]; then echo "$(date '+%F %T') cert не изменился — пропуск" exit 0 fi echo "$(date '+%F %T') обнаружен новый cert — деплой" scp -i "$MC_KEY" -o StrictHostKeyChecking=no "$TMP/cert.pem" "$TMP/key.pem" "$MC_HOST:/tmp/" $SSHMC " set -e cd /opt/mailcow-dockerized TS=\$(date +%Y%m%d-%H%M%S) cp $MC_SSL/cert.pem $MC_SSL/cert.pem.bak-\$TS cp $MC_SSL/key.pem $MC_SSL/key.pem.bak-\$TS mv /tmp/cert.pem $MC_SSL/cert.pem mv /tmp/key.pem $MC_SSL/key.pem chmod 644 $MC_SSL/cert.pem; chmod 600 $MC_SSL/key.pem docker compose exec -T postfix-mailcow postfix reload >/dev/null 2>&1 || docker compose restart postfix-mailcow docker compose exec -T dovecot-mailcow dovecot reload >/dev/null 2>&1 || docker compose restart dovecot-mailcow docker compose exec -T nginx-mailcow nginx -s reload >/dev/null 2>&1 || true " echo "$(date '+%F %T') задеплоен: $NEW"