WP_Mail ist nicht kaputt

WP Mail ist nicht kaputt - DKIM für wp_mail

Table of content

Warum versuchen dann alle, es zu reparieren? Ich versuche, es zu erklären. WP_Mail() ohne funktionierendem DKIM schlägt fehl – und hier bekommst du die Lösung. Ich zeige dir, wie du ohne zusatzliches Plugin den E-mail-Versand in WordPress verbessern kannst.

Vor ein paar Wochen bin ich mit meinem Server umgezogen von einem LAMP Stack (Linux, Apache, Mysql und PHP) zu einem LOMP Stack (Ich habe statt Apache nun OpenLiteSpeed als Webserver.)

Durch den Umzug musste ich zunächst meine Seiten umziehen und am Ende den Emailserver.

Dabei habe ich unter anderem auch darauf geachtet, die Anzahl meiner Plugins zu reduzieren, einfach um die Performance zu erhöhen.

Eines der Plugins, die ich vorher verwendet habe, war Fluent SMTP – eigentlich ein sehr nützluiches Tool mit dem du deine Emails statt mit wp_mail() nun über SMTP versendest.

Das tolle an Fluent SMTP ist, dass du jederzeit deinen Mailsever bzw. deine Emailverbindung austauschen kannst und einfach eine andere Verbindung nutzen kannst.

Aber warum habe ich Fluent SMTP überhaupt genutzt? Nun, weil ich für meine Mails immer schon DKIM nutzen wollte, was aber teilweise bei einigen Anbietern nicht so ohne Weiteres machbar war.

Bei der Nutzung von SMTP habe ich diese Probleme in der Regel nicht, weil ich mir den Versand aussuchen kann und mich für einen Anbieter mit DKIM Unterstützung entscheiden kann.

Was viele noch zurück gehalten hat, wp_mail() zu nutzen? Die Zustellbarkeit der Emails war teilweise schlecht, was allerdings letztlich auch nur eine Einstellung ist – und wie die am besten funktioniert, zeige ich dir heute. du brauchst folgende Dinge, damit deine Mails sauber und erfolgreich zugestellt werden:

  • einen passenden Return Path
  • DKIM und DMarc für den Versand von Emails
  • SPF DNS Eintrag eingeben
  • einen DKIM Schlüssel und den DNS Eintrag dafür

Emails authentifizieren

Wenn du willst, dass deine Emails beim Empfänger ankommen, musst du deinen Mailserver entsprechend konfigurieren, und diese DNS Werte zu deiner Domain hinzufügen.

  • DMarc – Domain-based Message Authentication, Reporting and Conformance
  • DKIM – DomainKeys Identified Mail
  • SPF – Sender Policy Framework

Wenn du es richtig konfigurierst, sorgst du dafür, dass deine E-Mails bei Empfängern wie Gmail und Co auch ankommen.

Diese Werte in den DNS-Einstellungen sind wichtig, damit deine Mails nicht im Spam-Ordner landen, sondern beim Empfänger im Posteingang landen.

Ich wollte die beste Email Konfiguration

Problematisch an meinem Umzug war, dass ich durch den Wechsel auf OpenLiteSpeed diverse Einstellungen an meinem Webserver vorgenommen habe, von denen eine ein spezielles Logging war. Durch das spezielle Logging wurden mir Fehlermeldungen und Warnungen in meiner WordPress Instanz angezeigt – und eine der Warnungen war:

“Fluent SMTP – Creation of Dynamic Properties deprecated”.

Das ist grundsätzlich erst einmal nicht schlimm, sagt es doch, dass die in dem Plugin verwendete Funktion mit meiner PHP Version nicht mehr konform ist – sie ist sozusagen veraltet.

Genaugenommen ist diese Funktion seit PHP8.2 veraltet – wenn du also eine neuere PHP Version nutzen willst, dann musst du dein Plugin entweder updaten oder eventuell darauf verzichten.

Genau hier entstand allerdings das Problem – Stand heute (22.04.2024) wurde das Plugin zuletzt vor einem Monat aktualisiert.

Fluent SMTP not updated

Und da das nicht mein Plugin war, wollte ich nicht selbst Hand anlegen.

Also hatte ich zwei Optionen: entweder drauf verzichten oder… PHP downgraden.

Kein Downgrade von PHP

Aus Performancegründen wollte ich PHP nicht auf die Version 8.1 herunter stufen, zumal PHP 8.1 auch nur noch bis zum Ende dieses Jahres (Ende 2024) Security Updates erhalten sollte. Mehr Infos unter https://www.php.net/supported-versions.php

Also habe ich nach einer Lösung gesucht für den Versand mit wp_mail – WordPress hat eine eingebaute Funktion, mit der du ganz einfach Mails versenden kannst.

Die Funktion wp_mail() in WordPress ist das grundlegende Werkzeug für den E-Mail-Versand innerhalb des WordPress-Ökosystems. Sie ähnelt der Funktion mail() von PHP, ist jedoch speziell auf WordPress zugeschnitten und bietet eine einfachere Integration mit WordPress-spezifischen Features und Plugins.

Grundlegend ist allerdings, dass deine Mails mit SPF und auch anderen DNS Einträgen versehen sind – aber das ist bei SMPT Versand nicht anders.

Ein typischer SPF sieht so aus und wird in der Regel als TXT-Eintrag in deine DNS Einstellungen hinzugefügt:

v=spf1 ip4:192.168.0.1 include:example.com -all

SPF – Erklärung der Komponenten

  • v=spf1: Dies ist die Versionsangabe des SPF-Protokolls. spf1 zeigt an, dass es sich um SPF Version 1 handelt, die aktuell genutzte Version.
  • ip4:192.168.0.1: Dies gibt an, dass E-Mails, die von der IP-Adresse 192.168.0.1 gesendet werden, als legitim angesehen werden sollen. Es können auch IP-Bereiche angegeben werden, z. B. ip4:192.168.0.0/24.
  • include:example.com: Dieser Teil des Eintrags schließt die SPF-Einträge einer anderen Domain (example.com) in die Überprüfung mit ein. Das bedeutet, dass auch die dort definierten Server als berechtigte Absender für die Domain gelten.
  • -all: Das -all am Ende des SPF-Eintrags definiert eine strenge Policy. Es bedeutet, dass E-Mails, die nicht mit den vorherigen Angaben übereinstimmen, strikt abgelehnt werden sollen (Fail). Andere Optionen sind ~all für eine weiche Ablehnung (SoftFail, was bedeutet, dass die Nachrichten normalerweise angenommen, aber als verdächtig markiert werden) und ?all für eine neutrale Behandlung, die keine spezifische Empfehlung ausspricht.

Diese Einträge sind wichtig, da Anbieter wie Google und Co. sagen, dass Emails heute authentifiziert werden müssen, entweder durch DKIM oder durch SPF Records.

Emailzustellung verbessern in WordPress

Um die Zustellbarkeit von Emails langfristig zu gewährleisten wird zum einen ein vernünftiger “Return Path” nötig sein.

Der “Return-Path” wird verwendet, um anzugeben, wohin Antworten auf die E-Mail gesendet werden sollen, insbesondere im Falle von Zustellfehlern.

Bei WordPress Subdomains sieht man allerdings oft, dass Mails folgenden Return Path haben:

[email protected]

In WordPress, insbesondere wenn es auf einer Subdomain läuft, wird der “Return-Path” für ausgehende E-Mails nicht automatisch speziell für Subdomains angepasst. Der “Return-Path” wird typischerweise vom E-Mail-Server oder der PHP-Mail-Konfiguration, die WordPress zum Versenden von E-Mails verwendet, bestimmt.

Wenn deine WordPress-Site auf einer Subdomain läuft und du spezifische Anforderungen an den “Return-Path” hast (z.B. für verbessertes Bounce Management oder Spam-Vermeidung), ist es ratsam, diesen explizit zu setzen, entweder durch Serverkonfiguration, ein spezialisiertes Plugin oder Code-Anpassungen. Dies stellt sicher, dass du volle Kontrolle über die E-Mail-Funktionalitäten hast und verbessert die Zustellbarkeit und das Handling von Antwort-E-Mails.

Anbei findest du ein paar Code Snippets, die dir helfen, deine Emailzustellbarket mit wp_mail() zu erhöhen. Dabei kannst du dann auf zusätzliuche Plugins verzichten.

Anpassen des Return Paths

Der folgende Code passt deinen Return Path an.

class email_return_path {
   function __construct() {
        add_action( 'phpmailer_init', array( $this, 'fix' ) );
   }

    function fix( $phpmailer ) {
        $phpmailer->Sender = $phpmailer->From;
    }
}

new email_return_path();

DKIM Signing

Da du entweder SPF oder DKIM Authentifizierung benötigst, lassen wir WordPress jede ausgehende Mail signieren.

Dazu nutzen wir das folgende Snippet:

class email_customizations {
    function __construct() {
        add_action('phpmailer_init', array($this, 'setup_mail'));
    }

    function setup_mail($phpmailer) {
        $phpmailer->Sender = $phpmailer->From; // Set Sender to From
        $phpmailer->DKIM_domain = 'chris-martens.com'; // Deine Domain
        $phpmailer->DKIM_private = '/path/to/your/dkim_wp/dkim_private.key'; 
        $phpmailer->DKIM_selector = 'mail'; // Dein DKIM-Selektor, abhängig von DNS
        $phpmailer->DKIM_identity = $phpmailer->From;
    }
}

new email_customizations();

Was macht das Snippet?

DKIM Domain setzt die Domain für den Schlüssel.

DKIM private sagt wp_mail(), wo der Private Key ist. Den Private Key müssen wir einmal anlegen. Ich zeige dir das gleich im nächsten Abschnitt.

DKIM Selektor sagt, welchen Selektor wir auswählen müssen für den Versand. Es gibt manchmal mehrere DKIM Selektoren in deiner DNS, und beim Versand der Mail wird der Selektor zugewiesen.

Einen DKIM erstellen

Wir verbinden uns mit unserem Server via SSH.

Dann gehen wir zu unserem WordPress Verzeichnis:

// Gehe zum WP Verzeichnis
cd /var/www/html/domain.tld/

// Erstelle und betrete ein neues Verzeichnis - nutze sudo -u -- als Nutzer von WP
sudo -u USER -- mkdir wp_dkim && cd wp_dkim

// Erstelle den privaten und den öffentlichen Schlüssel
sudo -u USER -- openssl genrsa -out dkim_private.key 2048
sudo -u USER -- openssl rsa -in dkim_private.key -pubout -out dkim_public.key

Da ich den Befehl jeweils mit sudo -u USER (User ist hier dein Unix User für deine Installation) nutze, wird gleichzeitig mit der Erstellung auch der User und seine Gruppe gesetzt, so dass WP auf jeden Fall auf die Dateien zugreifen kann.

Jetzt muss ich noch den Public Key als DNS Eintrag veröffentlichen.

"v=DKIM1; h=sha256; k=rsa; p=HIER KOMMT DEIN CODE REIN MIIBIj......."

Dazu hole ich mir den Inhalt des öffentlichen Schlüssels und entferne jeden Zeilenumbruch und jedes Leerzeichen:

cat dkim_public.key

Die Ausgabe sieht dann etwa so aus:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq0g3nrsKCdW58VWS27ZX
rHBIafE64v2Yex3P/9njGd4jKc7JF0pRUEnPsuBorVtLRz/y2rhgo7hFaDeZqqQB
R2RsqyrTHhS+duUYk0nZO9zrQg9PToV6R3ok2RdtzOYbYUz6Mjvh7UVNsKc33gUT
r6vOpWMpEQKjcEgJOwRLJuikC82x7dDZqXIggw2Er22qp7QrqeWj053m7YHoL3yH
6CJ+Zehxs+LJLd+aP2hmL9dEKqDPNgVjp0nS0f4YVObQfjw9kNohoGVZwUZPeTXa
rRh/gzFTXMgM0lj+OqH8TZxw19twe/qNYDhoj2vQBSlY02drz/KjbzBsCH4zxw/m
YQIDAQAB

Achtung: wir nutzen nur den Teil zwischen Begin Public Key und End Public Key, und wir schreiben alles in eine einzelne Zeile. Diese setzen wir dann in unseren DNS Eintrag.

Das Ergebnis sieht dann so aus:

"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq0g3nrsKCdW58VWS27ZXrHBIafE64v2Yex3P/9njGd4jKc7JF0pRUEnPsuBorVtLRz/y2rhgo7hFaDeZqqQBR2RsqyrTHhS+duUYk0nZO9zrQg9PToV6R3ok2RdtzOYbYUz6Mjvh7UVNsKc33gUTr6vOpWMpEQKjcEgJOwRLJuikC82x7dDZqXIggw2Er22qp7QrqeWj053m7YHoL3yH6CJ+Zehxs+LJLd+aP2hmL9dEKqDPNgVjp0nS0f4YVObQfjw9kNohoGVZwUZPeTXarRh/gzFTXMgM0lj+OqH8TZxw19twe/qNYDhoj2vQBSlY02drz/KjbzBsCH4zxw/mYQIDAQAB"

In unserem Code haben wir den Selektor mail ausgewählt, also veröffentlichen wir einen TXT EIntrag in unserem DNS mit mail._domainkey.domain.tld.

Dazu brauchst du noch einen DMarc Record und dann ist deinem Mailing fast nichts mehr im Wege. ElasticMail hat einen kostenlosen DMarc Generator

Name: _dmarc(or_dmarc.yourdomain)

Type: TXT

Value: v=DMARC1;p=none;pct=100;aspf=r;adkim=r;

Absender anpassen

Zum Schluss wollen wir noch den Absender anpassen und damit die Emails personalisieren.

// Ändern der Absender-E-Mail und des Namens
add_filter('wp_mail_from', function ($original_email_address) {
    return '[email protected]';
});

add_filter('wp_mail_from_name', function ($original_email_from) {
    return 'Chris | Chris Martens GmbH';
});

Der komplette Code

Du kannst den kompletten Code als Snippet nutzen, entweder in deinem eigenen Plugin oder in einem Snippet Plugin wie WPCodeBox (*) oder Fluent Snippets.

<?php 

class email_return_path {
   function __construct() {
        add_action( 'phpmailer_init', array( $this, 'fix' ) );
   }

    function fix( $phpmailer ) {
        $phpmailer->Sender = $phpmailer->From;
    }
}

new email_return_path();


class email_customizations {
    function __construct() {
        add_action('phpmailer_init', array($this, 'setup_mail'));
    }

    function setup_mail($phpmailer) {
        $phpmailer->Sender = $phpmailer->From; // Set Sender to From
        $phpmailer->DKIM_domain = 'chris-martens.com'; // Deine Domain
        $phpmailer->DKIM_private = '/path/to/your/dkim_wp/dkim_private.key'; // Pfad zum privaten Schlüssel
        $phpmailer->DKIM_selector = 'mail'; // Dein DKIM-Selektor, abhängig von DNS
        $phpmailer->DKIM_identity = $phpmailer->From;
    }
}

new email_customizations();

// Ändern der Absender-E-Mail und des Namens
add_filter('wp_mail_from', function ($original_email_address) {
    return '[email protected]';
});

add_filter('wp_mail_from_name', function ($original_email_from) {
    return 'Chris | Chris Martens GmbH';
});

Was noch wichtig ist

Du kannst den Schlüssel für DKIM auch manuell zum Beispiel mit dem Terminal oder Putty generieren, wenn du keinen Zugriff auf deinen Server mit SSH hast.

Wichtig ist, dass wir bei der Erstellung des Schlüsselpaares den Ordner wp_dkim angelegt habe – ABER ACHTUNG diesen Ordner habe ich in dem Code erstellt in einem Verzeichnis OBERHALB des public_html Verzeichnisses. Du kannst das auch in einen anderen Ordner legen, wichtig ist nur, dass das Schlüsselpaar nicht von außen erreichbar ist.

Im folgenden siehst du eine mögliche Struktur.

// Pfad zu deinem Webfolder

docRoot
|
|-- public_hmtl
|       |
|       |-- wp-admin
|       |-- wp-content
|       |-- wp-includes
|       |-- index.php
|       |-- .htaccess
|       |-- ...usw
| 
|-- wp-config.php
|      
|-- logs
|       |
|       |-- error.log
|       |-- access.log
|
|-- wp_dkim
        |
        |-- dkim_private.key
        |--dkim_public.key

Der Private Key sollte unbedingt durch Zugriffe von außen geschützt sein.

Im oben genannten Beispiel siehst du auch, dass die wp-config.php nicht im public_html deiner WP Installation ist – keine Sorge, das funktioniert auch und es erhöht die Sicherheit.

Was sollte jetzt möglich sein?

E-Mail-Nachrichten, wie zum Beispiel beim Zurücksetzen von Passwörtern oder auch andere WordPress-E-Mails aus deiner WordPress Installation wie zum Beispeil Zugangsdaten sollten jetzt ohne Fehlermeldung im E-Mail-Postfach bei deinen Empfängern ankommen.

Gleichzeitig brauchst du kein zusätzliches Plugin installieren für den Versand von E-Mails. E-Mails über WordPress kommen jetzt im Postfach an, anstatt im Spam-Ordner zu landen.

Wenn du Fragen hast, hinterlasse gerne einen Kommentar oder schreib mir eine Mail.

WP Security Settings - Anleitung

Trag dich ein und lade dir dein Handbuch zum Thema WordPress Sicherheit herunter.

Das Handbuch wird permanent aktualisiert und steht dir gleich als Download zur Verfügung.

* Trag einfach deine E-Mail-Adresse ein, und schon bist du dabei! Wir freuen uns, dich mit den neuesten Updates zum Thema WordPress Sicherheit direkt in deinem Posteingang zu begrüßen.

(*) Links mit Sternchen (*) sind Affiliate-Links. Wenn du über diese Links einkaufst, bekommen wir von dem betreffenden Anbieter eine Provision. Für dich verändert sich der Preis nicht.

Related posts

Sie sitzen um einen großen Tisch herum, jeder Freund mit einem Notizblock und einem Stift, und diskutieren und bewerten verschiedene Lösungen und Optionen für ihren ersten Einsatz in WordPress Sicherheit.

WordPress Sicherheit

Reading Time: 14:35 min

Vielleicht hast du auch das Gefühl, dass du hinter der Sicherheit deiner WordPress Installation gar nicht mehr so richtig hinterher kommst? Machst du auch jeden Tah Updates und denkst dir…

View post
Warum du verlassene Plugins vermeiden solltest - Frau spricht am Telefon

Warum du verlassene Plugins vermeiden solltest

Reading Time: 7:5 min

In letzter Zeit ist das Problem der nicht mehr genutzten WordPress-Plugins und -themes immer wieder aufgetaucht. Da etwa 30 % der gemeldeten Sicherheitslücken in Plugins nicht gepatcht werden, haben sich…

View post
Desktop View, Frau am Arbeiten - Cyberpanel Absicherung

CyberPanel absichern

Reading Time: 1:11 min

Kleiner Reminder – wenn du CyberPanel nutzt und deine Installation absichern willst, ein Hinweis, der nicht offensichtich ist. Ich bin erst darüber gestolpert, als ich mich vertippt habe – und…

View post

Hinterlasse den ersten Kommentar