Ausgangssituation

Mailcow und Traefik sind, wie in der hervorragenden Anleitung von goneuland.de für mailcow beschrieben, installiert. Das einzige Manko an dieser Anleitung ist, dass man nach dem Hinzufügen einer Email Domäne noch in der docker-compose.override.yml Datei manuelle Anpassungen vornehmen muss und mailcow über docker-compose danach neu deployen muss. Die Abhilfe ist, dass ein extra Container die Traefik Konfiguration aus der Mailcow Datenbank generiert und als Http Provider zur Verfügung stellt.

Http Provider

Die dynamische Traefik Konfiguration wird von einer kleinen Flask Webapp generiert. Der Code ist hier zu finden: https://github.com/olqs/mailcow-traefik-cert-helper

Docker Compose und neuer Container

In der Datei „docker-compose.override.yml“ muss man zwei Sachen verändern.

Zuerst alle Einträge die die SSL Terminierung konfigurieren auskommentieren, oder löschen. Der Traefik Router der das erledigt heisst nginx-mailcow-secure.

services:
  nginx-mailcow:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx-mailcow.entrypoints=http"
      - "traefik.http.routers.nginx-mailcow.rule=HostRegexp(`{host:(autodiscover|autoconfig|webmail|mail|email).+}`)"
      - "traefik.http.middlewares.nginx-mailcow-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.nginx-mailcow.middlewares=nginx-mailcow-https-redirect"
#      - "traefik.http.routers.nginx-mailcow-secure.entrypoints=https"
#      - "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.worli.info`)" ###### hier eure FQDN angeben #####
#      - "traefik.http.routers.nginx-mailcow-secure.tls=true"
#      - "traefik.http.routers.nginx-mailcow-secure.tls.domains[0].main=mail.worli.info" ###### anpassen zu euer FQDN von oben #####
#      - "traefik.http.routers.nginx-mailcow-secure.tls.domains[0].sans=imap.worli.info, smtp.worli.info, pop3.worli.info" ## Domain anpassen ##
#      - "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow"
#      - "traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http"
      - "traefik.http.services.nginx-mailcow.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
    networks:
      proxy:

Den Container der die Konfiguration zur Verfügung stellt hinzufügen, das Datenbank Passwort wird mit der Konfiguration aus der mailcow.conf übernommen:

  mailcow-traefik-cert-helper:
    image: olqs/mailcow-traefik-cert-helper
    container_name: mailcowdockerized_mailcow-traefik-cert-helper
    restart: unless-stopped
    networks:
      proxy:
        aliases:
          - mailcow-traefik-cert-helper
      mailcow-network:
        aliases:
          - mailcow-traefik-cert-helper
    environment:
      - MYSQL_DATABASE_PASSWORD=${DBPASS}

Statische Traefik Konfiguration anpassen

Den Konfigurationspunkt „providers“ um den Http Provider erweitern.

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: "./dynamic_conf.yml"
    watch: true
  http:
    endpoint: http://mailcowdockerized_mailcow-traefik-cert-helper:5000/

Certdumper Container

Der in der Anleitung genutzte certdumper Container hat nur die Möglichkeit alle im Traefik hinterlegten Zertifikate oder eine manuell gepflegte Liste an Zertifikaten aus der acme.json zu extrahieren. Zusätzlich muss für Mailcow in den Zertifikatsordnern die generiert werden eine Datei „domains“ liegen, die eine Leerzeichen separierte Liste aller Domänen enthält für die das Zertifikat gültig ist.

Das Container Image wurde von mir so angepasst, das die „domains“ Datei erstellt wird und man jetzt über eine Umgebungsvariable festlegen kann, das nur Domänen die mit einem definierten Text starten exportiert werden. Für die Code Änderungen habe ich einen Pull Request erstellt, aber zum Zeitpunkt der Artikelerstellung wurde der noch nicht akzeptiert. Mein angepasster Quellcode ist hier zu finden: https://github.com/olqs/traefik-certs-dumper

  certdumper:
    image: olqs/traefik-certs-dumper
    container_name: mailcowdockerized_traefik_certdumper
    restart: unless-stopped
    network_mode: none
    command: --restart-containers mailcowdockerized_postfix-mailcow_1,mailcowdockerized_dovecot-mailcow_1
    volumes:
      # mount the folder which contains Traefik's `acme.json' file
      #   in this case Traefik is started from its own docker-compose in ../traefik
      - /data/traefik:/traefik:ro
      # mount mailcow's SSL folder
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/assets/ssl:/output:rw
    environment:
      # only change this, if you're using another domain for mailcow's web frontend compared to the standard config
      - DOMAIN_STARTS_WITH=mail

Im „certdumper“ Abschnitt der „docker-compose.override.yml“ die Punkte „image“ und „environment“ anpassen.

Mailcow und Traefik neu starten/deployen

Zum Schluss müssen jetzt noch Traefik neu gestartet werden und Mailcow neu deployed werden. Die Befehle müssen an die Umgebung angepasst sein und sind nur beispielhaft.

user@host:~ $ sudo -i
host:/mailcow # docker-compose down && docker-compose up -d
host:/mailcow # docker stop traefik && docker start traefik

2 thoughts on “Mailcow – Traefik, automatisch Zertifikate für Email Domänen generieren

  1. Hallo,
    ich habe nach der Anleitung von goneuland.de für mailcow gearbeitet und versucht diese Erweiterung zu testen.
    Leider ohne positives Ergebnis.
    Es wird nur das Zertifikat für traefik selber geholt und nach mailcow /data/assets/ssl/domainname kopiert.
    Mir ist nicht klar, wo ich die zusätzlichen Domainen eintragen soll.
    Hintergrund: ich möchte mehrere Domainen mit mailcow nutzen.
    Allerdings akzeptiert der Outlook.Client keine einzelnes Zertifikat mit allen Domains, sondern für jede Domain ein Einzelnes.
    Ich hoffte mit dieser Erweiterung das Problem zu lösen, oder liege ich da ganz falsch?

    Gruß
    Rolf

    1. Hallo Rolf,
      deinen Kommentar habe ich irgendwie übersehen.
      Du solltest hier nichts zusätzlich eintragen müssen. Im /data/assets/ssl/domainname sollte nicht nur eine Zertifikatsdatei liegen, sondern auch eine Textdatei domains für welche (Sub-)Domains die Zertifikate gültig sind.
      Über diese Datei baut der postfix und dovecot container seine SNI Konfiguration zusammen. Wir können uns das gerne auch mal zusammen ansehen.
      Die traefik Konfiguration wird aus der mailcow Datenbank generiert und als http endpunkt zur Verfügung gestellt, so sollte traefik für die Domains in deiner Mailcow Konfiguration die passenden letsencrypt Zertifikate ausstellen.

      Vg
      Alex

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.