Mailcow aufsetzen

  • Hallo,

    ich habe drei Domains und möchte mir für E-Mail Konten Mailcow auf meinem vServer installieren. Hierzu möchte ich den dockerisierten Ansatz wählen.

    Muss ich nun für jeder Domain eine eigene Mailcow-Instanz spendieren, oder kann Mailcow mehrere Domains verwalten?

  • Du Setzt den Server mit einer technischen Domain oder Subdomain auf. Diese wird dann für alle aufgeschalteten Domains als Eingangs und Ausgangsserver, sowie für das Webmail verwendet. Dann kannst du beliebig viele Domains aufschalten.

    Einmal editiert, zuletzt von fisi (24. Januar 2025 um 22:14)

  • Ok, ich habe nun nach dieser Anleitung einen Mailcow aufgesetzt: https://community.netcup.com/de/tutorials/m…lcow-einrichten was auch erstmal prima funktioniert hat. Aktuell habe ich in meiner Domain einen "mail" A-Record auf die IP meines vServers hinterlegt. Das erschien mir sinnvoller als einen CNAME darauf. Die restlichen Einstellungen (Records) im DNS habe ich soweit auch hinbekommen. mail-tester-com ist fast zufrieden damit...

    Eine Besonderheit habe ich jedoch bei mir. Ich möchte div. Dienste auf meinem vServer betreiben und nicht nur einen. Daher klappt es nicht das jeder Dienst um Port 80 und oder 443 buhlt. Ich habe also einen eigenen Docker (vielleicht wäre das sogar besser direkt auf dem Host aufgehoben...? hm) mit Nginx der auf Port 80 und 443 hört. Dieser hat div. server-Blöcke und leitet die Anfragen gemäß dem aufgerufenen Hostnamen an andere Docker-Container weiter. Diese befinden sich im gleichen Docker-Netzwerk wodurch sie der Nginx (Ingres-Controller) durch Angabe ihres Containernamens und dem Port erreichen kann. Die SSL-Terminierung übernimmt ebenfalls dieser Nginx. Die Zertifikate erstelle ich mit dem acme.sh auf dem Host und mappe diese in den Nginx Controller.

    Nun bringt Mailcow ja seinen eigenen acme-Container mit, welcher aber so keinen Sinn für mich macht, denn er würde ja dasselbe tun wie mein Nginx. Derzeit ignoriere ich das einfach, aber bin der Meinung das ich diesen Container aus dem Verbund auslösen könnte.

    Eine weitere Aufgabe ist noch die alten Mails zu migrieren (IMAP -> IMAP). Derzeit teste ich mit einer noch nicht benutzten Domain. Sobald ich aber in Mailcow mein echtes Mailkonto anlegen will, muss ich es ja beim alten Provider wegnehmen, zwei verschiedene MX sind sicher ungesund ;) Dann kann ich aber ja nicht mehr migrieren, außer ich finde einen Weg das über eine offline-Backup-Kopie zu machen?

    Vielleicht sowas hier? https://github.com/imapsync/imapsync oder gleich das hiesige Tool nehmen? https://mailsync.netcup.net/

    2 Mal editiert, zuletzt von go4it (25. Januar 2025 um 11:03)

  • Wunderbar! Wie gehe ich nun am geschicktesten vor für den Umzug? Ich kann ja in Mailcow meine Domain, welche noch bei 1und1 liegt, anlegen und auch ein Mailkonto dazu, jedoch wird da ja noch nicht funktionieren da die ganzen DNS-Einträge noch auf den 1und1 Server lauten. Also wird vermutlich der Sync alt -> neu nicht klappen.

    P.S.: Scheinbar hab ich mich geirrt, man kann genau so migrieren. Also einfach eine Domain in Mailcow anlegen, dann ein Konto darauf anlegen und mit dem Mailsync die Daten vom alten ins neue übertragen!

    Einmal editiert, zuletzt von go4it (25. Januar 2025 um 12:08)

  • Du kannst die Domain doch bereits in deiner Mailcow anlegen (ohne DNS) und die Mailboxen anlegen.

    Da dein bisheriger Anbieter einen IMAP Server hat der unter imap.1und1.de lauscht sollte einem Sync steht erstmal nichts im Weg stehen.

    Nach erfolgreichem Sync kannst du dann MX etc. umstellen

  • Du kannst die Domain doch bereits in deiner Mailcow anlegen (ohne DNS) und die Mailboxen anlegen.

    Da dein bisheriger Anbieter einen IMAP Server hat der unter imap.1und1.de lauscht sollte einem Sync steht erstmal nichts im Weg stehen.

    Nach erfolgreichem Sync kannst du dann MX etc. umstellen

    Genau so mache ich es jetzt auch, hatte meinen Denkfehler oben schon selbst erkannt und es einfach ausprobiert, hat geklappt :) Jetzt lasse ich mal syncen und dann stelle ich den MX um.

  • Wenn ich nun versuche eines der neuen Konten auf einer bereits MX-Mäßig umgestellten Domain auf meinem Handy einzurichten erhalte ich einen Zertifikatsfehler (wird nicht vertraut). Ich habe ein SSL-Zertifikat für den Hostname von Mailcow (mailcow.conf) in meinem eigenen Reverse-Proxy hinterlegt. Aber nur für Port 443, welcher der Nginx dann auf 8080 vom Mailcow leitet. Nicht aber für 993 (IMAPS), dieser geht von meinem Host direkt in den Mailcow-Container (Docker Port mapping). Müsste ich nun den 993er dann auf meinen Nginx leiten und von dort auf 143 (IMAP) vom Mailcow gehen?

    Oder sollte ich das ganze Zertifikatsgedönse doch besser von Mailcow selbst regeln lassen und den Nginx für die Mail-Server URL auf Durchzug stellen? Also Port 80, 443, 993 und 587 ohne Änderung zum Docker-Container von Mailcow schieben?

  • Was ist denn die Ursache für den Zertifikatsfehler? Stimmt der Hostname nicht überein?

    Und für welchen Service UI, IMAP, SMTP?

    Reverse Proxy für http/https und dein IMAP, SMTP Server sind unterschiedliche Welten.

    Die IMAP Verbindung wirst du nicht durch den Reverse Proxy jagen.

    Ist das Zertifikat auch in der Mailcow hinterlegt?

  • Ich habe jetzt wie angegeben in der mailcow.conf den Bind auf localhost/127.0.0.1 vorgenommen:

    Code
    HTTP_BIND=127.0.0.1
    HTTP_PORT=8080
    HTTPS_BIND=127.0.0.1
    HTTPS_PORT=8443

    Das docker-compose.yml erzeugt ein eigenes Netzwerk für die Container der Mailcow

    Code
    docker network inspect mailcowdockerized_mailcow-network
    ...
       "Subnet": "172.22.1.0/24"
       "Subnet": "fd4d:6169:6c63:6f77::/64"

    Mailcow baut aufgrund der Port-Einstellungen im docker-compose.yml über folgende Container einen direkten Kontakt zum Host-Netzwerk auf:

    • "mailcowdockerized-nginx-mailcow-1" (Reverse-Proxy von Mailcow)
      • 127.0.0.1:8080 => hier sollen die externen HTTP-Verbindungen für die Zertifikatsausstellung/Erneuerung ankommen
      • 127.0.0.1:8443 => hier sollen die externen HTTPS-Verbindungen für die Mailcow-Admin-UI und SOGo Webmailer ankommen
    • "mailcowdockerized-dovecot-mailcow-1" (IMAP-Server)
      • 0.0.0.0:110 => POP3 (will ich eigentlich nicht nutzen!)
      • 0.0.0.0:143 => Eingangsport für IMAP (will ich nicht nutzen, nur IMAPS)
      • 0.0.0.0:993 => Eingangsport für IMAPS
      • 0.0.0.0:995 => POP3 SSL (will ich eigentlich nicht nutzen!)
      • 0.0.0.0:4190 => Sieve-Script Management Port (hm, ich wüsste jetzt nicht wozu ich Sieve einsetzen würde oder sollte?)
      • 127.0.0.1:19991->12345/tcp ??? was ist das ???
    • "mailcowdockerized-postfix-mailcow-1" (Mail-Transport)
      • 0.0.0.0:25 => SMTP (will ich nicht nutzen, nur SMTPS)
      • 0.0.0.0:465 => Alte SMTPS Implementation (will ich nicht nutzen, nur SMTPS)
      • 0.0.0.0:587 => SMTPS

    Laut Doku soll man beim Betrieb eines Nginx-Reverse-Proxy VOR der ganzen Mailcow-Wolke folgendes einstellen:

    (!) In der aktuellen Version von Nginx muss das "http2" in einer eigenen Zeile aktiviert werden, das habe ich hier schon angepasst.

    Der externe Reverse-Proxy benötigt also für die HTTPS Validierung der eingehenden Verbindung das Zertifikat welches im Mailcow liegt. Mailcow-Nginx legt das im Unterverzeichnis data/assets/ssl ab, in dem auch das docker-compose.yml liegt. Das habe ich dann als Volume in meinen externen Nginx gemapped:

    Somit verwende ich wirklich dieselbe(n) Zertifikatsdatei(en) auf meinem Nginx und dem von Mailcow.

    Soweit so gut, aber einiges verstehe ich an diesem Setup noch nicht:

    1.) Der HTTP Listener auf dem Reverse-Proxy hat jetzt nur die Aufgabe Anfragen auf HTTPS umzuleiten. Ich hatte es so verstanden das der Port 80 für Let's Encrypt genutzt wird um die HTTP-Challenge durchzuführen. Eingehende Verbindungen würden also auf HTTPS umgeleitet (macht LE das mit?), dann im Reverse-Proxy SSL-Terminiert und an den HTTP-Port von Mailcow (8080) geleitet.

    2.) Jetzt warte ich darauf das mit der acme-Container von Mailcow ein Zertifikat für meine dort hinterlegten Domains ausstellt. Was ich noch nicht durchblicke ist, wie bei einer Zertifikatserneuerung der ACME-Container meinem Reverse-Proxy Container mitteilen will das er die Zertifikatsdatei neu einlesen soll?

    Davon ab klappt der Zertifikatsabruf vom ACME-Container nicht:

    Code
    Sun Jan 26 13:59:35 CET 2025 - Initializing, please wait...
    Sun Jan 26 13:59:35 CET 2025 - Using existing domain rsa key /var/lib/acme/acme/key.pem
    Sun Jan 26 13:59:35 CET 2025 - Using existing Lets Encrypt account key /var/lib/acme/acme/account.pem
    Sun Jan 26 13:59:35 CET 2025 - Detecting IP addresses...
    Sun Jan 26 13:59:35 CET 2025 - OK: 1xx.xx.xxx.xxx, 2a0a:xxx:xx:35e5:5400:6dff:xxx:xxx
    Sun Jan 26 13:59:35 CET 2025 - Found AAAA record for autodiscover.domain.de: 2a0a:xxx:xx:35e5:5400:6dff:xxx:xxx - skipping A record check
    Sun Jan 26 13:59:36 CET 2025 - Cannot validate any hostnames, skipping Let's Encrypt for 1 hour.
    Sun Jan 26 13:59:36 CET 2025 - Use SKIP_LETS_ENCRYPT=y in mailcow.conf to skip it permanently.

    Dann habe ich probehalber mal "SKIP_HTTP_VALIDATION=y" eingestellt

    Das kann meines Erachtens auch nicht funktionieren, denn localhost oder 127.0.0.1 innerhalb eines Containers entspricht dem Container und nicht dem Host. Wie soll mein Nginx also auf den auf dem Host hörenden Docker-Container von mailcow zugreifen? Ggf. könnte das funktionieren wenn man das Netzwerk vom Reverse-Proxy in den Host-Mode stellt, anstelle dem Bridge-Mode. Oder man nimmt als Ziel nicht 127.0.0.1 sondern die IP-Adresse des Docker-Hosts.

    6 Mal editiert, zuletzt von go4it (26. Januar 2025 um 14:33)

  • UFF! Das war ne harte Nuss, aber so ganz zufrieden bin ich noch nicht...

    Innerhalb eines Containers auf den Host zuzugreifen ist normalerweise nicht üblich. Normalerweise würde man versuchen die Container/Container Kommunikation innerhalb der Docker-Wolke zu halten, oder man greift von einem Container auf die offizielle Host-URL zu.

    Ähnliches erreicht man wenn man den Network-Mode des Containers auf "host" stellt (default ist "bridge"). Dann nutzt Docker nicht mehr sein internes Netzwerk, sondern direkt das vom Host. Das hat aber wieder andere Nachteile...

    Das Docker-Netzwerk "bridge" stellt unter der IP 172.17.0.1 das lokale Hostnetzwerk dar, hierüber kann man aus dem Dockernetzwerk heraus auf das Hostnetzwerk zugreifen. So habe ich den BIND erstmal wieder geöffnet:

    Code
    HTTP_PORT=8080
    HTTP_BIND=
    
    HTTPS_PORT=8443
    HTTPS_BIND=

    Dann habe ich in meinem Reverse-Proxy die Pass-Regel auf die IP 172.17.0.1 gesetzt, damit ich aus dem Reverse-Proxy raus auf den Host komme. Gleichzeitig habe ich die Regel für HTTP so erweitert, das ein acme-challenge direkt auf den Port 8080 geht und nicht erst über HTTPS redirected wird:

    Nun landet der Request von außen wirklich direkt auf dem mailcow-nginx und kann von dort aus auf dem mailcow-acme Container weitergereicht werden.

    Der trickreiche Part war der der UFW Firewall. Man muss die Verbindung die vom Reverse-Proxy aus dem Container-Netzwerk kommt (bei mir ist das die Subnetz-Adresse 172.18.0.0/24) in Richtung Host-IP erlauben, sonst werden diese Pakete geblockt:

    Code
    ufw allow from 172.18.0.0/24 to 172.17.0.1 port 8080
    ufw allow from 172.18.0.0/24 to <YOUR IP> port 8080

    Jetzt hat dann auch der ACME Container ein Zertifikat bauen und hinterlegen können. Leider ist es so wie schon gedacht, das Mailcow natürlich nichts von meinem Reverse-Proxy weiß und ich daher noch einen Weg suchen muss wie der Mailcow-ACME meinen Reverse-Proxy nach einer Zertifikatserneuerung zum Reload zwingt.

    Jedenfalls emittiert Mailcow jetzt auch für die IMAPS und SMTPS Protokolle ein Zertifikat und ich kann ohne Fehler mit einem Mailclient von meinem Handy zugreifen.

  • Wenn ich nun eine Maildomain samt DNS für Mailcow eingerichtet habe und weitere Domains dazu nehme, müssen diese außer einem MX-Record auch die ganze Litanei von TXT Records besitzen? Und muss der MX einer Domain auf einen CNAME der Domain zeigen oder kann es auch ein anderer sein?

    Sprich, ist sowas zulässig ohne als Spammer oder was gelistet zu werden?

    Domain A

    @ MX mail.domain.a

    Domain B

    @ MX mail.domain.a

  • müssen diese außer einem MX-Record auch die ganze Litanei von TXT Records besitzen?

    ja.

    Und muss der MX einer Domain auf einen CNAME der Domain zeigen oder kann es auch ein anderer sein?

    der MX muss einfach auf einen hostnamen zeigen.

    das kann auch ein beliebiger anderer mailserver sein, der sich für die domain zuständig fühlt.

    »Hauptsache BogoMIPS!«
    Volksfront DLT #64Ksplit
    Sag' NEIN zu Wordpress

    Einmal editiert, zuletzt von Olivetti (30. Januar 2025 um 09:22)

  • Wenn ich nun eine Maildomain samt DNS für Mailcow eingerichtet habe und weitere Domains dazu nehme, müssen diese außer einem MX-Record auch die ganze Litanei von TXT Records besitzen? Und muss der MX einer Domain auf einen CNAME der Domain zeigen oder kann es auch ein anderer sein?

    Ich kann Dir nur ans Herz legen, les die Mailcow Dokumentation da steht alles drin und ansonten bist Du wegen Mailcow hier gut aufgehoben: https://community.mailcow.email/

    Weiterhin möchte ich Dir nicht zu nahe treten aber bist Du Dir sicher das Du einen Mailserver, der im Internet verfügbar ist, administrieren kannst?

  • MTA-STS richte ich mir für die Maildomains ein, wo ich es gern drin hätte. Derzeit mache ich das auch nur aus Perfektionismus, um bei MECSA 5 Sterne zu bekommen ^^ . Also nicht, weil irgendeiner meiner Empfänger das zwingend verlangen würde. Jedenfalls nicht Google, Microsoft, GMX oder Web.de. Die sind alle mit STARTTLS, Zertifikat, SPF, DKIM und DMARC zufrieden, bis vor kurzem sogar ohne DKIM und DMARC. Ist mir jedenfalls nichts gegenteiliges aufgefallen. MTA-STS + DNSSEC kann man als halbwegs passablen Ersatz für DANE (+DNSSEC) betrachten. DANE ist mir zuviel Aufwand, MTA-STS ist einfacher einzurichten und deutlich pflegeleichter. Ich benutze aber auch keine Mailcow.