2mail — SMTP-Relay aus belgischer Infrastruktur

SMTP für Python — die Post Ihres Skripts oder Ihrer Django-App, die ankommt

Python bringt SMTP mit: Mit smtplib senden Sie eine Nachricht in wenigen Zeilen, und Django fasst das in einer eigenen Mail-Schicht mit EMAIL-Einstellungen zusammen. Was keines von beiden liefert, ist die Zustellbarkeit — die hängt vom Server ab, über den Sie senden.

Ob Sie ein eigenständiges Skript, eine Flask-App oder ein Django-Projekt haben: Die Einstellungen sind dieselben fünf Daten. Sie richten sie auf Ihr Relay, und der Code, der die Nachrichten baut, bleibt unverändert.

Warum es ohne Relay schiefgeht

Python-Post kommt oft aus dem Hintergrund: ein nächtlicher Bericht, ein Cron-Job, der Rechnungen versendet, ein Skript, das alarmiert, wenn ein Messwert aus dem Toleranzbereich fällt. Niemand schaut zu — und deshalb merkt niemand, dass der empfangende Server sie still abweist. Bei Django kommt die klassische Go-live-Überraschung hinzu: In der Entwicklung geht alles an die Konsole, in der Produktion an echte Anbieter, die Reputation sehr wohl prüfen.

SMTP in Python einrichten

1

Zugangsdaten abrufen

Melden Sie sich in Ihrem 2mail-Konto an und rufen Sie dort Ihren SMTP-Server, Benutzernamen und Ihr Passwort ab.

2

In Python eintragen

In einem Django-Projekt legen Sie die EMAIL-Einstellungen in den Settings fest: das SMTP-Backend als E-Mail-Backend, den Host des Relays, Port 587, die STARTTLS-Option aktiviert, Benutzername und Passwort sowie eine Standard-Absenderadresse auf Ihrer eigenen Domain. Wenn Sie direkt mit smtplib arbeiten, verbinden Sie sich mit dem Host auf Port 587, rufen starttls auf, melden sich mit Benutzername und Passwort an und senden dann die Nachricht. In beiden Fällen lesen Sie die Daten aus Umgebungsvariablen, nicht aus dem Code.

3

Domain authentifizieren

Sorgen Sie dafür, dass SPF, DKIM und DMARC für Ihre Domain korrekt gesetzt sind, damit Empfänger verifizieren können, dass die Mail von Ihnen stammt.

4

Testen

Senden Sie von Ihrer Plattform aus eine Testnachricht an eine Adresse bei einem großen Provider und prüfen Sie, ob sie im Posteingang ankommt und nicht im Spam-Ordner.

Die Felder, die Python abfragt

Jede Plattform nennt sie etwas anders, aber es geht immer um dieselben fünf. Die konkreten Werte sind kontogebunden und finden Sie in Ihrem 2mail-Konto — rufen Sie sie dort ab, damit Sie sicher die richtigen verwenden.

Feld Was Sie eintragen
SMTP-Server (Host)Der Servername aus Ihrem 2mail-Konto.
PortDer Port, der zu Ihrer gewählten Verschlüsselung gehört; Ihr Konto zeigt, welcher.
VerschlüsselungTLS. Senden Sie nie unverschlüsselt — sonst gehen Ihre Zugangsdaten lesbar über die Leitung.
BenutzernameDer SMTP-Login Ihres 2mail-Kontos.
PasswortDas zugehörige Passwort. Verwenden Sie nie das Passwort eines Mitarbeiterpostfachs.

SMTP-Konfiguration für Python im Code

Funktionierende Beispiele für Port 587 mit STARTTLS, direkt zum Übernehmen. Ersetzen Sie die Absenderadresse durch eine Adresse auf Ihrer eigenen Domain und prüfen Sie Servername und Login in Ihrem 2mail-Konto. Das Passwort gehört in eine Umgebungsvariable — nie in den Code und nie in die Versionsverwaltung.

smtplib: Verbindung auf 587 mit starttls()

Die Standardbibliothek genügt. Die Reihenfolge zählt: zuerst starttls(), erst dann login() — sonst geht Ihr Passwort unverschlüsselt über die Leitung, oder das Relay lehnt die Anmeldung ab. Verwenden Sie smtplib.SMTP und nicht SMTP_SSL: Letzteres gehört zu Port 465. Benutzername und Passwort kommen aus Umgebungsvariablen.

import os
import smtplib
import ssl
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "Example <noreply@example.com>"
msg["To"] = "you@example.org"
msg["Subject"] = "SMTP test"
msg.set_content("Sent through the 2mail SMTP relay.")

context = ssl.create_default_context()

with smtplib.SMTP("relay.2mail.eu", 587, timeout=10) as server:
    server.starttls(context=context)  # upgrade to TLS first, log in afterwards
    server.login(os.environ["SMTP_USERNAME"], os.environ["SMTP_PASSWORD"])
    server.send_message(msg)          # call again for the next message, same connection

Django: die EMAIL_*-Settings

Django braucht kein zusätzliches Paket. Legen Sie das SMTP-Backend ausdrücklich fest: In der Entwicklung steht es oft auf dem Konsolen-Backend, und dann versendet die Produktion nichts, während alles zu funktionieren scheint. sendtestemail ist ein eingebauter Management-Befehl, mit dem Sie die Einstellungen prüfen, ohne eine View oder einen Task aufrufen zu müssen.

# settings.py
import os

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "relay.2mail.eu"
EMAIL_PORT = 587
EMAIL_USE_TLS = True   # STARTTLS - never together with EMAIL_USE_SSL
EMAIL_HOST_USER = os.environ["SMTP_USERNAME"]
EMAIL_HOST_PASSWORD = os.environ["SMTP_PASSWORD"]
EMAIL_TIMEOUT = 10
DEFAULT_FROM_EMAIL = "Example <noreply@example.com>"
SERVER_EMAIL = "noreply@example.com"   # sender of error reports to ADMINS

# Test from the shell:
#   python manage.py sendtestemail you@example.org

Flask-Mail: dieselben fünf Daten

Wenn Sie mit Flask arbeiten, fragt Flask-Mail dieselben Daten unter anderen Namen ab. Auch hier gilt: MAIL_USE_TLS für Port 587, und MAIL_USE_SSL bleibt aus.

import os
from flask import Flask
from flask_mail import Mail

app = Flask(__name__)
app.config.update(
    MAIL_SERVER="relay.2mail.eu",
    MAIL_PORT=587,
    MAIL_USE_TLS=True,    # STARTTLS
    MAIL_USE_SSL=False,
    MAIL_USERNAME=os.environ["SMTP_USERNAME"],
    MAIL_PASSWORD=os.environ["SMTP_PASSWORD"],
    MAIL_DEFAULT_SENDER="noreply@example.com",
)
mail = Mail(app)

Welche Mails Python sendet

Sobald das Relay eingerichtet ist, laufen diese alle über 2mail — Sie müssen sie nicht einzeln konfigurieren.

Passwort-Zurücksetzen und Adressverifizierung aus Django
Geplante Berichte und Exporte aus Cron-Jobs
Alarme aus Monitoring- und Datenverarbeitungsskripten
Rechnungen und Bestätigungen aus einer Webanwendung
Fehlerberichte an die Administratoren

Stolperfallen bei Python

TLS-Option und Port müssen zusammenpassen

Django kennt zwei getrennte TLS-Einstellungen: eine für STARTTLS und eine für TLS von Anfang an. Aktivieren Sie nur die für STARTTLS, die zu Port 587 passt. Beide zugleich führen zu einem Konfigurationsfehler; keine von beiden sendet Ihre Zugangsdaten im Klartext, was ein Relay zu Recht ablehnt.

Eine Verbindung pro Serie, nicht pro Nachricht

Ein Skript, das für jede von tausend Nachrichten eine neue SMTP-Verbindung öffnet, verhält sich wie ein Angreifer. Öffnen Sie eine Verbindung, senden Sie die Serie, schließen Sie. Django hat dafür eine Funktion, die mehrere Nachrichten über eine einzige Verbindung sendet.

Stille Fehler in Hintergrundaufgaben

Eine Exception in einem Cron-Job verschwindet in einer Logdatei, die niemand liest. Fangen Sie Versandfehler ab und melden Sie sie dort, wo sie gesehen werden — und binden Sie die Webhooks von 2mail für Zustellung und Bounces an, damit Sie auch sehen, was nach der Übergabe scheitert.

Häufige Fehlermeldungen bei Python

Die Meldungen, die Sie sehen, wenn Host, Port, Verschlüsselung oder Login nicht stimmen — im Wortlaut, damit Sie sie in Ihrem Log wiedererkennen, mit Ursache und Lösung daneben.

Meldung Ursache Lösung
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Error: authentication failed: …') Das Relay lehnt die Anmeldung ab: ein falscher Benutzername oder ein falsches Passwort, oder eine Umgebungsvariable, die im Cron- oder Service-Kontext einen anderen Wert hat als in Ihrer Shell. Geben Sie aus, was der Prozess tatsächlich liest (den Benutzernamen, nie das Passwort), und verwenden Sie den SMTP-Login aus Ihrem 2mail-Konto — nicht das Passwort eines Postfachs.
smtplib.SMTPNotSupportedError: SMTP AUTH extension not supported by server. login() wird vor starttls() aufgerufen. Ein Relay bietet die Anmeldung erst an, sobald die Verbindung verschlüsselt ist; auf der noch unverschlüsselten Verbindung gibt es AUTH also nicht. Rufen Sie zuerst server.starttls(context=context) auf und erst dann server.login(…). In Django: Setzen Sie EMAIL_USE_TLS = True.
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:…) Der Code verwendet smtplib.SMTP_SSL (oder in Django EMAIL_USE_SSL) auf Port 587. Python beginnt dann sofort mit einem TLS-Handshake, während das Relay auf diesem Port zuerst gewöhnliches SMTP erwartet und erst nach STARTTLS umschaltet. Die klassische Verwechslung von 465 und 587. Verwenden Sie smtplib.SMTP(…, 587) gefolgt von starttls(), oder in Django EMAIL_USE_TLS = True mit Port 587.
smtplib.SMTPServerDisconnected: Connection unexpectedly closed Die Verbindung ist vor oder während des Dialogs abgebrochen. Meist ein Skript, das eine Verbindung offen hält und sie nach einer langen Pause wiederverwendet, während der Server sie inzwischen wegen Inaktivität geschlossen hat — oder eine gewöhnliche SMTP-Verbindung zu einem Port, der TLS ab dem ersten Byte erwartet. Öffnen Sie eine Verbindung pro Serie von Nachrichten und schließen Sie sie danach; fangen Sie die Exception ab und verbinden Sie sich neu. Prüfen Sie, dass Sie Port 587 mit starttls() verwenden.
ValueError: EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set one of those settings to True. In den Django-Settings sind beide TLS-Optionen aktiviert — oft, weil eine davon aus einer gemeinsamen Basisdatei stammt und die andere aus den Produktions-Settings. Lassen Sie nur EMAIL_USE_TLS = True stehen und setzen Sie EMAIL_USE_SSL = False.
SPF, DKIM & DMARC erklärt Über Zustellbarkeit

Andere Plattform?

SMTP ist ein Standardprotokoll: Jedes System, das SMTP spricht — ein CRM, ein ERP, eine eigene Anwendung oder ein Server —, kann über 2mail mit denselben fünf Feldern senden.

Häufige Fragen zu SMTP für Python

smtplib und Django versenden, liefern aber keine Zustellbarkeit: Die hängt vom Server ab, über den Sie senden. Eine lokale Mailfunktion oder ein frischer Server hat weder Authentifizierung noch Reputation. Ein SMTP-Relay mit korrekten SPF-, DKIM- und DMARC-Einträgen löst das.
Das SMTP-Backend als E-Mail-Backend, den Host des Relays, Port 587, die STARTTLS-Option aktiviert, Ihren Benutzernamen und Ihr Passwort sowie eine Standard-Absenderadresse auf Ihrer eigenen Domain. Bewahren Sie die Zugangsdaten in Umgebungsvariablen auf, nicht in den Settings selbst.
Verbinden Sie sich mit dem Host auf Port 587, rufen Sie starttls auf, melden Sie sich mit Benutzername und Passwort an und senden Sie die Nachricht. Nutzen Sie für mehrere Nachrichten dieselbe Verbindung, statt pro Nachricht eine neue zu öffnen.
In Ihrem 2mail-Konto, pro Anwendung. Sie sind kontogebunden, deshalb veröffentlichen wir sie nicht auf der Website. Legen Sie pro Skript oder Anwendung am besten eigene Zugangsdaten an, damit Sie sie separat widerrufen und den Verkehr getrennt verfolgen können.
Jetzt anrufen
E-Mail senden