From 98b9306290f99ccbe33ca20acc3fa41ca4507fd1 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Wed, 28 Jan 2026 13:31:39 -0600 Subject: [PATCH] autodiscover --- basic_setup/cloudflareDns.sh | 214 +++++++++++++++++++---------------- 1 file changed, 117 insertions(+), 97 deletions(-) diff --git a/basic_setup/cloudflareDns.sh b/basic_setup/cloudflareDns.sh index fe9308f..3fc12ad 100755 --- a/basic_setup/cloudflareDns.sh +++ b/basic_setup/cloudflareDns.sh @@ -1,156 +1,176 @@ #!/bin/bash -# Cloudflare API-Konfiguration -# Setze deine API-Schlüssel und Zone-ID als Umgebungsvariablen oder ersetze sie direkt +# ========================================== +# KONFIGURATION +# ========================================== + +# AWS_REGION="us-east-2" +# CADDY_SERVER_IP="DEINE_CADDY_IP_HIER" # WICHTIG: IP deines Caddy Servers eintragen +# MAIL_SERVER_HOSTNAME="mail.email-srvr.com" # Der Server, mit dem sich Outlook/iPhone verbinden -# CF_ZONE_ID="1b7756cee93ed8ba8c05bdc3cb0a5da8" # Die Zone-ID deiner Domain bei Cloudflare -AWS_REGION="us-east-2" # AWS-Region if [ -z "$DOMAIN_NAME" ]; then - echo "Fehler: DOMAIN_NAME ist nicht gesetzt." - echo "Bitte setzen Sie die Variable mit: export DOMAIN_NAME='IhreDomain.de'" - exit 1 # Skript mit Fehlercode beenden + echo "Fehler: DOMAIN_NAME ist nicht gesetzt (z.B. export DOMAIN_NAME='bayarea-cc.com')." + exit 1 fi -# Überprüfen, ob der erforderliche API-Token gesetzt ist if [ -z "$CF_API_TOKEN" ]; then - echo "Fehler: Bitte setze CF_API_TOKEN als Umgebungsvariable oder im Skript." + echo "Fehler: CF_API_TOKEN fehlt." + exit 1 +fi +if [ -z "$CADDY_SERVER_IP" ]; then + echo "Fehler: CADDY_SERVER_IP fehlt. Bitte im Skript eintragen." exit 1 fi -# Zone ID basierend auf Domain-Namen abrufen +# Fallback für Mailserver Variable +if [ -z "$MAIL_SERVER_HOSTNAME" ]; then + MAIL_SERVER_HOSTNAME="mail.email-srvr.com" +fi + +# ========================================== +# ZONE ID ERMITTELN +# ========================================== + echo "Zone ID für $DOMAIN_NAME abrufen..." ZONE_RESPONSE=$(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") -# Überprüfen, ob die Antwort erfolgreich war if [ "$(echo $ZONE_RESPONSE | jq -r '.success')" != "true" ]; then echo "Fehler beim Abrufen der Zone ID:" echo $ZONE_RESPONSE | jq . exit 1 fi -# Zone ID extrahieren CF_ZONE_ID=$(echo $ZONE_RESPONSE | jq -r '.result[0].id') +echo "Zone ID: $CF_ZONE_ID" -# Überprüfen, ob eine Zone ID gefunden wurde -if [ -z "$CF_ZONE_ID" ] || [ "$CF_ZONE_ID" = "null" ]; then - echo "Keine Zone ID für $DOMAIN_NAME gefunden. Bitte stelle sicher, dass die Domain bei Cloudflare registriert ist." - exit 1 -fi +# ========================================== +# FUNKTIONEN +# ========================================== -echo "Zone ID für $DOMAIN_NAME: $CF_ZONE_ID" - -# Hilfsfunktion für DNS-Einträge anlegen create_dns_record() { local TYPE=$1 local NAME=$2 local CONTENT=$3 local PROXIED=$4 local TTL=$5 - local PRIORITY=$6 # Neu: MX-Priority + local PRIORITY=$6 - # Standardwerte für Proxied und TTL setzen, falls nicht angegeben - if [ -z "$PROXIED" ]; then - PROXIED="false" - fi - - if [ -z "$TTL" ]; then - TTL=3600 # 1 Stunde - fi + if [ -z "$PROXIED" ]; then PROXIED="false"; fi + if [ -z "$TTL" ]; then TTL=3600; fi - echo "Erstelle $TYPE-Eintrag für $NAME mit Inhalt $CONTENT..." + echo "Erstelle $TYPE-Eintrag für $NAME..." - # Json Payload vorbereiten abhängig vom Record-Typ local JSON_DATA="" if [ "$TYPE" = "MX" ]; then - # Bei MX-Einträgen müssen wir die Priority separat angeben - if [ -z "$PRIORITY" ]; then - PRIORITY=10 # Standard-Priority, falls nicht angegeben - fi - + if [ -z "$PRIORITY" ]; then PRIORITY=10; fi JSON_DATA="{ - \"type\": \"$TYPE\", - \"name\": \"$NAME\", - \"content\": \"$CONTENT\", - \"ttl\": $TTL, - \"priority\": $PRIORITY, - \"proxied\": $PROXIED + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\", + \"ttl\": $TTL, \"priority\": $PRIORITY, \"proxied\": $PROXIED }" elif [ "$TYPE" = "TXT" ]; then - # Bei TXT-Einträgen müssen wir sicherstellen, dass der Inhalt in Anführungszeichen steht - # Aber Anführungszeichen innerhalb von JSON müssen escaped werden - # Wir entfernen zuerst alle vorhandenen Anführungszeichen und fügen sie dann korrekt hinzu CONTENT=$(echo "$CONTENT" | sed 's/"//g') - JSON_DATA="{ - \"type\": \"$TYPE\", - \"name\": \"$NAME\", - \"content\": \"\\\"$CONTENT\\\"\", - \"ttl\": $TTL, - \"proxied\": $PROXIED + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"\\\"$CONTENT\\\"\", + \"ttl\": $TTL, \"proxied\": $PROXIED }" else - # Für alle anderen Record-Typen (z.B. CNAME) JSON_DATA="{ - \"type\": \"$TYPE\", - \"name\": \"$NAME\", - \"content\": \"$CONTENT\", - \"ttl\": $TTL, - \"proxied\": $PROXIED + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\", + \"ttl\": $TTL, \"proxied\": $PROXIED }" fi - # API-Aufruf an Cloudflare curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json" \ - --data "$JSON_DATA" | jq . + --data "$JSON_DATA" | jq -r '.success' } -# DKIM-Einträge abrufen und bei Cloudflare eintragen -echo "DKIM-Tokens abrufen von AWS SES..." -DKIM_TOKENS=$(aws ses get-identity-dkim-attributes \ - --identities ${DOMAIN_NAME} \ - --region ${AWS_REGION} \ - --query "DkimAttributes.\"${DOMAIN_NAME}\".DkimTokens" \ - --output text) +create_srv_record() { + local SERVICE=$1 # z.B. _imap + local PROTO=$2 # z.B. _tcp + local PORT=$3 # z.B. 993 + local TARGET=$4 # z.B. mail.email-srvr.com + local NAME="${SERVICE}.${PROTO}.${DOMAIN_NAME}" -# Überprüfen, ob DKIM-Tokens abgerufen wurden -if [ -z "$DKIM_TOKENS" ]; then - echo "Fehler: Konnte DKIM-Tokens nicht abrufen. Ist die Domain bei AWS SES verifiziert?" - exit 1 + echo "Erstelle SRV-Eintrag für $NAME -> $TARGET:$PORT..." + + local JSON_DATA="{ + \"type\": \"SRV\", + \"name\": \"$NAME\", + \"data\": { + \"service\": \"$SERVICE\", + \"proto\": \"$PROTO\", + \"name\": \"$DOMAIN_NAME\", + \"priority\": 0, + \"weight\": 1, + \"port\": $PORT, + \"target\": \"$TARGET\" + }, + \"ttl\": 3600 + }" + + curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json" \ + --data "$JSON_DATA" | jq -r '.success' +} + +# ========================================== +# 1. AWS SES Setup (DKIM & Verifizierung) +# ========================================== +echo "--- AWS SES Konfiguration ---" +DKIM_TOKENS=$(aws ses get-identity-dkim-attributes \ + --identities ${DOMAIN_NAME} --region ${AWS_REGION} \ + --query "DkimAttributes.\"${DOMAIN_NAME}\".DkimTokens" --output text) + +VERIFICATION_TOKEN=$(aws ses get-identity-verification-attributes \ + --identities ${DOMAIN_NAME} --region ${AWS_REGION} \ + --query "VerificationAttributes.\"${DOMAIN_NAME}\".VerificationToken" --output text) + +if [ -n "$DKIM_TOKENS" ]; then + for TOKEN in ${DKIM_TOKENS}; do + create_dns_record "CNAME" "${TOKEN}._domainkey.${DOMAIN_NAME}" "${TOKEN}.dkim.amazonses.com" "false" + done fi -# Domain-Verifizierungstoken abrufen -VERIFICATION_TOKEN=$(aws ses get-identity-verification-attributes \ - --identities ${DOMAIN_NAME} \ - --region ${AWS_REGION} \ - --query "VerificationAttributes.\"${DOMAIN_NAME}\".VerificationToken" \ - --output text) +if [ -n "$VERIFICATION_TOKEN" ]; then + create_dns_record "TXT" "_amazonses.${DOMAIN_NAME}" "${VERIFICATION_TOKEN}" "false" +fi -# DKIM-Einträge anlegen -echo "DKIM-Einträge anlegen bei Cloudflare..." -for TOKEN in ${DKIM_TOKENS}; do - create_dns_record "CNAME" "${TOKEN}._domainkey.${DOMAIN_NAME}" "${TOKEN}.dkim.amazonses.com" "false" 3600 -done - -# Domain-Verifizierungs-TXT-Eintrag anlegen -echo "Domain-Verifizierungs-TXT-Eintrag anlegen bei Cloudflare..." -create_dns_record "TXT" "_amazonses.${DOMAIN_NAME}" "${VERIFICATION_TOKEN}" "false" 3600 - -# MX-Einträge anlegen -echo "MX-Einträge anlegen bei Cloudflare..." +# ========================================== +# 2. MX Records (AWS SES Ingest) +# ========================================== +echo "--- MX Records (AWS SES) ---" +# Hier leiten wir eingehende Mails an Amazon S3/SQS Pipeline create_dns_record "MX" "${DOMAIN_NAME}" "inbound-smtp.${AWS_REGION}.amazonaws.com" "false" 3600 10 -create_dns_record "MX" "mail.${DOMAIN_NAME}" "feedback-smtp.${AWS_REGION}.amazonses.com" "false" 3600 10 -# SPF-Eintrag anlegen -echo "SPF-Eintrag anlegen bei Cloudflare..." -create_dns_record "TXT" "mail.${DOMAIN_NAME}" "v=spf1 include:amazonses.com ~all" "false" 3600 -# DMARC-Eintrag anlegen -echo "DMARC-Eintrag anlegen bei Cloudflare..." -create_dns_record "TXT" "_dmarc.${DOMAIN_NAME}" "v=DMARC1; p=none; pct=100; rua=mailto:postmaster@${DOMAIN_NAME}" "false" 3600 +# ========================================== +# 3. Autodiscover & Caddy (Client Access) +# ========================================== +echo "--- Autodiscover & Caddy Konfiguration ---" -echo "DNS-Einrichtung abgeschlossen." -echo "Es kann bis zu 72 Stunden dauern, bis AWS SES die Domain verifiziert hat." \ No newline at end of file +# A-Records: Autodiscover Domains zeigen auf deinen Caddy +create_dns_record "A" "autodiscover.${DOMAIN_NAME}" "$CADDY_SERVER_IP" "false" +create_dns_record "A" "autoconfig.${DOMAIN_NAME}" "$CADDY_SERVER_IP" "false" + +# SRV-Records: Apple Clients finden hier deinen IMAP/SMTP Server +create_srv_record "_imap" "_tcp" "993" "$MAIL_SERVER_HOSTNAME" +create_srv_record "_submission" "_tcp" "587" "$MAIL_SERVER_HOSTNAME" + + +# ========================================== +# 4. SPF & DMARC +# ========================================== +echo "--- E-Mail Sicherheit (SPF & DMARC) ---" + +# SPF: Nur Amazon SES erlaubt (Versand läuft darüber) +create_dns_record "TXT" "${DOMAIN_NAME}" "v=spf1 include:amazonses.com ~all" "false" + +# DMARC: Standard Policy +create_dns_record "TXT" "_dmarc.${DOMAIN_NAME}" "v=DMARC1; p=none; pct=100; rua=mailto:postmaster@${DOMAIN_NAME}" "false" + +echo "Fertig. Konfiguration für $DOMAIN_NAME abgeschlossen." \ No newline at end of file