#!/bin/bash
# ===========================================
# Certbot DNS-01 Cleanup Hook pour o2switch
# Supprime l'enregistrement TXT _acme-challenge
# ===========================================
# Variables fournies par certbot:
# CERTBOT_DOMAIN - Le domaine validé
# CERTBOT_VALIDATION - La valeur du challenge
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Config peut être dans lib/ (local) ou au même niveau (sur nginx)
if [ -f "$SCRIPT_DIR/lib/config.sh" ]; then
source "$SCRIPT_DIR/lib/config.sh"
elif [ -f "$SCRIPT_DIR/../../lib/config.sh" ]; then
source "$SCRIPT_DIR/../../lib/config.sh"
else
echo "ERROR: config.sh not found" >&2
exit 1
fi
LOG_FILE="/tmp/certbot-dns-hook.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
log "=== CLEANUP HOOK START ==="
log "Domain: $CERTBOT_DOMAIN"
log "Validation: $CERTBOT_VALIDATION"
# Extraire le sous-domaine
if [[ "$CERTBOT_DOMAIN" == *".$O2SWITCH_DOMAIN" ]]; then
SUBDOMAIN="${CERTBOT_DOMAIN%.$O2SWITCH_DOMAIN}"
SUBDOMAIN="${SUBDOMAIN#\*.}"
TXT_NAME="_acme-challenge.$SUBDOMAIN"
elif [[ "$CERTBOT_DOMAIN" == "$O2SWITCH_DOMAIN" ]]; then
TXT_NAME="_acme-challenge"
else
log "ERROR: Domain $CERTBOT_DOMAIN not part of $O2SWITCH_DOMAIN"
exit 1
fi
log "Looking for TXT record: $TXT_NAME.$O2SWITCH_DOMAIN"
# Récupérer la zone pour trouver l'index de l'enregistrement et le serial
ZONE_DATA=$(curl -4 --connect-timeout 30 -m 60 -s \
-H "Authorization: cpanel $O2SWITCH_USERNAME:$O2SWITCH_API_TOKEN" \
"$O2SWITCH_API_URL/execute/DNS/parse_zone?zone=$O2SWITCH_DOMAIN")
# Récupérer le serial depuis le SOA (nécessaire pour la suppression)
SERIAL_B64=$(echo "$ZONE_DATA" | jq -r '.data[] | select(.record_type == "SOA") | .data_b64[2]' 2>/dev/null)
SERIAL=$(echo "$SERIAL_B64" | base64 -d 2>/dev/null)
log "Zone serial: $SERIAL"
# Trouver le line_index du TXT record avec le bon nom
# Les données sont en base64, on cherche le dname_b64 qui correspond
TXT_NAME_B64=$(echo -n "$TXT_NAME" | base64 -w0)
LINE_INDEX=$(echo "$ZONE_DATA" | jq -r ".data[] | select(.record_type == \"TXT\" and .dname_b64 == \"$TXT_NAME_B64\") | .line_index" 2>/dev/null | head -1)
if [ -z "$LINE_INDEX" ]; then
log "WARNING: TXT record not found by exact match, trying partial match..."
# Essayer de trouver par le nom décodé
LINE_INDEX=$(echo "$ZONE_DATA" | jq -r ".data[] | select(.record_type == \"TXT\") | select(.dname_b64 | @base64d | contains(\"_acme-challenge\")) | .line_index" 2>/dev/null | head -1)
fi
if [ -z "$LINE_INDEX" ]; then
log "WARNING: TXT record not found, may have been already deleted"
log "=== CLEANUP HOOK END ==="
exit 0
fi
log "Found TXT record at line_index: $LINE_INDEX"
# Supprimer l'enregistrement via UAPI (avec serial obligatoire)
RESULT=$(curl -4 --connect-timeout 30 -m 60 -s \
-H "Authorization: cpanel $O2SWITCH_USERNAME:$O2SWITCH_API_TOKEN" \
"$O2SWITCH_API_URL/execute/DNS/mass_edit_zone?zone=$O2SWITCH_DOMAIN&serial=$SERIAL&remove=$LINE_INDEX")
if echo "$RESULT" | grep -q '"status":1'; then
log "SUCCESS: TXT record deleted"
else
log "WARNING: Failed to delete TXT record"
log "Response: $RESULT"
fi
log "=== CLEANUP HOOK END ==="
exit 0