|
| 1 | +# Let's Encrypt mit DNS-01-Challenge |
| 2 | + |
| 3 | +## Einführung |
| 4 | + |
| 5 | +### Was ist die DNS-01-Challenge? |
| 6 | + |
| 7 | +DNS-01 ist eine alternative ACME (Automated Certificate Management Environment) Validierungsmethode, die den Domainbesitz durch DNS-TXT-Records anstelle von HTTP-Anfragen nachweist. Bei der Anforderung eines Zertifikats mit DNS-01: |
| 8 | + |
| 9 | +1. Der ACME-Server (Let's Encrypt) stellt einen einzigartigen Token bereit |
| 10 | +2. Ihr mailcow-Server erstellt automatisch einen DNS-TXT-Record `_acme-challenge.ihredomain.de` mit diesem Token |
| 11 | +3. Let's Encrypt fragt DNS ab, um zu überprüfen, ob der Record existiert |
| 12 | +4. Nach erfolgreicher Prüfung wird Ihr Zertifikat ausgestellt |
| 13 | + |
| 14 | +mailcow nutzt [acme.sh](https://github.com/acmesh-official/acme.sh) für die DNS-01-Validierung und unterstützt über 150 DNS-Provider über deren APIs. |
| 15 | + |
| 16 | +### Wann die DNS-Challenge verwenden? |
| 17 | + |
| 18 | +Erwägen Sie die Verwendung der DNS-01-Challenge, wenn Sie Folgendes benötigen: |
| 19 | + |
| 20 | +- **Wildcard-Zertifikate** (`*.example.de`) - HTTP-01 kann keine Wildcard-Zertifikate ausstellen |
| 21 | +- **Server hinter Firewall** - Port 80 (HTTP) ist blockiert oder nicht öffentlich erreichbar |
| 22 | +- **Komplexe Reverse-Proxy-Setups** - HTTP-Validierung würde den falschen Server erreichen |
| 23 | +- **Mehrere Server, die sich eine Domain teilen** - HTTP-Challenge könnte einen anderen Server erreichen |
| 24 | +- **Reduzierte externe Exposition** - Kein Port 80 muss ins Internet exponiert werden |
| 25 | + |
| 26 | +### Wann NICHT die DNS-Challenge verwenden? |
| 27 | + |
| 28 | +Bleiben Sie bei der Standard-HTTP-01-Challenge, wenn: |
| 29 | + |
| 30 | +- Sie ein einfaches Single-Server-Setup mit öffentlichem HTTP-Zugang haben (einfacher zu konfigurieren) |
| 31 | +- Ihr DNS-Provider keinen API-Zugang bietet oder von acme.sh nicht unterstützt wird |
| 32 | +- Sie den DNS-API-Zugang aufgrund organisatorischer Einschränkungen nicht automatisieren können |
| 33 | +- Sie keine Wildcard-Zertifikate benötigen |
| 34 | + |
| 35 | +!!! note "Standard-Methode" |
| 36 | + mailcow verwendet standardmäßig die HTTP-01-Challenge, die für die meisten Installationen gut funktioniert. Wechseln Sie nur zu DNS-01, wenn Sie einen spezifischen Bedarf dafür haben. |
| 37 | + |
| 38 | +--- |
| 39 | + |
| 40 | +## Voraussetzungen |
| 41 | + |
| 42 | +Bevor Sie die DNS-01-Challenge aktivieren, stellen Sie sicher, dass Sie Folgendes haben: |
| 43 | + |
| 44 | +1. **mailcow Version 2026-03 oder neuer** |
| 45 | +2. **Einen unterstützten DNS-Provider** mit API-Zugang (siehe [Unterstützte DNS-Provider](#unterstutzte-dns-provider)) |
| 46 | +3. **API-Zugangsdaten** von Ihrem DNS-Provider mit Berechtigung zum Bearbeiten von DNS-Records |
| 47 | +4. **Verständnis Ihrer DNS-Zonenstruktur** (welche Domains/Subdomains Zertifikate benötigen) |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Konfiguration |
| 52 | + |
| 53 | +### Schritt 1: DNS-Challenge in mailcow.conf aktivieren |
| 54 | + |
| 55 | +Bearbeiten Sie `/opt/mailcow-dockerized/mailcow.conf` und fügen Sie folgende Parameter hinzu oder ändern Sie sie: |
| 56 | + |
| 57 | +```bash |
| 58 | +# DNS-01-Challenge aktivieren (statt HTTP-01) |
| 59 | +ACME_DNS_CHALLENGE=y |
| 60 | + |
| 61 | +# DNS-Provider-Plugin angeben (siehe Provider-Liste unten) |
| 62 | +# Beispiel: dns_servercow für Servercow, dns_cf für CloudFlare, dns_aws für AWS Route53 |
| 63 | +ACME_DNS_PROVIDER=dns_servercow |
| 64 | + |
| 65 | +# E-Mail-Adresse für ACME-Account-Registrierung |
| 66 | +ACME_ACCOUNT_EMAIL=admin@example.de |
| 67 | +``` |
| 68 | + |
| 69 | +!!! warning "Wichtige Einstellungen" |
| 70 | + - Wenn `ACME_DNS_CHALLENGE=y` gesetzt ist, ignoriert mailcow `SKIP_HTTP_VERIFICATION` (es ist impliziert) |
| 71 | + - Port 80 wird für DNS-Challenge **nicht benötigt** |
| 72 | + - Alle Domains in Ihrer mailcow-Installation verwenden DNS-01 (HTTP-01 und DNS-01 können nicht gemischt werden) |
| 73 | + |
| 74 | +### Schritt 2: DNS-Provider-Zugangsdaten konfigurieren |
| 75 | + |
| 76 | +Erstellen oder bearbeiten Sie `/opt/mailcow-dockerized/data/conf/acme/dns-01.conf`: |
| 77 | + |
| 78 | +```bash |
| 79 | +# Servercow Beispiel |
| 80 | +SERVERCOW_API_Username="servercow-api-username" |
| 81 | +SERVERCOW_API_Password="servercow-api-password" |
| 82 | +``` |
| 83 | + |
| 84 | +Das Dateiformat sind einfache `key=value` Paare. Jeder DNS-Provider benötigt unterschiedliche Variablen - siehe [Konfigurations-Beispiele](#konfigurations-beispiele) für Ihren spezifischen Provider. |
| 85 | + |
| 86 | +### Schritt 3: Konfiguration anwenden |
| 87 | + |
| 88 | +Starten Sie den acme-mailcow-Container neu, um die Änderungen anzuwenden: |
| 89 | + |
| 90 | +=== "docker compose (Plugin)" |
| 91 | + |
| 92 | + ``` bash |
| 93 | + cd /opt/mailcow-dockerized |
| 94 | + docker compose up -d |
| 95 | + ``` |
| 96 | + |
| 97 | +=== "docker-compose (Standalone)" |
| 98 | + |
| 99 | + ``` bash |
| 100 | + cd /opt/mailcow-dockerized |
| 101 | + docker-compose up -d |
| 102 | + ``` |
| 103 | + |
| 104 | +### Schritt 4: Zertifikatsanforderung überwachen |
| 105 | + |
| 106 | +Beobachten Sie die Logs, um zu überprüfen, ob die DNS-Challenge funktioniert: |
| 107 | + |
| 108 | +=== "docker compose (Plugin)" |
| 109 | + |
| 110 | + ``` bash |
| 111 | + docker compose logs -f acme-mailcow |
| 112 | + ``` |
| 113 | + |
| 114 | +=== "docker-compose (Standalone)" |
| 115 | + |
| 116 | + ``` bash |
| 117 | + docker-compose logs -f acme-mailcow |
| 118 | + ``` |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## Unterstützte DNS-Provider |
| 123 | + |
| 124 | +mailcow nutzt acme.sh DNS-API-Plugins. Über 150 Provider werden unterstützt. |
| 125 | + |
| 126 | +### Tier 1: Vollständig getestet & empfohlen |
| 127 | + |
| 128 | +| Provider | Plugin-Name | Benötigte Zugangsdaten | Dokumentation | |
| 129 | +|----------|-------------|------------------------|---------------| |
| 130 | +| **Servercow** | `dns_servercow` | `SERVERCOW_API_Username`, `SERVERCOW_API_Password` | [Servercow API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_servercow) | |
| 131 | +| **CloudFlare** | `dns_cf` | `CF_Token`, `CF_Account_ID` | [CloudFlare DNS API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf) | |
| 132 | +| **AWS Route53** | `dns_aws` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` | [Route53 API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws) | |
| 133 | +| **Azure DNS** | `dns_azure` | `AZUREDNS_SUBSCRIPTIONID`, `AZUREDNS_TENANTID`, `AZUREDNS_APPID`, `AZUREDNS_CLIENTSECRET` | [Azure API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_azure) | |
| 134 | +| **Google Cloud DNS** | `dns_gcloud` | `CLOUDSDK_ACTIVE_CONFIG_NAME` | [GCloud API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcloud) | |
| 135 | +| **DigitalOcean** | `dns_dgon` | `DO_API_KEY` | [DigitalOcean API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dgon) | |
| 136 | + |
| 137 | +### Tier 2: Community-getestet |
| 138 | + |
| 139 | +| Provider | Plugin-Name | Hinweise | |
| 140 | +|----------|-------------|----------| |
| 141 | +| **Hetzner** | `dns_hetzner` | Beliebt in Deutschland/Europa | |
| 142 | +| **IONOS** | `dns_ionos` | Deutscher Provider (früher 1&1) | |
| 143 | +| **Strato** | `dns_strato` | Deutscher Hosting-Provider | |
| 144 | +| **OVH** | `dns_ovh` | Europäischer Provider | |
| 145 | +| **Namecheap** | `dns_namecheap` | Benötigt DDNS-Passwort, nicht Standard-API | |
| 146 | +| **GoDaddy** | `dns_gd` | API-Key + API-Secret erforderlich | |
| 147 | +| **Linode** | `dns_linode` | API-Token | |
| 148 | + |
| 149 | +**Vollständige Provider-Liste:** [acme.sh DNS API Dokumentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) (150+ Provider) |
| 150 | + |
| 151 | +!!! tip "Provider nicht aufgeführt?" |
| 152 | + Wenn Ihr Provider DNS-API unterstützt und in der acme.sh-Dokumentation aufgeführt ist, sollte er mit mailcow funktionieren. Prüfen Sie das [acme.sh Wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) für Konfigurationsdetails. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Wildcard-Zertifikate |
| 157 | + |
| 158 | +Die DNS-01-Challenge ist die **einzige Möglichkeit**, Wildcard-Zertifikate von Let's Encrypt zu erhalten. |
| 159 | + |
| 160 | +### Konfigurations-Beispiel |
| 161 | + |
| 162 | +Bearbeiten Sie `mailcow.conf`: |
| 163 | + |
| 164 | +```bash |
| 165 | +MAILCOW_HOSTNAME=mail.example.de |
| 166 | +ADDITIONAL_SAN=*.example.de,example.de |
| 167 | +ACME_DNS_CHALLENGE=y |
| 168 | +ACME_DNS_PROVIDER=dns_servercow |
| 169 | +``` |
| 170 | + |
| 171 | +!!! warning "Wildcard-Einschränkungen" |
| 172 | + - `*.example.de` deckt `mail.example.de`, `webmail.example.de`, `smtp.example.de`, etc. ab |
| 173 | + - `*.example.de` deckt **NICHT** `example.de` (die Apex/Root-Domain) ab |
| 174 | + - Sie müssen beides explizit hinzufügen: `ADDITIONAL_SAN=*.example.de,example.de` |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Konfigurations-Beispiele |
| 179 | + |
| 180 | +### Beispiel 1: Servercow mit Wildcard |
| 181 | + |
| 182 | +**Szenario:** mailcow bei Servercow gehostet, einzelne Domain mit Wildcard-Zertifikat |
| 183 | + |
| 184 | +**mailcow.conf:** |
| 185 | + |
| 186 | +```bash |
| 187 | +MAILCOW_HOSTNAME=mail.example.de |
| 188 | +ADDITIONAL_SAN=*.example.de,example.de |
| 189 | + |
| 190 | +# DNS-01-Challenge-Konfiguration |
| 191 | +ACME_DNS_CHALLENGE=y |
| 192 | +ACME_DNS_PROVIDER=dns_servercow |
| 193 | +ACME_ACCOUNT_EMAIL=admin@example.de |
| 194 | +``` |
| 195 | + |
| 196 | +**data/conf/acme/dns-01.conf:** |
| 197 | + |
| 198 | +```bash |
| 199 | +# Servercow API-Zugangsdaten |
| 200 | +# Abrufen unter: https://cp.servercow.de |
| 201 | +# API > API-Benutzer > Neuen Benutzer erstellen oder existierenden verwenden |
| 202 | +SERVERCOW_API_Username="ihr-servercow-api-benutzername" |
| 203 | +SERVERCOW_API_Password="ihr-servercow-api-passwort" |
| 204 | +``` |
| 205 | + |
| 206 | +**Servercow API-Benutzer erstellen:** |
| 207 | + |
| 208 | +1. Einloggen im [Servercow Control Panel](https://cp.servercow.de) |
| 209 | +2. Navigation zu **API** > **API-Benutzer** |
| 210 | +3. Klick auf **API-Benutzer erstellen** oder existierenden API-Benutzer verwenden |
| 211 | +4. Benutzername und Passwort notieren |
| 212 | +5. Sicherstellen, dass der API-Benutzer DNS-Verwaltungsrechte hat |
| 213 | + |
| 214 | +--- |
| 215 | + |
| 216 | +### Beispiel 2: CloudFlare mit Wildcard |
| 217 | + |
| 218 | +**Szenario:** Kleines Unternehmen, einzelne Domain, Wildcard-Zertifikat für alle Subdomains gewünscht |
| 219 | + |
| 220 | +**mailcow.conf:** |
| 221 | + |
| 222 | +```bash |
| 223 | +MAILCOW_HOSTNAME=mail.example.de |
| 224 | +ADDITIONAL_SAN=*.example.de,example.de |
| 225 | + |
| 226 | +# DNS-01-Challenge-Konfiguration |
| 227 | +ACME_DNS_CHALLENGE=y |
| 228 | +ACME_DNS_PROVIDER=dns_cf |
| 229 | +ACME_ACCOUNT_EMAIL=admin@example.de |
| 230 | +``` |
| 231 | + |
| 232 | +**data/conf/acme/dns-01.conf:** |
| 233 | + |
| 234 | +```bash |
| 235 | +# CloudFlare API-Token (NICHT Global API Key!) |
| 236 | +# Erstellen unter: https://dash.cloudflare.com/profile/api-tokens |
| 237 | +# Berechtigungen: Zone > DNS > Edit für Zone 'example.de' |
| 238 | +CF_Token="ihr_cloudflare_api_token_hier" |
| 239 | +CF_Account_ID="ihre_cloudflare_account_id" |
| 240 | +``` |
| 241 | + |
| 242 | +**CloudFlare API-Token erstellen:** |
| 243 | + |
| 244 | +1. Gehen Sie zum [CloudFlare Dashboard](https://dash.cloudflare.com/profile/api-tokens) |
| 245 | +2. Klicken Sie auf "Token erstellen" |
| 246 | +3. Verwenden Sie die Vorlage "Zone-DNS bearbeiten" oder erstellen Sie einen benutzerdefinierten Token mit: |
| 247 | + - Berechtigungen: `Zone > DNS > Bearbeiten` |
| 248 | + - Zonenressourcen: `Einschließen > Bestimmte Zone > example.de` |
| 249 | +4. Kopieren Sie den Token (wird nur einmal angezeigt!) |
| 250 | + |
| 251 | +--- |
| 252 | + |
| 253 | +### Beispiel 3: Hetzner (Deutschland) |
| 254 | + |
| 255 | +**Szenario:** Deutscher Hosting-Provider, beliebt in Europa |
| 256 | + |
| 257 | +**mailcow.conf:** |
| 258 | + |
| 259 | +```bash |
| 260 | +MAILCOW_HOSTNAME=mail.example.de |
| 261 | +ADDITIONAL_SAN=*.example.de |
| 262 | + |
| 263 | +ACME_DNS_CHALLENGE=y |
| 264 | +ACME_DNS_PROVIDER=dns_hetzner |
| 265 | +ACME_ACCOUNT_EMAIL=admin@example.de |
| 266 | +``` |
| 267 | + |
| 268 | +**data/conf/acme/dns-01.conf:** |
| 269 | + |
| 270 | +```bash |
| 271 | +# Hetzner DNS API-Token |
| 272 | +# Erstellen unter: https://dns.hetzner.com/settings/api-token |
| 273 | +HETZNER_Token="ihr-hetzner-api-token-hier" |
| 274 | +``` |
| 275 | + |
| 276 | +--- |
| 277 | + |
| 278 | +### Beispiel 4: IONOS (Deutschland) |
| 279 | + |
| 280 | +**Szenario:** IONOS (früher 1&1), deutscher Provider |
| 281 | + |
| 282 | +**mailcow.conf:** |
| 283 | + |
| 284 | +```bash |
| 285 | +MAILCOW_HOSTNAME=mail.example.de |
| 286 | +ADDITIONAL_SAN=*.example.de |
| 287 | + |
| 288 | +ACME_DNS_CHALLENGE=y |
| 289 | +ACME_DNS_PROVIDER=dns_ionos |
| 290 | +ACME_ACCOUNT_EMAIL=admin@example.de |
| 291 | +``` |
| 292 | + |
| 293 | +**data/conf/acme/dns-01.conf:** |
| 294 | + |
| 295 | +```bash |
| 296 | +# IONOS API-Key |
| 297 | +# Abrufen im IONOS-Kundenbereich unter Developer Tools |
| 298 | +IONOS_API_KEY="ihr-ionos-api-key" |
| 299 | +``` |
| 300 | + |
| 301 | +--- |
| 302 | + |
| 303 | +### Beispiel 5: AWS Route53 (Multi-Domain) |
| 304 | + |
| 305 | +**Szenario:** Mehrere Domains auf AWS gehostet, Unternehmenssetup |
| 306 | + |
| 307 | +**mailcow.conf:** |
| 308 | + |
| 309 | +```bash |
| 310 | +MAILCOW_HOSTNAME=mail.firma.de |
| 311 | +ADDITIONAL_SAN=smtp.firma.de,mail.abteilung.de |
| 312 | + |
| 313 | +ACME_DNS_CHALLENGE=y |
| 314 | +ACME_DNS_PROVIDER=dns_aws |
| 315 | +ACME_ACCOUNT_EMAIL=admin@firma.de |
| 316 | +``` |
| 317 | + |
| 318 | +**data/conf/acme/dns-01.conf:** |
| 319 | + |
| 320 | +```bash |
| 321 | +# AWS IAM User Zugangsdaten |
| 322 | +# IAM User: mailcow-acme-dns |
| 323 | +# Policy: Angehängte benutzerdefinierte Richtlinie (siehe unten) |
| 324 | +AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE" |
| 325 | +AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" |
| 326 | +``` |
| 327 | + |
| 328 | +**Empfohlene IAM-Richtlinie (minimale Rechte):** |
| 329 | + |
| 330 | +```json |
| 331 | +{ |
| 332 | + "Version": "2012-10-17", |
| 333 | + "Statement": [ |
| 334 | + { |
| 335 | + "Effect": "Allow", |
| 336 | + "Action": [ |
| 337 | + "route53:GetChange", |
| 338 | + "route53:ListHostedZones" |
| 339 | + ], |
| 340 | + "Resource": "*" |
| 341 | + }, |
| 342 | + { |
| 343 | + "Effect": "Allow", |
| 344 | + "Action": [ |
| 345 | + "route53:ChangeResourceRecordSets" |
| 346 | + ], |
| 347 | + "Resource": "arn:aws:route53:::hostedzone/Z1234567890ABC" |
| 348 | + } |
| 349 | + ] |
| 350 | +} |
| 351 | +``` |
| 352 | + |
| 353 | +Ersetzen Sie `Z1234567890ABC` durch Ihre tatsächliche Hosted-Zone-ID. |
| 354 | + |
| 355 | +--- |
| 356 | + |
| 357 | +## Zusätzliche Ressourcen |
| 358 | + |
| 359 | +- [acme.sh DNS API Dokumentation](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) - Vollständige Liste von 150+ unterstützten DNS-Providern mit Konfigurationsbeispielen |
| 360 | +- [Let's Encrypt Challenge-Typen](https://letsencrypt.org/de/docs/challenge-types/) - Offizielle Dokumentation zu HTTP-01 vs DNS-01 |
| 361 | +- [Let's Encrypt Rate Limits](https://letsencrypt.org/de/docs/rate-limits/) - Limits für Zertifikatsausstellung |
| 362 | +- [mailcow SSL Dokumentation (HTTP-01)](firststeps-ssl.md) - Standard HTTP-basierte Zertifikatsausstellung |
| 363 | +- [mailcow Reverse Proxy Setup](reverse-proxy/r_p.md) - mailcow hinter Reverse Proxies verwenden |
| 364 | +- [mailcow DNS Voraussetzungen](../getstarted/prerequisite-dns.md) - Für Mail-Betrieb erforderliche DNS-Records |
0 commit comments