moving
This commit is contained in:
158
basic_setup/mailadminDns.sh
Executable file
158
basic_setup/mailadminDns.sh
Executable file
@@ -0,0 +1,158 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# mailadminDns.sh
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Setzt AUSSCHLIESSLICH den DNS-Record fuer den mailadmin-Zugang.
|
||||||
|
# Faesst NICHTS anderes an (kein SES, SPF, DKIM, MX, keine anderen
|
||||||
|
# Subdomains). Kann gefahrlos auf bereits migrierten Domains laufen.
|
||||||
|
#
|
||||||
|
# Verwendet dieselbe ensure_record-Logik wie cloudflareMigrationDns.sh,
|
||||||
|
# damit das Verhalten (Create/Update/Skip-bei-identisch) identisch ist.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# PFLICHT-VARIABLEN:
|
||||||
|
# DOMAIN_NAME Kundendomain, z.B. innungsapp.com
|
||||||
|
# CF_API_TOKEN Cloudflare API Token
|
||||||
|
#
|
||||||
|
# OPTIONALE VARIABLEN:
|
||||||
|
# MAILADMIN_HOST Subdomain-Label, Default: "mailadmin"
|
||||||
|
# -> ergibt mailadmin.<DOMAIN_NAME>
|
||||||
|
# MAILADMIN_TARGET CNAME-Ziel, Default: "mail.<DOMAIN_NAME>"
|
||||||
|
# Beispiele:
|
||||||
|
# mail.innungsapp.com (pro-Domain Modell)
|
||||||
|
# mailadmin.bayarea-cc.com (zentrales Modell)
|
||||||
|
# DRY_RUN "true" -> zeigt nur an, aendert nichts
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# BEISPIELE:
|
||||||
|
#
|
||||||
|
# # Standard: mailadmin.innungsapp.com -> mail.innungsapp.com
|
||||||
|
# DOMAIN_NAME=innungsapp.com CF_API_TOKEN=xxx ./mailadminDns.sh
|
||||||
|
#
|
||||||
|
# # Zentrales Modell: mailadmin.innungsapp.com -> mailadmin.bayarea-cc.com
|
||||||
|
# DOMAIN_NAME=innungsapp.com \
|
||||||
|
# MAILADMIN_TARGET=mailadmin.bayarea-cc.com \
|
||||||
|
# CF_API_TOKEN=xxx ./mailadminDns.sh
|
||||||
|
#
|
||||||
|
# # Erst testen ohne zu aendern
|
||||||
|
# DOMAIN_NAME=innungsapp.com CF_API_TOKEN=xxx DRY_RUN=true ./mailadminDns.sh
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# --- KONFIGURATION ---
|
||||||
|
DRY_RUN=${DRY_RUN:-"false"}
|
||||||
|
MAILADMIN_HOST=${MAILADMIN_HOST:-"mailadmin"}
|
||||||
|
MAILADMIN_TARGET=${MAILADMIN_TARGET:-"mail.${DOMAIN_NAME}"}
|
||||||
|
|
||||||
|
# --- CHECKS ---
|
||||||
|
if [ -z "$DOMAIN_NAME" ]; then echo "❌ Fehler: DOMAIN_NAME fehlt."; exit 1; fi
|
||||||
|
if [ -z "$CF_API_TOKEN" ]; then echo "❌ Fehler: CF_API_TOKEN fehlt."; exit 1; fi
|
||||||
|
if ! command -v jq &> /dev/null; then echo "❌ Fehler: 'jq' fehlt."; exit 1; fi
|
||||||
|
if ! command -v curl &> /dev/null; then echo "❌ Fehler: 'curl' fehlt."; exit 1; fi
|
||||||
|
|
||||||
|
RECORD_NAME="${MAILADMIN_HOST}.${DOMAIN_NAME}"
|
||||||
|
|
||||||
|
echo "============================================================"
|
||||||
|
echo " 🔧 mailadmin DNS Setup"
|
||||||
|
echo " 🌐 Domain: $DOMAIN_NAME"
|
||||||
|
echo " 📍 Record: CNAME $RECORD_NAME → $MAILADMIN_TARGET"
|
||||||
|
[ "$DRY_RUN" = "true" ] && echo " ⚠️ DRY RUN MODE - Keine Änderungen!"
|
||||||
|
echo "============================================================"
|
||||||
|
|
||||||
|
# Schutz: CNAME auf sich selbst macht keinen Sinn
|
||||||
|
if [ "$RECORD_NAME" == "$MAILADMIN_TARGET" ]; then
|
||||||
|
echo "❌ Fehler: CNAME-Ziel ist identisch mit dem Record-Namen."
|
||||||
|
echo " $RECORD_NAME kann nicht auf sich selbst zeigen."
|
||||||
|
echo " Setze MAILADMIN_TARGET auf einen anderen Host."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. ZONE ID HOLEN
|
||||||
|
echo "🔍 Suche Cloudflare Zone ID..."
|
||||||
|
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN_NAME" \
|
||||||
|
-H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" | jq -r '.result[0].id')
|
||||||
|
|
||||||
|
if [ "$ZONE_ID" == "null" ] || [ -z "$ZONE_ID" ]; then
|
||||||
|
echo "❌ Zone nicht gefunden für $DOMAIN_NAME."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo " ✅ Zone ID: $ZONE_ID"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# FUNKTION: ensure_record
|
||||||
|
# Identisch zur Logik in cloudflareMigrationDns.sh, reduziert auf
|
||||||
|
# die Typen die wir hier brauchen (CNAME).
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
ensure_record() {
|
||||||
|
local type=$1
|
||||||
|
local name=$2
|
||||||
|
local content=$3
|
||||||
|
local proxied=${4:-false}
|
||||||
|
|
||||||
|
echo " ⚙️ Prüfe $type $name..."
|
||||||
|
|
||||||
|
local search_res=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=$type&name=$name" \
|
||||||
|
-H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json")
|
||||||
|
|
||||||
|
local rec_id=$(echo "$search_res" | jq -r '.result[0].id')
|
||||||
|
local rec_content=$(echo "$search_res" | jq -r '.result[0].content')
|
||||||
|
|
||||||
|
[ -z "$rec_id" ] && rec_id="null"
|
||||||
|
[ -z "$rec_content" ] && rec_content="null"
|
||||||
|
|
||||||
|
local json_data=$(jq -n --arg t "$type" --arg n "$name" --arg c "$content" --argjson p "$proxied" \
|
||||||
|
'{type: $t, name: $n, content: $c, ttl: 3600, proxied: $p}')
|
||||||
|
|
||||||
|
if [ "$rec_id" == "null" ]; then
|
||||||
|
if [ "$DRY_RUN" = "true" ]; then
|
||||||
|
echo " [DRY] Würde ERSTELLEN: $type $name → $content"
|
||||||
|
else
|
||||||
|
local res=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
|
||||||
|
-H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" --data "$json_data")
|
||||||
|
if [ "$(echo $res | jq -r .success)" == "true" ]; then
|
||||||
|
echo " ✅ Erstellt: $type $name → $content"
|
||||||
|
else
|
||||||
|
echo " ❌ Fehler beim Erstellen: $(echo $res | jq -r '.errors[0].message')"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$rec_content" == "$content" ]; then
|
||||||
|
echo " 🆗 Identisch ($rec_content). Überspringe."
|
||||||
|
else
|
||||||
|
if [ "$DRY_RUN" = "true" ]; then
|
||||||
|
echo " [DRY] Würde UPDATEN: '$rec_content' → '$content'"
|
||||||
|
else
|
||||||
|
local res=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$rec_id" \
|
||||||
|
-H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" --data "$json_data")
|
||||||
|
if [ "$(echo $res | jq -r .success)" == "true" ]; then
|
||||||
|
echo " ✅ Aktualisiert: '$rec_content' → '$content'"
|
||||||
|
else
|
||||||
|
echo " ❌ Fehler beim Updaten: $(echo $res | jq -r '.errors[0].message')"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Der eigentliche Record
|
||||||
|
# proxied=false ist hier wichtig: der mailadmin laeuft hinter Caddy
|
||||||
|
# mit eigenem TLS-Zertifikat. Cloudflare-Proxy davor wuerde die
|
||||||
|
# Zertifikatskette stoeren bzw. doppeltes TLS-Terminieren.
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
echo ""
|
||||||
|
echo "--- mailadmin CNAME ---"
|
||||||
|
ensure_record "CNAME" "$RECORD_NAME" "$MAILADMIN_TARGET" false
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "============================================================"
|
||||||
|
echo "✅ Fertig."
|
||||||
|
echo ""
|
||||||
|
echo " mailadmin erreichbar unter: https://$RECORD_NAME"
|
||||||
|
echo ""
|
||||||
|
echo " ⚠️ Wichtig: Caddy muss ein Zertifikat für $RECORD_NAME"
|
||||||
|
echo " ausstellen. Stelle sicher, dass der Hostname in der"
|
||||||
|
echo " Caddy-Konfiguration enthalten ist."
|
||||||
|
echo "============================================================"
|
||||||
Reference in New Issue
Block a user