Privater Mailserver
Man muss ja irgendwo seine e-Mails archivieren. Ich finde es nicht gut diese bei GMX, Web oder gar Google zu lassen. Auch Apple oder Google cloud Archive sind nicht so mein Ding.
Deshalb habe ich schon seit Jahrzehnten einen Mailservice aufgebaut. In der Vergangenheit habe ich meine Mails mit der Benutzung eine Cyrus Imap-Server zuhause auf entsprechender Hardware gespeichert. Jede Nacht wurde per POP3 Protokoll die Mail auf mein NAS herunter geladen. Erst war es ein NAS, dann reichte ein Raspbery Pi mit USB-Disk. Ein Spiegelung auf ein anderes NAS ergab dann die Backup Lösung.
Alte Cyrus IMAP Lösung
In dieser alten Lösung fehlte aber ein guter SPAM Filter oder gar eine Sortierung in entsprechende Verzeichnisse. Klar kann man das mit Postfix oder Cyrus IMAP implementieren, aber mit entsprechenden Aufwand direkt an der Basis Konfiguration.
Die entsprechende Konfiguration muss am System in der Hauptkonfiguration als User root gemacht werden. Es gab kein Weg zurück, oder man musste in altbewährter Weise alte Konfigurationen vorher sichern, bevor man Änderungen tut.
Auch wurde der Aufwand immer größer, so eine Umgebung zu warten. Update Pfade von alten Cyrus IMAP zu neuen oder System-Austausch waren aufwendig. Ähnliches galt bei Postfix. Auch die Wartung der Mail von vier Hausbewohnern mit entsprechender Nutzerverwaltung im Unix System ergab doch ab und an Probleme. User können entsprechend abgesichert werden, doch sie exsistieren dann auf dem installierten Linux Basis-System.
Neue Docker-basierende Mailserver
Im Allgemeinen reicht aber ein kleiner Server mit entsprechender Festplatte aus. Ein Docker-basierende Lösung in der ich gerne mal das gesamte Archiv per rsync
auf einen anderen Platz schieben kann und somit Backup oder System-Austausch schnell zustande bekomme. Dies alles bietet die neue Lösung bzw. der Austausch für meine alte Cyrus IMAP-basierte nativ installierte Lösung.
Ich nutze nun folgende Mailserver-Konfiguration:
https://github.com/docker-mailserver/docker-mailserver
Diese Lösung läuft in einem Docker Container und beinhaltet IMAP server, SPAM filter oder die Filterung mittels dem Sieve-Tools.
Da ich schon im Cyrus IMAP das Maildir
Ablageformat für Mails genutzt habe, musste ich nur diese Dateien mit rsync
in das mailserver
Data Verzeichnis synchronisieren. Die Konfiguration ist ziemlich einfach.
Beispiel um zu starten ist:
DMS_GITHUB_URL="https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master"
wget "${DMS_GITHUB_URL}/compose.yaml"
wget "${DMS_GITHUB_URL}/mailserver.env"
Folgende Docker-composer Konfiguration habe ich genutzt:
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:15.0.2
container_name: mailserver
# Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
hostname: <mail host alias>
env_file: mailserver.env
# More information about the mail-server ports:
# https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead)
- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
environment:
- ENABLE_FETCHMAIL=1
- FETCHMAIL_POLL=60
volumes:
- ./docker-data/dms/mail-data/:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
restart: always
stop_grace_period: 1m
# Uncomment if using `ENABLE_FAIL2BAN=1`:
cap_add:
- NET_ADMIN
healthcheck:
test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
timeout: 3s
retries: 0
Der mailserver
lässt sich dann einfach mit dem folgenden Kommando starten
docker-compose up -d
Der mailserver
lässt sich dann einfach mit dem folgenden Kommando stoppen
docker-compose down
docker-compose Kommandos
Kommando | Aktion |
---|---|
docker-compose pull | Alle Docker images werden aus dem Internet geladen (pull) |
docker-compose up -d | Starten der Docker container im Hintergrund, shell kommt zurück |
docker-compose up | Starten der Docker container im Vordergrund, shell kommt nicht zurück |
docker-compose down | Stoppen und Aufräumen der Docker container |
docker-compose logs | Listed alle Log-Daten des Docker containers. Man sieht alle erzeugten Ausgaben. Mit -f Option wird fortlaufend der Log angezeigt. |
Anlegen von Usern
Die Lösung von mailserver
gibt die Möglichkeit, Benutzer innerhalb der Docker Instanz anzulegen. Nachdem der Docker container oder Podman pod gestartet ist, kann man direkt mit Docker auf die setup
Skript für die Konfiguration zugreifen.
So kann man per docker
oder podman
Kommando dann den Setup vom mailserver
aufrufen. Hierbei sieht man alle möglichen Optionen die diese setup
Skript zur Verfügung stellt.
docker exec mailserver setup
Mit einen einfachen Kommando wird der Benutzer dann hinzugefügt.
docker exec mailserver setup add test@example.com
Entsprechende Benutzer muss man dann im fetchmail
oder getmail
den Benutzernamen dann als Ziel konfigurieren.
Mails laden
Meine ursprüngliche Lösung war es jede Nacht zwischen 2 und 3 Uhr alle Mails herunter zu laden. Auf dem Server des Anbieters werden sie dabei gelöscht. Es wurden alle Mails die im Laufe des Tages noch nicht gelöscht wurden, und auf dem IMAP server des Anbieters noch lagen, per fetchmail
auf dem lokalen eMail-Server herunter geladen.
Entsprechend wurde um 5 Uhr die Synchronisierung auf ein anderes NAS im Haus erzeugt. Gerade Mails von Firmen oder Behörden sind da wichtig zu archivieren. Ab und an braucht man doch eine Möglichkeit diese Mails performant Wiederzufinden. Das hatte bis jetzt Cyrus IMAP gut gemacht.
Der fetchmail
wurde in der Nacht von allen eingetragenen IMAP Anbieter und allen Nutzern der alten Lösung durchgeführt. Per normalen Mail-Reader kann dieser lokale IMAP-Server dann normal gelesen werden. In manchen Lösungen musste man die Ausgangs-Server auf port 25 disablen, aber es hat bei allen Profis als auch Leien gut funktioniert.
In der neuen Architektur gab es die gleich Funktionalität. Hier wurde dann ähnlich wie vorher allen Nutzern, alle IMAP Services eingetragen. Leider hat die neue Lösung, ohne eine eigene Lösung zu indoktrinieren zu müssen, nur einen Intervall für das Laden der Mails per fetchmail
vorgesehen. So wurde z.B. alle Stunde die Mails vom Server geladen, aber nicht auf dem Server gelöscht. Auf dem Server werden hierbei die Mails als "gelesen" markiert. Man verliert hiermit die Übersicht welche Mail gelesen wurde oder nicht. Auch bestimmte der Startzeitpunkt den Anfang und das Ende des Intervalls. Man hätte den cron entsprechend konfigurieren können, doch wäre das nicht so schön gewesen.
Der mailserver
integriert aber noch ein zweites Tool um Mails zu laden. Der Vorteil der getmail
Lösung ist, dass die Mail zwar stündlich geladen wird, jedoch nicht mehr das "gelesen" Flag markiert wird. Somit werden alle ungelesenen Mails beim Anbieter noch sichtbar und nicht übersehen.
Fetchmail
In <mail-data>/dms/config/fetchmail
kann man alle IMAP email Addressen eintragen. fetchmail
wird dann mit der environment Variable
ENABLE_FETCHMAIL=1
FETCHMAIL_POLL=60
aktiviert. Alle 60 Sekunden wird hierbei fetchmail
gestartet um Mails zu laden.
In der <mail-data>/dms/config/fetchmail
Datei kann dann normal wie fetchmail
normal benutzt die entsprechende Konfiguration eingetragen werden:
poll pop.gmx.net with proto POP3 uidl
user 'user@gmx.xxx' there with password 'ekrferoe' is 'user@example.de' here fetchall ssl keep
sslfingerprint "1A:EF:49:31:84:6C:87:8D:11:5E:2A:E6:C1:48:08:AF"
GetMail
Im <mail-data>/dms/config/getmail
Verzeichnis sind die Konfigurationen und alle User Konfigurationen eingetragen. Jeder User bekommt da seine eigene Konfiguration pro IMAP oder POP3 service. Gegenüber fetchail
kann Getmail
nicht nur per POP3, sondern auch per IMAP die Mails laden. Hier muss aber unter Umständen noch zusätzliche Pfade im IMAP konfiguriert werden, falls mehrere Pfade geladen werden sollen.
So habe ich in der getmail/getmailrc_general.cf
folgend Konfiguration:
[options]
verbose = 0
read_all = false
delete = false
max_messages_per_session = 500
received = false
delivered_to = false
Für ein Beispiel Konfiguration für GMX
[retriever]
type = SimpleIMAPSSLRetriever
server = imap.gmx.net
username = <GMX email>
password = <GMX password>
mailboxes = ("INBOX","SubMail") // zusätzliche Pfad vom IMAP laden
[destination]
type = MDA_external
path = /usr/lib/dovecot/deliver
allow_root_commands = true
arguments =("-d","test@example.com")
Finale Nacht Lösung
Da immer noch nicht in der Nacht dann alle Mails beim Anbieter gelöscht werden, habe ich momentan noch ein zweites System das nur getriggered den fetchmail
startet und dabei alle Mails auf dem Servern der Anbieter löscht.
Sieve Konfiguration
Einige Mails sollen gleich in entsprechende Unterordner einsortiert werden. Hierfür gibt es Sieve in dem mailserver
Paket. Dafür muss in dem entsprechenden Verzeichnis namens home
in dem user Verzeichnis unter dms/mail-data/<user>/home
eine .dovecot.sieve
Datei erstellt werden. Die Syntax ist auf der Sieve-Homepage zu lesen.
Hier ist ein Beispiel um verschiedene kleine Sortierungen zu machen:
require ["fileinto", "reject"];
if address "From" "noreply@transactions.paramountplus.com" {
fileinto "Spam";
} elsif address "From" "user@googlemail.com" {
fileinto "TestMail";
} elsif address "From" "jobs@mail.xing.com" {
fileinto "Privat/OpenBC";
} else {
keep;
}
Mail Programm
Hat man nun einen mailserver
Container gestartet, egal ob Docker oder Podman, und hat man einen Benutzer hinzugefügt, dann kann man mit jedweden IMAP fähigen Mail Programm die Mails lesen.
Die Server Parameter des Mail-Programms enthalten dann für IMAP service den Namen des Hosts, auf dem der Container läuft. Der Benutzer ist der Name den man beim anlegen des Benutzers angegeben hat (z.B. user@example.com).
Ohne selbsterstelltes SSL Zertifikat wird die Mail unverschlüsselt gelesen. Stört mich für den ersten Eintrag nicht, da ich die Mails nur lokal in meinem privaten Netzwerk lese. Auch habe ich mittlerweile mehrere Dienste in meinem lokalen Netzwerk und da werde ich alle konsolidieren um ein Zertifikat für mein lokales Netzwerk zu erstellen und zu nutzen.
Senden von Mails bzw. SMTP ist mit dieser Lösung auch möglich, nutze ich aber selbst nicht im Moment.
TO_DO
- Nutzen des SSL Zugangs indem ich ein eigenes SSL Certificate erstelle
- Weitere filter Möglichkeiten untersuchen