Files
SMTPGraphRelay/README.md
T

14 KiB

SMTPGraphRelay

SMTPGraphRelay ist ein nativer Windows-SMTP-Relay für interne Geräte und Anwendungen.

Er nimmt klassische SMTP-Mails von Druckern, Scannern, NAS-Systemen, Servern, Monitoring-Tools und anderen Legacy-Geräten entgegen und versendet sie anschließend über Microsoft Graph mit App-only OAuth2 über Microsoft 365.

Der Relay läuft vollständig unter Windows PowerShell 5.1 und benötigt keinen Docker-Container, keinen lokalen Exchange-Server und keinen klassischen SMTP-Smarthost.


Überblick

Drucker / Scanner / NAS / Server / Monitoring
                    |
                    | SMTP
                    v
             SMTPGraphRelay
                    |
                    | Store-and-Forward Queue
                    v
             Microsoft Graph
                    |
                    | OAuth2 App-only
                    v
              Microsoft 365

SMTPGraphRelay wurde für den Betrieb in internen Netzwerken entwickelt.


Installation

Schnellinstallation

Auf dem Zielsystem Windows PowerShell 5.1 als Administrator öffnen und ausführen:

$u='https://me-gitea.maieredv.cloud/MAIEREDV/SMTPGraphRelay/raw/branch/main/Setup-SMTPGraphRelay.ps1';$f="$env:TEMP\Setup-SMTPGraphRelay.ps1";Invoke-WebRequest $u -UseBasicParsing -OutFile $f;& $f

Der Bootstrap-Installer lädt automatisch den aktuellen Stand aus dem Gitea-Repository und installiert SMTPGraphRelay nach:

C:\Program Files\SMTPGraphRelay

Es muss kein ZIP manuell heruntergeladen oder entpackt werden.


Setup / Manager

Nach dem Start erscheint das Verwaltungsmenü:

[1] Neuinstallation aus Gitea
[2] Installation aus Gitea reparieren
[3] Nach Online-Updates suchen
[4] Entra / Exchange RBAC prüfen
[5] Zertifikat erneuern
[6] Health Check ausführen
[7] Deinstallieren
[8] Status anzeigen
[9] SMTP-AUTH verwalten
[10] Failed Queue verwalten
[11] Failure-Mode QA
[0] Beenden

Neuinstallation

Die Neuinstallation erledigt automatisch:

  • Prüfung auf Windows PowerShell 5.1
  • Prüfung auf Administratorrechte
  • Download der aktuellen Programmdateien aus Gitea
  • Installation nach C:\Program Files\SMTPGraphRelay
  • Installation der benötigten Microsoft-Graph-PowerShell-Module
  • Installation von ExchangeOnlineManagement
  • Erstellung eines lokalen Zertifikats
  • Erstellung der Entra ID App Registration
  • Erstellung des Entra Service Principals
  • Einrichtung von Exchange Online Application RBAC
  • Beschränkung von Application Mail.Send auf das konfigurierte Absenderpostfach
  • Erstellung der config.json
  • Erstellung der Queue-/Failed-/Log-Verzeichnisse
  • Erstellung der Windows-Firewallregel
  • Erstellung des Scheduled Tasks unter SYSTEM
  • Start des Relay
  • abschließender Health Check

Microsoft 365 / Graph

SMTPGraphRelay verwendet Microsoft Graph mit App-only Authentifizierung.

Der Versand erfolgt über:

POST /v1.0/users/<SenderMailbox>/sendMail

Die Authentifizierung erfolgt mit:

Tenant ID
Client ID
Certificate Thumbprint

Es wird kein Client Secret verwendet.


Exchange Application RBAC

Der Relay verwendet bewusst keine tenantweite Microsoft Graph Mail.Send Application Permission.

Stattdessen wird Exchange Online Application RBAC verwendet:

Application Mail.Send
        |
        v
Custom Resource Scope
        |
        v
konfiguriertes SenderMailbox

Beispiel:

SMTPGraphRelay App
        |
        | Application Mail.Send
        v
info@example.com

Dadurch kann die Anwendung ausschließlich über das konfigurierte Absenderpostfach senden.


Zertifikatsauthentifizierung

Das Setup erzeugt ein RSA-Zertifikat unter:

Cert:\LocalMachine\My

Eigenschaften:

RSA 2048
SHA256
Private Key nicht exportierbar
Gültigkeit: 2 Jahre

Der Relay überwacht die Zertifikatslaufzeit regelmäßig.

Standard:

Warnung:   60 Tage
Kritisch:  14 Tage
Prüfung:   alle 12 Stunden

Das Zertifikat kann über den Manager erneuert werden:

[5] Zertifikat erneuern

Die Rotation erfolgt mit Überlappung:

altes Zertifikat
        |
        v
neues Zertifikat erstellen
        |
        v
neues Credential zusätzlich in Entra hinterlegen
        |
        v
App-only Login mit neuem Zertifikat testen
        |
        v
config.json auf neues Zertifikat umstellen
        |
        v
Relay neu starten
        |
        v
altes Zertifikat optional entfernen

SMTP-Funktionen

Unterstützte SMTP-Kommandos:

EHLO
HELO
MAIL FROM
RCPT TO
DATA
RSET
NOOP
QUIT
AUTH LOGIN
AUTH PLAIN

STARTTLS wird bewusst nicht verwendet, da SMTPGraphRelay für interne, vertrauenswürdige Netzwerke vorgesehen ist.


SMTP Listener

Standardmäßig:

ListenAddress: 0.0.0.0
Port:          2525

Der Port kann in config.json geändert werden.


IP-Allowlist

SMTPGraphRelay akzeptiert ausschließlich Clients aus konfigurierten Netzwerken.

Beispiel:

"AllowedNetworks": [
  "127.0.0.1/32",
  "10.0.0.0/8",
  "172.16.0.0/12",
  "192.168.0.0/16"
]

Nicht erlaubte Hosts erhalten:

554 5.7.1 Client not allowed

Die IP-Allowlist bleibt auch bei aktiviertem SMTP-AUTH immer die erste Zugriffskontrolle.


SMTP-AUTH

SMTPGraphRelay unterstützt:

AUTH LOGIN
AUTH PLAIN

SMTP-AUTH kann optional oder verpflichtend aktiviert werden.

Beispiel:

"RequireAuth": true

Clients ohne erfolgreiche Authentifizierung erhalten dann:

530 5.7.0 Authentication required

Erfolgreiche Anmeldung:

235 2.7.0 Authentication successful

Fehlgeschlagene Anmeldung:

535 5.7.8 Authentication credentials invalid

Nach mehreren Fehlversuchen kann die Verbindung temporär gesperrt werden:

454 4.7.0 Too many authentication failures

Standard:

AuthMaxFailures = 5

SMTP-Benutzerverwaltung

Im Manager:

[9] SMTP-AUTH verwalten

Funktionen:

[1] SMTP-AUTH erforderlich EIN/AUS
[2] Benutzer hinzufügen
[3] Benutzer anzeigen
[4] Passwort ändern
[5] Benutzer löschen
[6] Netze ohne Auth verwalten
[7] Max. Fehlversuche ändern
[0] Zurück

Passwörter werden nicht im Klartext gespeichert.

Verwendet wird:

PBKDF2-HMAC-SHA256
zufälliger Salt
150000 Iterationen
32 Byte Hash

AUTH-Ausnahmen

Bestimmte Netze können trotz RequireAuth=true ohne SMTP-AUTH zugelassen werden:

"AllowUnauthenticatedNetworks": [
  "10.60.10.0/24"
]

Diese Clients müssen trotzdem zusätzlich in AllowedNetworks enthalten sein.


Absenderkontrolle

Der SMTP-Benutzer beeinflusst nicht den tatsächlichen Microsoft-365-Absender.

Mit:

"ForceSender": true

wird immer Graph.SenderMailbox als Absender verwendet.


Parallele SMTP-Verbindungen

SMTPGraphRelay verarbeitet mehrere SMTP-Clients parallel über einen PowerShell-Runspace-Pool.

Standard:

MaxConcurrentClients = 20

Ist das Limit erreicht:

421 4.3.2 SMTPGraphRelay busy, try again later

SMTP-Limits

Standardwerte:

MaxRecipients             = 50
MaxMessagesPerConnection  = 25
MaxMessageSizeMB          = 25

Zu viele Empfänger:

452 4.5.3 Too many recipients

Zu viele Nachrichten innerhalb einer Verbindung:

452 4.5.3 Too many messages in this session

Zu große Nachricht:

552 5.3.4 Message size exceeds fixed maximum message size

Store-and-Forward Queue

Queue-Struktur:

queue\
├── incoming\
├── pending\
└── processing\

failed\
  • incoming: Nachricht wird atomar geschrieben.
  • pending: vollständig gespeicherte, versandbereite Nachrichten.
  • processing: aktuell durch den Graph-Worker verarbeitete Nachrichten.
  • failed: dauerhaft fehlgeschlagene Nachrichten.

Queue-ID

Jede Nachricht erhält eine eindeutige Queue-ID.

Beispiel:

7F3A91C2D441

SMTP-Antwort:

250 2.0.0 Message accepted for delivery; queue-id=7F3A91C2D441

Die Queue-ID wird ebenfalls in den Logs verwendet.


Received-Header und Message-ID

SMTPGraphRelay fügt einen eigenen Received:-Header hinzu.

Besitzt eine eingehende Nachricht keine Message-ID, erzeugt der Relay automatisch eine.

Bereits vorhandene Message-IDs bleiben unverändert.


Retry-Logik

Standard-Retry-Zeiten:

1 Minute
5 Minuten
15 Minuten
30 Minuten
60 Minuten
120 Minuten
240 Minuten
480 Minuten

Standard:

MaxRetries = 8

Automatische Wiederholung erfolgt bei:

HTTP 408
HTTP 429
HTTP 5xx
DNS-Fehler
TLS-/Transportfehler
Timeouts
Netzwerkfehler

Bei 429 Too Many Requests wird Retry-After berücksichtigt.

Typische permanente Fehler wie 400, 401, 403, 404, 409, 410, 412, 413, 415, 422 und 423 werden direkt nach failed verschoben.


Queue-Backpressure

Standard:

MaxPendingMessages = 5000
MinFreeDiskSpaceMB = 1024

Queue-Limit erreicht:

452 4.3.1 SMTPGraphRelay queue limit reached

Zu wenig freier Speicher:

452 4.3.1 Insufficient system storage

Kann eine Nachricht nach DATA nicht atomar gespeichert werden:

451 4.3.0 SMTPGraphRelay queue temporarily unavailable

Failed Queue

Im Manager:

[10] Failed Queue verwalten

Funktionen:

[1] Failed Queue anzeigen
[2] Details einer Mail anzeigen
[3] Eine Mail erneut zustellen
[4] Alle Mails erneut zustellen
[5] Eine Mail endgültig löschen
[6] Alle Failed-Mails endgültig löschen
[0] Zurück

Beim erneuten Zustellen wird die Nachricht zurück nach queue\pending verschoben.


Graceful Shutdown

Update, Repair und kontrollierte Stop-Vorgänge beenden den Relay nicht sofort hart.

Der Manager erzeugt:

C:\Program Files\SMTPGraphRelay\shutdown.request

Der Relay schließt zuerst den Listener, nimmt keine neuen Verbindungen mehr an, lässt laufende SMTP-Sessions und den aktuellen Queue-/Graph-Versand auslaufen und beendet sich anschließend selbst.

Standard:

GracefulShutdownSeconds = 30

Bei Timeout fällt der Manager auf einen harten Scheduled-Task-Stop zurück.


Logging

Logdatei:

C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log

Log-Rotation:

MaxFileSizeMB = 10
RetentionDays = 30
CleanupHours  = 12

Archivierte Logs:

SMTPGraphRelay-YYYYMMDD-HHMMSS.log

Health Check

Im Manager:

[6] Health Check ausführen

oder direkt:

.\Test-SMTPGraphRelay.ps1

Geprüft werden unter anderem:

  • Windows PowerShell 5.1
  • Administratorstatus
  • config.json
  • Graph-PowerShell-Modul
  • Zertifikat und Private Key
  • Zertifikatslaufzeit
  • Queue-Verzeichnisse und Schreibrechte
  • Pending / Processing / Failed Queue
  • Scheduled Task
  • SMTP Listener
  • Graph App-only Login
  • SMTP-AUTH-Konfiguration

Exitcodes:

0 = OK
1 = Warnung
2 = Fehler

SMTP-Testmail

.\Test-SMTPGraphRelay.ps1 `
    -SendTestMail `
    -TestRecipient "user@example.com"

Bei aktiviertem SMTP-AUTH:

.\Test-SMTPGraphRelay.ps1 `
    -SendTestMail `
    -TestRecipient "user@example.com" `
    -SmtpUsername "scanner01"

Das Passwort wird interaktiv und verdeckt abgefragt.


Online Update

Im Manager:

[3] Nach Online-Updates suchen

Der Manager prüft die version.json im Gitea-Repository und lädt bei einer neuen Version das aktuelle main.zip.

Vor dem Update werden die verwalteten Programmdateien gesichert.

Ablauf:

Versionsprüfung
    |
    v
Repository laden
    |
    v
Backup
    |
    v
Graceful Shutdown
    |
    v
Programmdateien aktualisieren
    |
    v
Relay starten
    |
    v
Health Check
    |
    +--> Fehler -> automatischer Rollback

Repair

Im Manager:

[2] Installation aus Gitea reparieren

Repair lädt den aktuellen Programmstand erneut aus Gitea und stellt fehlende oder beschädigte Programmdateien wieder her.

Dabei bleiben erhalten:

config.json
queue\
failed\
logs\
backup\
Zertifikat
Entra App Registration
Exchange Application RBAC

Failure-Mode QA

Im Manager:

[11] Failure-Mode QA

oder direkt:

.\Test-SMTPGraphRelay-FailureModes.ps1

Tests:

[1] Graph HTTP 429 / Retry testen
[2] Graph HTTP 500 / Retry testen
[3] Queue-Schreibfehler / SMTP 451 testen
[4] Pending-Queue-Backpressure / SMTP 452 testen
[5] Disk-Backpressure / SMTP 452 testen
[6] Graceful Shutdown während SMTP DATA testen
[7] Graceful Shutdown während Queue/Graph testen
[8] QA-/Debug-Block aus Config entfernen
[0] Beenden

Die ursprüngliche config.json wird vor jedem Test gesichert und anschließend automatisch wiederhergestellt.


Scheduled Task

SMTPGraphRelay läuft als Scheduled Task unter:

SYSTEM

Ausgeführt wird explizit:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

mit:

-NoLogo
-NoProfile
-ExecutionPolicy Bypass
-File "C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1"
-ConfigPath "C:\Program Files\SMTPGraphRelay\config.json"

Verzeichnisstruktur

C:\Program Files\SMTPGraphRelay\
│
├── SMTPGraphRelay.ps1
├── Setup-SMTPGraphRelay.ps1
├── Test-SMTPGraphRelay.ps1
├── Test-SMTPGraphRelay-FailureModes.ps1
├── Renew-SMTPGraphRelayCertificate.ps1
├── version.json
├── config.json
│
├── queue\
│   ├── incoming\
│   ├── pending\
│   └── processing\
│
├── failed\
├── logs\
└── backup\

Systemvoraussetzungen

  • Windows 10 / Windows 11 oder Windows Server
  • Windows PowerShell 5.1
  • lokale Administratorrechte für Installation und Verwaltung
  • Zugriff auf das Gitea-Repository
  • Internetzugang zu Microsoft Entra ID
  • Internetzugang zu Microsoft Graph
  • Internetzugang zu Exchange Online
  • Microsoft-365-/Exchange-Online-Postfach als Relay-Absender
  • Entra-/Exchange-Administratorkonto für die Ersteinrichtung

Repository

https://me-gitea.maieredv.cloud/MAIEREDV/SMTPGraphRelay

Betriebskonzept

SMTPGraphRelay ist für den internen Einsatz vorgesehen.

Empfohlene Absicherung:

interne Netzwerksegmente
        +
AllowedNetworks
        +
optional SMTP-AUTH
        +
ForceSender
        +
Exchange Application RBAC

Dadurch bleibt sowohl der lokale Zugriff als auch der tatsächliche Microsoft-365-Versand klar eingeschränkt.