Eingehende E-Mail-Direktzustellung für selbst gehostete Seiten mit Mail-Receiver konfigurieren

Wie genau kann man die DMARC-Unterstützung deaktivieren?

Das Hinzufügen von INCLUDE_DMARC: false zum env-Abschnitt von mail-receiver.yml scheint dies nicht zu bewirken. Es scheint zwar dazu zu führen, dass die opendkim- und opendmarc-Daemons nicht ausgeführt werden (was zu einer Warnung in den Protokollen führt), aber die SPF-Prüfung wird immer noch durchgeführt.

Bearbeitet zur Ergänzung:
Ich glaube, ich habe es geschafft, die SPF-Prüfungen zu deaktivieren, indem ich auch die folgende POSTCONF_-Zeile zum env-Abschnitt hinzugefügt habe:

env:
  ...
  INCLUDE_DMARC: false
  POSTCONF_smtpd_recipient_restrictions: check_policy_service unix:private/policy
  ...

Ich habe dies durch die Überprüfung des Commits erhalten, der die DMARC-Prüfungen eingeführt hat, und gesehen, was passieren sollte, wenn INCLUDE_DMARC false ist.

Ich weiß so gut wie nichts darüber, wie Docker-Images erstellt werden, aber ich habe den Eindruck, dass das INCLUDE_DMARC-Flag etwas ist, das von jemand anderem, irgendwo anders und zu einer anderen Zeit gesetzt werden soll – nicht etwas, das in mail-receiver.yml erfolgen kann.

2 „Gefällt mir“

Ich habe festgestellt, dass ich Port 443 in ufw öffnen muss – andernfalls erhalte ich in den logs die Meldung API Request Preparation Failed. Ich dachte, dies sollte erwähnt werden, da die Standardinstallationsanweisungen das Aktivieren von ufw erwähnen.

Port 25 wird in der Datei mail-receiver.yml erwähnt und scheint ufw zu umgehen.

1 „Gefällt mir“

Soll das GitHub-Repo im OP sein?

3 „Gefällt mir“

Benutzer von mail-receiver, siehe Remove smtp_should_reject & discourse-smtp-fast-rejection

Wir werden die schnelle Ablehnung vollständig entfernen, da das ursprüngliche Feature fehlerhaft war und Probleme für Benutzer verursachte, insbesondere diese Art von Dingen:

und es betrifft auch weitergeleitete E-Mails, da der Pre-Delivery-Test die Envelope-From- und Envelope-To-Adressen überprüfte, während Discourse nur die Werte in den Headern verwendet.

1 „Gefällt mir“

Ich habe gerade diesen PR eingereicht, um die unnötigen Anführungszeichen um den Wert von DISCOURSE_BASE_URL in der Beispieldatei mail-receiver.yml zu entfernen. Die Anführungszeichen haben mein Setup beeinträchtigt. Das Entfernen der Anführungszeichen ermöglicht den erfolgreichen Abschluss dieses Dokuments.

Können Sie erklären wie? Die Anwesenheit/Abwesenheit von Anführungszeichen um diesen Wert ergibt keinen Unterschied:

[2] pry(main)=> YAML::load("env:\n  DISCOURSE_BASE_URL: 'https://discourse.example.com'")
=> {"env"=>{"DISCOURSE_BASE_URL"=>"https://discourse.example.com"}}

[3] pry(main)=> YAML::load("env:\n  DISCOURSE_BASE_URL: https://discourse.example.com")
=> {"env"=>{"DISCOURSE_BASE_URL"=>"https://discourse.example.com"}}

Als ich die Logs von diesem Container verfolgte und Nachrichten daran sendete, sah ich eine Reihe von Fehlern, die so etwas wie discourse.example.com ist kein Teil der MX-Einträge oder Ähnliches erwähnten. Ich habe die Anführungszeichen entfernt, den Container neu erstellt und es funktionierte :person_shrugging:

Die Reihenfolge der Ereignisse könnte auch eine Rolle spielen:

  1. Ich habe den Mail-Receiver-Container konfiguriert und gestartet
  2. Einige Tage später habe ich die MX-DNS-Einträge eingerichtet
  3. Ich habe überprüft, ob die MX-Einträge korrekt gesetzt waren, und dann mit dem Testen begonnen. Es funktionierte nicht
  4. Anführungszeichen entfernt, Container neu erstellt, funktionierte

Ich bin mir also nicht sicher, ob die Lösung mit dem Entfernen der Anführungszeichen oder mit dem Neuerstellen des Containers nach dem Erstellen der MX-Einträge zusammenhing.

Im schlimmsten Fall sorgt der PR dafür, dass die yml-Datei konsistent aussieht :slight_smile:

1 „Gefällt mir“

Es scheint die Annahme zu bestehen, dass der Mail-Empfänger immer dieselbe Domain wie das Basisforum ist. Wenn dies nicht der Fall ist, wie richten wir TLS ein?

Zum Beispiel:
forum => forum.domain.tld
mail-receiver => mail.domain.tld

In der mail-receiver.yml zeigt TLS auf die Basis-Forum-Zertifikate. Gibt es eine Möglichkeit, dass mail-receiver eigene Zertifikate bezieht?

Ich kenne die direkte Antwort nicht, obwohl ich vermute, dass zusätzliche Optionen in der yml erforderlich wären, um Änderungen am Container während des Builds vorzunehmen.

Mehr dazu folgt, aber ich frage mich, was Ihre Beweggründe sind, es unter einer anderen Domain zu betreiben. Der Mail-Receiver ist stark zugeschnitten und funktioniert ohne Änderungen ausschließlich zum Empfangen von E-Mails für eine gekoppelte Discourse-Instanz, daher ist es typischerweise ratsam, ihn unter derselben Domain wie diese Instanz betreiben zu lassen.


Wenn Sie sich einige der Vorlagen ansehen, die Sie in Ihre Discourse yml aufnehmen können, von denen einige bereits verwendet werden, sollten Sie einige Hinweise darauf erhalten, wie Sie Befehle ausführen und Dateien über die yml (während des Container-Builds) ändern können.

web.onion.template.yml enthält einige Beispiele dafür, wie Zeichenfolgen innerhalb von Dateien ersetzt werden können, und web.letsencrypt.ssl.template.yml ist diejenige, die Let’s Encrypt zum Haupt-Discourse-Container hinzufügt.

Ich weiß nicht, wie viel davon von Dingen im Basis-Image abhängt, daher wäre es möglicherweise einfacher, den Haupt-Discourse-Container ein zweites Zertifikat abrufen zu lassen und dann die Zertifikats-/Schlüsselpfade in mail-receiver.yml entsprechend zu ändern.

Seien Sie vorsichtig bei dieser Art von Änderungen, wenn Sie diesen Ansatz wählen, und stellen Sie sicher, dass Sie genau wissen, welche Auswirkungen die Änderung haben wird. Eine fehlerhafte Änderung an den Let’s Encrypt-Sachen könnte beispielsweise zu einem stillschweigend fehlschlagenden Zertifikats-Erneuerung führen, was Ihnen möglicherweise erst nach etwa 3 Monaten auffällt, wenn Besucher abgelaufene Zertifikatsfehler erhalten.

CloudFlare Anwendungsfall

Diese Anweisungen gelten für selbst gehostete Discourse-Foren, die den Cloudflare Proxy verwenden.

Wenn Sie den Cloudflare Proxy verwenden, verhindert dies, dass jeglicher SMTP-Verkehr (Port 25) Ihren Server erreicht. Dies erfordert die Einrichtung eines anderen Subdomains, damit der Mail-Receiver funktioniert.

Wenn Ihre Domain beispielsweise forums.domain.tld lautet, müssen Sie eine neue Subdomain erstellen, z. B. mail.domain.tld.

Mit Cloudflare haben Sie die folgenden zusätzlichen Schritte.

  1. Erstellen Sie den A-Eintrag für die neue Subdomain. Er verwendet dieselbe IP-Adresse wie Ihre forums.domain.tld.
  2. Erstellen Sie den MX-Eintrag für die neue Subdomain, wie in den Hauptanweisungen angegeben.

Folgen Sie den Hauptanweisungen mit dieser geringfügigen Änderung. Es wird einwandfrei funktionieren, wenn die TLS-Sicherheit deaktiviert ist.

Wenn Sie die TLS-Sicherheit aktivieren möchten, sind zusätzliche Arbeiten erforderlich.

Überblick über die TLS-Einrichtung

Diese Anweisungen installieren Certbot und ein CloudFlare Certbot-Plugin. Die Befehle werden LetsEncrypt-Zertifikate im Standalone-Modus über den DNS-Zertifizierungsprozess abrufen. Sobald die Zertifikate verfügbar sind, werden sie in den gemeinsam genutzten Bereich des Mail-Receivers kopiert, damit der Container sie verwenden kann. Wir müssen das DNS-Modell verwenden, da Discourse bereits Port 80 verwendet.

DNS-Herausforderung

Anstatt den Besitz der Domain über HTTP nachzuweisen, beweist Certbot dies durch das Erstellen eines TXT-Eintrags in Ihrem DNS. Da Ihr DNS Cloudflare ist, kann dies mit einem Cloudflare API-Token vollständig automatisiert werden – kein Port 80, kein Herunterfahren des Webservers erforderlich.

Funktionsweise

Certbot → Erstellt den _acme-challenge.mail.lotuselan.net TXT-Eintrag in Cloudflare
Let's Encrypt → Ruft diesen TXT-Eintrag ab → Validiert → Stellt das Zertifikat aus
Certbot → Löscht den TXT-Eintrag

All dies geschieht auf Ihrem Basis-Server, nicht innerhalb des Discourse-Containers.

Einrichtung

1 — Installieren Sie Certbot und das Cloudflare Certbot-Plugin:

bash

apt install certbot python3-certbot-dns-cloudflare -y

2 — Erstellen Sie ein Cloudflare API-Token:

  1. Gehen Sie zu Cloudflare → Mein Profil → API-Tokens → Token erstellen
  2. Verwenden Sie die Vorlage „Zonen-DNS bearbeiten“
  3. Berechtigungen: Zone → DNS → Bearbeiten
  4. Zonenressourcen: Einschließlich → Spezifische Zone → lotuselan.net
  5. IP-Einschränkungen: Nur so einrichten, dass der Zugriff von der IP-Adresse Ihres Servers erlaubt wird
  6. Kopieren Sie das Token

3 — Speichern Sie das Token in einer Anmeldedatei:

bash

mkdir -p /etc/letsencrypt/cloudflare
nano /etc/letsencrypt/cloudflare/credentials.ini

Fügen Sie ein:

dns_cloudflare_api_token = IHR_CLOUDFLARE_API_TOKEN

Sichern Sie die Datei:

bash

chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

4 — Fordern Sie das Zertifikat an:

Aktualisieren Sie den folgenden Befehl mit Ihrer Admin-E-Mail-Adresse und dem Domainnamen.

bash

certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --non-interactive \
  --agree-tos \
  --email Ihreemailadresse@domain.tld \
  -d mail.domain.tld

In Ihren Ergebnissen sollte eine Meldung erscheinen, die besagt:

Certbot hat eine geplante Aufgabe eingerichtet, um dieses Zertifikat automatisch im Hintergrund zu erneuern.

Certbot richtet einen Cronjob ein, um die Ablaufdaten der Zertifikate zweimal täglich zu überprüfen. Es wird die Zertifikate erneuern, wenn sie weniger als 30 Tage vor dem Ablauf stehen. Sie können dies überprüfen durch:

# Prüfen, ob der systemd-Timer aktiv ist (die meisten modernen Ubuntu-Systeme)
systemctl status certbot.timer

# Oder prüfen, ob ein Cronjob hinzugefügt wurde
cat /etc/cron.d/certbot

Sie haben nun die TLS-Zertifikate auf Ihrem Server für den neuen Mail-Receiver-Domainnamen. Sie befinden sich nicht an einem Ort, an dem sie verwendet werden können.

5 — Richten Sie ein Bereitstellungsskript für das Verschieben von Dateien ein
Da Certbot automatisch erneuert, müssen Sie mit Ihrem Skript nur die Discourse-spezifischen Teile behandeln – das Kopieren der erneuerten Zertifikate und das Neuerstellen des Mail-Receivers. Sie können das Skript erheblich vereinfachen, indem Sie den integrierten Deploy Hook von Certbot verwenden, der nach einer erfolgreichen Erneuerung automatisch ausgeführt wird.

Erstellen Sie eine Deploy-Hook-Datei:

bash

nano /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh
chmod +x /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh

Fügen Sie dies ein:

bash

#!/bin/bash
DOMAIN="mail.domain.tld"
DISCOURSE_DIR="/var/discourse"
CERT_SRC="/etc/letsencrypt/live/${DOMAIN}"
CERT_DEST_1="${DISCOURSE_DIR}/shared/mail-receiver/letsencrypt/${DOMAIN}"
CERT_DEST_2="${DISCOURSE_DIR}/shared/mail-receiver/letsencrypt/${DOMAIN}_ecc"
ADMIN_EMAIL="admin email address"
LOG_FILE="/var/log/mail-cert-renewal.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "=== Certbot deploy hook für ${DOMAIN} ausgelöst ==="

# Zertifikate kopieren (verwenden Sie -L, um symbolische Links aufzulösen)
for DEST in "$CERT_DEST_1" "$CERT_DEST_2"; do
    mkdir -p "$DEST"
    cp -L "${CERT_SRC}/fullchain.pem" "${DEST}/fullchain.pem"
    cp -L "${CERT_SRC}/privkey.pem"   "${DEST}/privkey.pem"
    cp -L "${CERT_SRC}/cert.pem"      "${DEST}/cert.pem"
    cp -L "${CERT_SRC}/chain.pem"     "${DEST}/chain.pem"
    chmod 644 "${DEST}/fullchain.pem" "${DEST}/cert.pem" "${DEST}/chain.pem"
    chmod 600 "${DEST}/privkey.pem"
    log "Zertifikate kopiert nach ${DEST}"
done

# Mail-Receiver neu erstellen
cd "$DISCOURSE_DIR" || { echo "Kann nicht nach ${DISCOURSE_DIR}" | mail -s "[FEHLER] Mail-Zertifikat-Deploy-Hook fehlgeschlagen" "$ADMIN_EMAIL"; exit 1; }
log "Erstelle mail-receiver neu..."
if ./launcher rebuild mail-receiver >> "$LOG_FILE" 2>&1; then
    log "mail-receiver erfolgreich neu erstellt"
else
    log "FEHLER: Neuerstellung fehlgeschlagen"
    echo "mail-receiver-Neuerstellung nach Zertifikatserneuerung fehlgeschlagen. Prüfen Sie ${LOG_FILE}" | \
        mail -s "[FEHLER] Mail-Zertifikat-Deploy-Hook fehlgeschlagen" "$ADMIN_EMAIL"
    exit 1
fi

log "=== Deploy hook erfolgreich abgeschlossen ==="

Kein manueller Cronjob erforderlich – Certbot koordiniert den gesamten Prozess. Der Deploy Hook wird nur ausgelöst, wenn tatsächlich eine Erneuerung stattfindet, sodass Ihr Mail-Receiver an Tagen, an denen Certbot prüft, aber nicht erneuert, keine unnötigen Neuerstellungen durchläuft.

Um den Erneuerungs-Hook zu testen, führen Sie Folgendes aus:

bash

bash /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh

Wenn alles korrekt eingerichtet wurde, wird dies
→ Zertifikate in Discourse-Verzeichnisse kopieren
→ mail-receiver neu erstellen
→ alles protokollieren

6 — TLS in mail-receiver.yml einrichten

Das Hauptproblem hier scheint zu sein, dass der A-Eintrag für forum.domain.tld durch den Proxy maskiert wird, anstatt explizit einen Mailserver unter einer separaten Domain zu wünschen.

Bei der Aushandlung von TLS wird der Common Name des Zertifikats mit dem Hostnamen des MX-Eintrags verglichen, d. h. dem Hostnamen, mit dem der Client (möglicherweise ein anderer Mailserver) versucht, eine Verbindung herzustellen, anstatt mit dem A-Eintrag, auf den er verweist. Das bedeutet, Sie können Ihren mail.domain.tld A-Eintrag auf DNS Only setzen, dann einen MX-Eintrag für forum.domain.tld erstellen, der auf mail.domain.tld verweist, und in dieser Konfiguration sind keine weiteren speziellen Schritte erforderlich.

[quote=“Simon_Manning, post:542, topic:49487”]Ein Satz auf DNS-Modus Nur gesetzt, dann einen MX-Eintrag für forum.domain.tld erstellen, der auf mail.domain.tld verweist, und in dieser Konfiguration sind keine weiteren besonderen Schritte erforderlich.
[/quote]

Ja, Sie können den DNS-Modus nur für den A-Eintrag Ihres Hauptforums verwenden. Bei dieser Vorgehensweise verlieren Sie die umgekehrten globalen Proxy-Funktionen von CloudFlare. (Dies war für meine Discourse-Installation keine Option.)

Deshalb gilt die erste Zeile, die diese Lösung definiert, für Websites, die den CloudFlare Proxy verwenden.

Ich bezog mich auf den A-Eintrag von mail.domain.tld, der auf DNS-Modus allein eingestellt war, anstatt auf den A-Eintrag von forum.domain.tld. Allerdings habe ich erkannt, dass ich falsch interpretiert habe, wie SMTP-Clients TLS-Zertifikate authentifizieren.

Das Verhalten, das ich beobachtete, war ein Artefakt der standardmäßigen opportunistischen Methode, die den Hostnamen nicht validiert. Meine Behauptung, dass der Hostname des MX-Eintrags und nicht das Ziel des MX-Eintrags validiert wird, war daher falsch. Es würde in den meisten Fällen funktionieren, aber nicht, wenn DANE oder MTA-STS zur Erzwingung der TLS-Identitätsauthentifizierung verwendet werden.

Wenn der A-Eintrag auf „proxied“ (weitergeleitet) und der MX-Eintrag auf „DNS Only“ (nur DNS) gesetzt ist, funktioniert es nicht. CloudFlare-Dokumentationen besagen, dass bei jeder Domain, deren A-Eintrag weitergeleitet wird, der gesamte SMTP-Verkehr blockiert wird.

Ich habe dies durch mehrere Testrunden bestätigt. In dem Moment, in dem der A-Eintrag nicht mehr weitergeleitet wird, fließen SMTP-Daten. Schalten Sie die Weiterleitung ein, fließen SMTP-Daten nie. (Die Tests wurden durch die Verwendung von TELNET auf Port 25 durchgeführt.)

Wenn Sie also Folgendes möchten:

  • Ihr Discourse-Forum soll die CloudFlare-Proxy-Dienste nutzen
  • Ihr SMTP-Mail-Empfänger soll E-Mails akzeptieren

Müssen Sie unterschiedliche Domains für Ihren eingehenden Mailverkehr verwenden.

Wenn Sie TLS für Ihren SMTP-Mail-Empfänger wünschen:

  • Sie müssen ein LetsEncrypt über DNS-Prüfung einrichten

Die Anweisungen sehen einschüchternd aus, aber die Erstellung der Anweisungen dauerte länger als die eigentliche Implementierung der Lösung.

Das meinte ich nicht. Konkret schlug ich drei DNS-Einträge vor:
A: forum.domain.tld → Host-IP-Adresse (Proxy aktiviert)
A: mail.domain.tld → Host-IP-Adresse (Nur DNS-Modus)
MX: forum.domain.tldmail.domain.tld

Allerdings stellte ich später fest, dass dies nur im Standard-Opportunistic-TLS-Modus funktionieren würde. Es funktioniert nicht, wenn man DANE oder MTA-STS aktivieren möchte, um die Identitätsauthentifizierung zu erzwingen (sicherstellen, dass die richtige Serververbindung hergestellt wird, anstatt nur den Verkehr zu verschlüsseln).

Sie sehen sehr gut aus, sind leicht zu befolgen und erledigen alles außerhalb des Containers, sodass kein Risiko besteht, dass es bei Discourse-Updates möglicherweise zu Problemen kommt. Besonders gut gefällt mir die Verwendung eines Certbot-Erneuerungshooks, mit dem ich vorher nicht vertraut war.

1 „Gefällt mir“

Beachten Sie, dass dies die IP-Adresse Ihres Forums offenlegt und es möglich macht, Cloudflare-Schutzmechanismen wie DDoS-Schutz und WAF zu umgehen. Es ist besser, den Mail-Receiver auf einem separaten Server zu betreiben.

Meine erste Absicht war es aus diesem Grund, den Mail-Receiver auf einem anderen Server laufen zu lassen. Jedes Mal, wenn ich versuchte, die Launcher-Anwendung zu starten, um den Mail-Receiver zu starten, wollte diese das komplette Discourse-System installieren. Gibt es eine einfache Möglichkeit, nur den Mail-Receiver auf einem eigenständigen Docker-Server zu starten und auszuführen?

Ich bin mit der Launcher-App nicht wirklich vertraut, da wir unsere eigene Infrastruktur entwickeln. Meine Idee wäre, die Launcher-App dann nicht zu verwenden und sie wie jeden anderen Container zu starten. Die benötigten Umgebungsvariablen finden Sie in der Readme.

@Simon_Manning & @RGJ – Der Cloudflare-Artikel wurde aktualisiert, um die drei Hauptoptionen und deren Vor- und Nachteile darzustellen. Hoffentlich werden damit die verschiedenen Probleme behoben, die Sie mit den zunächst vorgestellten Optionen angesprochen haben.

@kelv Sie könnten in der Hauptbeschreibung des Cloudflare-Artikels eine Fußnote einfügen. Dies spart den betroffenen Personen Zeit. Configure direct-delivery incoming email for self-hosted sites with Mail-Receiver - #541 by LotusJeff

2 „Gefällt mir“