autodiscover
This commit is contained in:
parent
96a1815b6a
commit
98b9306290
|
|
@ -1,156 +1,176 @@
|
||||||
#!/bin/bash
|
#!/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
|
if [ -z "$DOMAIN_NAME" ]; then
|
||||||
echo "Fehler: DOMAIN_NAME ist nicht gesetzt."
|
echo "Fehler: DOMAIN_NAME ist nicht gesetzt (z.B. export DOMAIN_NAME='bayarea-cc.com')."
|
||||||
echo "Bitte setzen Sie die Variable mit: export DOMAIN_NAME='IhreDomain.de'"
|
exit 1
|
||||||
exit 1 # Skript mit Fehlercode beenden
|
|
||||||
fi
|
fi
|
||||||
# Überprüfen, ob der erforderliche API-Token gesetzt ist
|
|
||||||
if [ -z "$CF_API_TOKEN" ]; then
|
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
|
exit 1
|
||||||
fi
|
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..."
|
echo "Zone ID für $DOMAIN_NAME abrufen..."
|
||||||
ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN_NAME" \
|
ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN_NAME" \
|
||||||
-H "Authorization: Bearer $CF_API_TOKEN" \
|
-H "Authorization: Bearer $CF_API_TOKEN" \
|
||||||
-H "Content-Type: application/json")
|
-H "Content-Type: application/json")
|
||||||
|
|
||||||
# Überprüfen, ob die Antwort erfolgreich war
|
|
||||||
if [ "$(echo $ZONE_RESPONSE | jq -r '.success')" != "true" ]; then
|
if [ "$(echo $ZONE_RESPONSE | jq -r '.success')" != "true" ]; then
|
||||||
echo "Fehler beim Abrufen der Zone ID:"
|
echo "Fehler beim Abrufen der Zone ID:"
|
||||||
echo $ZONE_RESPONSE | jq .
|
echo $ZONE_RESPONSE | jq .
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Zone ID extrahieren
|
|
||||||
CF_ZONE_ID=$(echo $ZONE_RESPONSE | jq -r '.result[0].id')
|
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
|
# FUNKTIONEN
|
||||||
echo "Keine Zone ID für $DOMAIN_NAME gefunden. Bitte stelle sicher, dass die Domain bei Cloudflare registriert ist."
|
# ==========================================
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Zone ID für $DOMAIN_NAME: $CF_ZONE_ID"
|
|
||||||
|
|
||||||
# Hilfsfunktion für DNS-Einträge anlegen
|
|
||||||
create_dns_record() {
|
create_dns_record() {
|
||||||
local TYPE=$1
|
local TYPE=$1
|
||||||
local NAME=$2
|
local NAME=$2
|
||||||
local CONTENT=$3
|
local CONTENT=$3
|
||||||
local PROXIED=$4
|
local PROXIED=$4
|
||||||
local TTL=$5
|
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 "$PROXIED" ]; then
|
if [ -z "$TTL" ]; then TTL=3600; fi
|
||||||
PROXIED="false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$TTL" ]; then
|
echo "Erstelle $TYPE-Eintrag für $NAME..."
|
||||||
TTL=3600 # 1 Stunde
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Erstelle $TYPE-Eintrag für $NAME mit Inhalt $CONTENT..."
|
|
||||||
|
|
||||||
# Json Payload vorbereiten abhängig vom Record-Typ
|
|
||||||
local JSON_DATA=""
|
local JSON_DATA=""
|
||||||
|
|
||||||
if [ "$TYPE" = "MX" ]; then
|
if [ "$TYPE" = "MX" ]; then
|
||||||
# Bei MX-Einträgen müssen wir die Priority separat angeben
|
if [ -z "$PRIORITY" ]; then PRIORITY=10; fi
|
||||||
if [ -z "$PRIORITY" ]; then
|
|
||||||
PRIORITY=10 # Standard-Priority, falls nicht angegeben
|
|
||||||
fi
|
|
||||||
|
|
||||||
JSON_DATA="{
|
JSON_DATA="{
|
||||||
\"type\": \"$TYPE\",
|
\"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\",
|
||||||
\"name\": \"$NAME\",
|
\"ttl\": $TTL, \"priority\": $PRIORITY, \"proxied\": $PROXIED
|
||||||
\"content\": \"$CONTENT\",
|
|
||||||
\"ttl\": $TTL,
|
|
||||||
\"priority\": $PRIORITY,
|
|
||||||
\"proxied\": $PROXIED
|
|
||||||
}"
|
}"
|
||||||
elif [ "$TYPE" = "TXT" ]; then
|
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')
|
CONTENT=$(echo "$CONTENT" | sed 's/"//g')
|
||||||
|
|
||||||
JSON_DATA="{
|
JSON_DATA="{
|
||||||
\"type\": \"$TYPE\",
|
\"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"\\\"$CONTENT\\\"\",
|
||||||
\"name\": \"$NAME\",
|
\"ttl\": $TTL, \"proxied\": $PROXIED
|
||||||
\"content\": \"\\\"$CONTENT\\\"\",
|
|
||||||
\"ttl\": $TTL,
|
|
||||||
\"proxied\": $PROXIED
|
|
||||||
}"
|
}"
|
||||||
else
|
else
|
||||||
# Für alle anderen Record-Typen (z.B. CNAME)
|
|
||||||
JSON_DATA="{
|
JSON_DATA="{
|
||||||
\"type\": \"$TYPE\",
|
\"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\",
|
||||||
\"name\": \"$NAME\",
|
\"ttl\": $TTL, \"proxied\": $PROXIED
|
||||||
\"content\": \"$CONTENT\",
|
|
||||||
\"ttl\": $TTL,
|
|
||||||
\"proxied\": $PROXIED
|
|
||||||
}"
|
}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# API-Aufruf an Cloudflare
|
|
||||||
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
|
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
|
||||||
-H "Authorization: Bearer $CF_API_TOKEN" \
|
-H "Authorization: Bearer $CF_API_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "$JSON_DATA" | jq .
|
--data "$JSON_DATA" | jq -r '.success'
|
||||||
}
|
}
|
||||||
|
|
||||||
# DKIM-Einträge abrufen und bei Cloudflare eintragen
|
create_srv_record() {
|
||||||
echo "DKIM-Tokens abrufen von AWS SES..."
|
local SERVICE=$1 # z.B. _imap
|
||||||
DKIM_TOKENS=$(aws ses get-identity-dkim-attributes \
|
local PROTO=$2 # z.B. _tcp
|
||||||
--identities ${DOMAIN_NAME} \
|
local PORT=$3 # z.B. 993
|
||||||
--region ${AWS_REGION} \
|
local TARGET=$4 # z.B. mail.email-srvr.com
|
||||||
--query "DkimAttributes.\"${DOMAIN_NAME}\".DkimTokens" \
|
local NAME="${SERVICE}.${PROTO}.${DOMAIN_NAME}"
|
||||||
--output text)
|
|
||||||
|
|
||||||
# Überprüfen, ob DKIM-Tokens abgerufen wurden
|
echo "Erstelle SRV-Eintrag für $NAME -> $TARGET:$PORT..."
|
||||||
if [ -z "$DKIM_TOKENS" ]; then
|
|
||||||
echo "Fehler: Konnte DKIM-Tokens nicht abrufen. Ist die Domain bei AWS SES verifiziert?"
|
local JSON_DATA="{
|
||||||
exit 1
|
\"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
|
fi
|
||||||
|
|
||||||
# Domain-Verifizierungstoken abrufen
|
if [ -n "$VERIFICATION_TOKEN" ]; then
|
||||||
VERIFICATION_TOKEN=$(aws ses get-identity-verification-attributes \
|
create_dns_record "TXT" "_amazonses.${DOMAIN_NAME}" "${VERIFICATION_TOKEN}" "false"
|
||||||
--identities ${DOMAIN_NAME} \
|
fi
|
||||||
--region ${AWS_REGION} \
|
|
||||||
--query "VerificationAttributes.\"${DOMAIN_NAME}\".VerificationToken" \
|
|
||||||
--output text)
|
|
||||||
|
|
||||||
# DKIM-Einträge anlegen
|
# ==========================================
|
||||||
echo "DKIM-Einträge anlegen bei Cloudflare..."
|
# 2. MX Records (AWS SES Ingest)
|
||||||
for TOKEN in ${DKIM_TOKENS}; do
|
# ==========================================
|
||||||
create_dns_record "CNAME" "${TOKEN}._domainkey.${DOMAIN_NAME}" "${TOKEN}.dkim.amazonses.com" "false" 3600
|
echo "--- MX Records (AWS SES) ---"
|
||||||
done
|
# Hier leiten wir eingehende Mails an Amazon S3/SQS Pipeline
|
||||||
|
|
||||||
# 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..."
|
|
||||||
create_dns_record "MX" "${DOMAIN_NAME}" "inbound-smtp.${AWS_REGION}.amazonaws.com" "false" 3600 10
|
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..."
|
# 3. Autodiscover & Caddy (Client Access)
|
||||||
create_dns_record "TXT" "_dmarc.${DOMAIN_NAME}" "v=DMARC1; p=none; pct=100; rua=mailto:postmaster@${DOMAIN_NAME}" "false" 3600
|
# ==========================================
|
||||||
|
echo "--- Autodiscover & Caddy Konfiguration ---"
|
||||||
|
|
||||||
echo "DNS-Einrichtung abgeschlossen."
|
# A-Records: Autodiscover Domains zeigen auf deinen Caddy
|
||||||
echo "Es kann bis zu 72 Stunden dauern, bis AWS SES die Domain verifiziert hat."
|
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."
|
||||||
Loading…
Reference in New Issue