Mastodon

ecoMAILZ im Docker hinter einem WireGuard-VPN verstecken

ecoMAILZ im Docker hinter einem WireGuard-VPN verstecken

Revionssichere E-Mail-Archivierung mit ecoMAILZ

Ab dem 01.01.2025 wurde die E-Rechnung mehr oder weniger verpflichtend für deutsche Unternehmen. Ich habe mich daher im letzten Jahr für unsere Kunden nochmal mit der revisionssicheren Archivierung von E-Mails befasst und mir verschiedene Lösungen angeschaut. Der folgende Artikel beschreibt eine schlanke und ziemlich universelle Lösung, welche IMHO für die meisten Szenarien ausreichend sein dürfte.

Was bedeutet eigentlich revisionssichere Archivierung?

Grob vereinfacht darf z. B. eine E-Mail, nachdem sie revisionssicher archiviert wurde, nicht mehr gelöscht oder anderweitig verändert werden. Ein normales Backup des Postfaches oder gar das Verschieben in einen "Archivordner" innerhalb des E-Mail-Postfaches ist also defintiv keine revisionssichere Archivierung.

Alles klar! Nur wer braucht eine revisionssichere Archivierung?
Vor allem vermutlich Unternehmen und andere Organisationen, welche einer gesetzlichen Dokumentationspflicht nachkommen müssen. Hier ist die GoBD das vermutlich wichtigste Stichwort.

Ansonsten mag jeder selber entscheiden, ob er seine E-Mail-Postfächer archivieren möchte. Es stellt in jedem Fall ein automatisiertes Backup dar, falls man mal eine E-Mail mit einer Rechnung sucht...


Warum ecoMAILZ?

Je nach Bedarf gibt es verschiedene Lösungen, wie man eine revisionssichere Archivierung von E-Mail-Postfächern hinbekommt. Ich möchte hier die kommerzielle Software ecoMAILZ vorstellen, da diese in meinen Augen folgende Vorteile bietet:

  1. webbasierte Lösung die keinen Fatclient benötigt
  2. kann plattformunabhängig auf fast allen Systemen mit genug Leistung gehostet werden
  3. es gibt ein offizielles Docker-Image
  4. sehr faire Preisstruktur und bis 3000 Mails kostenlos einsetzbar

ecoMAILZ lässt sich sehr flexibel auf fast jedem System einrichten, was ich wirklich sehr charmant finde. Durch den offiziellen Docker-Container kann ich ecoMAILZ sogar z. B. auf einem Synology_NAS laufen lassen. Das fand ich zunächst Spielerei, aber das ist durchaus für kleine SoHo-Setups relevant. Vor allem da ich mit aktuellen Synology-NAS eine ganz ordentliche Backupstratgie aufgezogen bekommen. Vielleicht mache ich dazu auch mal einen Artikel...


ecoMAILZ auf dem Root-Server

Was aber tun, wenn man kein NAS zu Hause hat und auch sonst kein stromfressendes Blech laufen lassen möchte? Vielleicht könnte man ecoMAILZ auf einem Linux-Root-Server hosten, auf dem zufällig noch etwas Platz ist.

Ich hatte jedoch ein wenig Bauchschmerzen bei dem Gedanken, ecoMAILZ einfach so an eine Subleveldomain zu hängen und für jedermann im Internet erreichbar zu machen. Ich will damit jetzt nicht sagen, dass ich ecoMAILZ Qualitätsmängel unterstelle, aber meine E-Mail-Archivierung gehört IMHO nicht direkt ins Netz. Also doch lieber nicht auf den Root-Server packen?

Es gibt da evtl. einen Kompromiss: ecoMAILZ liegt als offizielles Docker-Image und so wäre es möglich mit den Netzwerkfunktionen von Docker, das Webfrontend von ecoMAILZ in einem internen Netzwerk "einzusperren" und nur über einen VPN-Tunnel erreichbar machen! So läuft das ecoMAILZ zwar auf dem Root-Server, ist aber nur für authorisierte Anwender über den VPN-Tunnel erreichbar.

Der folgende Artikel beschreibt daher, wie man ecoMAILZ auf dem Root-Server in einer Dockerumgebung so betreibt, dass es nur für authorisierte Benutzer überhaupt erreichbar wird.


Lösungsansatz mit Docker und Wireguard

Kapselung von ecoMAILZ

Da Docker auf ein eigenes virtuelles Netzwerk setzt, kann ich so die Schnittstellen und das Webfrontend von ecoMAILZ in ein internes Netzwerk einsperren. Der Dienst ist so nicht über das Netzwerkinterface des Hosts erreichbar und ich kann auf eine alternative Lösung mit Firewallregeln verzichten.

Die Konfiguration sieht grob wie folgt aus:

  • Kein Portmapping: Es wird bewusst kein Portmapping vorgenommen, um zu verhindern, dass die Schnittstellen und das Webfrontend von ecoMAILZ öffentlich zugänglich sind.
  • Virtuelles internes Docker-Netzwerk: Es wird ein internes Docker-Netzwerk namens ecomailz_intern erstellt, in dem ecoMailz läuft. Dieses Netzwerk ist nur innerhalb der Docker-Umgebung erreichbar.
  • Internet-Zugriff: Der ecoMailz-Container wird mit dem Docker-Standardnetzwerk defaultverbunden, um Zugriff auf das Internet für den Abruf von E-Mails zu erhalten.

Der VPN-Dienst WireGuard

Für den sicheren Zugriff interner Benutzer auf das interne Docker-Netzwerk wird der VPN-Dienst WireGuard als Docker-Container implementiert. Dieser Dienst bietet folgende Funktionen:

  • Zugriff auf das virtuelle Docker-Netzwerk ecomailz_intern.
  • Zugriff auf das Internet über das Docker-Standardnetzwerk default.
  • Externe Erreichbarkeit durch Mapping des WireGuard-Ports auf die Netzwerkkarte des Docker-Hosts.

Um die Wiederverwendbarkeit zu gewährleisten, wird WireGuard als eigenständiges Docker-Projekt realisiert, das unabhängig von ecoMAILZ betrieben wird.

Man kann Wireguard auch in einem gemeinsamen Docker Projekt laufen lassen, was die Konfiguration etwas erleichtert und verkürzt. Darauf habe ich aber explizit verzichtet, um ggf. bei einem weiteren ähnlichen Projekt nicht mehrere Wireguard-Instanzen parallel betreiben zu müssen.

Zugriff von Extern auf ecoMAILZ

Da Docker zur internen Kommunikation DNS-Namensauflösung nutzt, stellt sich die Frage, wie externe Benutzer über den VPN-Tunnel auf das ecoMAILZ-Webfrontend zugreifen können. Folgende Optionen wurden bewertet:

  1. Manuelle Nutzung der IP-Adresse: Die interne IP-Adresse des ecoMAILZ-Containers kann ausgelesen und auf dem Client verwendet werden. Problematisch ist jedoch, dass diese IP-Adresse sich ändern könnte, obwohl sie semi-statisch ist. Alternativ kann die IP-Adresse manuell gesetzt werden.
  2. Expose der Docker-internen DNS-Namensauflösung: Die interne DNS-Namensauflösung von Docker kann nach außen sichtbar gemacht werden. Dies birgt jedoch IMHO Sicherheitsrisiken, da dadurch die DNS-Namen aller Docker-Container einsehbar werden.
  3. Parallele DNS-Infrastruktur: Mithilfe von dnsmasq kann eine eigene DNS-Infrastruktur für die Container erstellt werden. Diese löst nur die Namen der relevanten Container auf und ist technisch die sauberste Lösung. Aufgrund des geringeren Bedarfs wurde zunächst die erste Option gewählt.

Einrichtung des Docker-Netzwerkes

Da wir ecoMAILZ und WireGuard in zwei getrennten Docker-Projekten betreiben, müssen die beiden Container über ein gemeinsames internes Netzwerk kommunizieren, um den Zugriff auf das ecoMAILZ-Frontend über den WireGuard-VPN-Tunnel zu ermöglichen. Dieses interne Netzwerk wird manuell erstellt und anschließend in den jeweiligen docker-compose.yml-Dateien eingebunden, damit beide Projekte das Netzwerk gemeinsam nutzen können.

Um die genannten Anforderungen zu erfüllen, wird das interne Netzwerk ecomailz_intern wie folgt erstellt:

docker network create --driver bridge --internal ecomailz_network

Verwendung des erstellten Docker-Netzwerkes

Das manuell erstellte Netzwerk ecomailz_internal wird in den docker-compose.yml-Dateien der Projekte eingebunden und als external: true deklariert, um eine gemeinsame Nutzung zu ermöglichen.

Unterschiede zwischen internen und externen Netzwerken

Interne Netzwerke (internal: true)

  • Diese Netzwerke sind vollständig isoliert. Nur Container innerhalb des gleichen Netzwerks können miteinander kommunizieren. Weder andere Docker-Netzwerke noch der Host haben Zugriff. Diese Konfiguration eignet sich ideal für Dienste, die ausschließlich intern genutzt werden.
  • "By default, Compose provides external connectivity to networks. Setting internal: true allows you to create an externally isolated network."
  • Quelle: Docker Documentation

Externe Netzwerke (external: true)

  • Diese Netzwerke werden manuell erstellt und können von mehreren Projekten gemeinsam genutzt werden. Sie erlauben die Kommunikation zwischen Containern verschiedener Projekte und den Zugriff durch externe Clients, beispielsweise über einen VPN-Tunnel.
  • "If set to true, external specifies that this network’s lifecycle is maintained outside of that of the application."
  • Quelle: Docker Documentation

Diese Konfiguration ermöglicht, dass ecoMAILZ und WireGuard über ein gemeinsames internes Netzwerk miteinander kommunizieren können, während die Dienste vor direktem Internetzugriff geschützt bleiben.


Die Docker Compose Configs

WireGuard-Konfiguration

Dokumentation des Docker-Image-Maintainers LinuxServer.io zur Einrichtung, Betrieb und Parametrisierung.

version: '3.8'
services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - SERVERURL=wireguard.DEINEDOMAIN.de
      - SERVERPORT=51820
      - PEERS=1
      - PEERDNS=1.1.1.1
    volumes:
      - ./wireguard-config:/config
      - /lib/modules:/lib/modules
    ports:
      - 51820:51820/udp
    networks:
      - default
      - ecomailz_network
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

networks:
  ecomailz_network:
    external: true

ecoMAILZ-Konfiguration

version: '3.8'
services:
  ecomailz:
    image: ecomailz/donnie
    container_name: ecomailz
    volumes:
      - ./export:/srv/export
      - ./backup:/srv/backup
      - ./data:/srv/data
    networks:
      - default
      - ecomailz_network
    restart: unless-stopped

networks:
  ecomailz_network:
    external: true

Schritt-für-Schritt-Anleitung

1. Vorbereitungen

  1. Voraussetzungen:
    • Ein laufender Debian oder Ubuntu Root-Server mit Docker und Docker Compose.
    • Zugang zu den ecoMailz-Installations- und Konfigurationsdokumentationen.
    • Falls Exchange Online verwendet wird, Vorbereitung des M365-Azure-Umgebung für die Anbindung des ecoMailz-Adapters - siehe Anleitung in der ecoMailz-Dokumentation.
  2. Verzeichnisse für ecoMAILZ erstellen:
mkdir -p /var/docker/ecomailz
mkdir -p /var/docker/ecomailz/export
mkdir -p /var/docker/ecomailz/backup
mkdir -p /var/docker/ecomailz/data
  1. Verzeichnisse für Wireguard erstellen:
mkdir -p /var/docker/wireguard
mkdir -p /var/docker/wireguard/wireguard-config

2. Einrichtung WireGuard-Host

  1. Erstelle das interne Netzwerk:
docker network create --driver bridge --internal ecomailz_network

Hinweis: Das gemeinsame interne Docker-Netzwerk muss existieren, bevor die Container gestartet werden.

  1. Wechsle in das WireGuard-Verzeichnis:
cd /var/docker/wireguard
  1. Erstelle die Docker-Compose-Datei:
vim docker-compose.yml
  1. Übernimm die WireGurard-Konfiguration und passe sie nach Bedarf an..

  2. Starte den WireGuard-Container:

docker-compose up -d

3. Konfiguriere die VPN-Clients:

Die Konfigurationsdatei für den WireGuard-Client wird beim ersten Start des Containers automatisch erzeugt.

Lade die Client-Konfigurationsdatei herunter:

docker exec wireguard cat /config/peer1/peer1.conf > ./peer1.conf

und importiere die Konfiguration in deinen WireGuard-Client. Anschließend starte die VPN-Verbindung. Der Zugriff auf das öffentliche Internet sollte weiterhin klappen und nach außen sollte dein Rechner jetzt mit der öffentliche IP-Adresse deines Root-Server unterwegs sein.

4. Einrichtung von ecoMailz

  1. Wechsle in das ecoMailz-Verzeichnis und erstelle die docker-compose.yml:
cd /var/docker/ecomailz
vim docker-compose.yml
  1. Kopiere die ecoMAILZ-Konfiguration.
  2. Starte den ecoMailz-Container:
docker-compose up -d

5. Testen des Setups

5.1 Überprüfung der internen Kommunikation

  1. Prüfe ob beide Container Teil des Netzwerkes ecomailz_intern sind und eine entsprechende IP-Adresse besitzen:
docker network inspect ecomailz_intern
[
    {
        "Name": "ecomailz_intern",
...
...
...
        "Containers": {
            "6b918731931aa20ab901caaef977ae633a925cabe9e05cc77646f50951532e37": {
                "Name": "wireguard",
                "EndpointID": "c428e9b7576a248118a4ac029e9291eb20ca205b7bf67d07d3372cff72cb84f6",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            },
            "c1ba331c23004291eb8176bc888f0f325398871bee7a7e077daab084e0836efc": {
                "Name": "ecomailz",
                "EndpointID": "66c95b3ce6ed755a8bf0a86a0f29f09f4f1245876ceb012ce209bc75bcbbe61d",
                "MacAddress": "02:42:ac:15:00:03",
                "IPv4Address": "172.21.0.3/16",
                "IPv6Address": ""
            }
        },
...
...
...
]
  1. Prüfe ob der Wireguard-Container den Ecomailz-Container per ping erreichen kann:
docker exec wireguard ping -c 4 ecomailz

5.2 Zugriff auf ecoMailz über VPN:

Da wir interne Kommunikation zwischen den Docker-Containern erfolgreich geprüft haben, sollte der Zugriff über die VPN-Verbindung ebenfalls funktionieren. Baue die VPN-Verbindung und fahre mit den folgenden Tests fort:

  1. Ermittle oder zumindest überprüfe die interne IP-Adresse des ecoMailz-Containers:
docker network inspect ecomailz_intern
  1. Prüfe ob die interne Adresse des ecoMAILZ-Containers per ping von deinem Client erreichen kannst.
  2. Wenn auch das klappt, solltest du das Webfrontend von ecoMAILZ im Browser öffnen können:
http://<ecoMailz-Container-IP>:8888

Weitere Einrichtung ecoMAILZ

Ab hier kann nun mit der weiteren regulären Einrichtung des ecoMAILZ-Dienstes fortgefahren werden.

Offizielle ecoMAILZ-Dokumentation: