From 70afda86bff1c26f7997e5f76769d6b2aeee2af4 Mon Sep 17 00:00:00 2001 From: "manuel.maier" Date: Fri, 14 Aug 2026 23:11:41 +0200 Subject: [PATCH] Dateien nach "/" hochladen --- README.md | 957 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 832 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index abe2f31..8c772a8 100644 --- a/README.md +++ b/README.md @@ -1,145 +1,58 @@ -# SMTPGraphRelay 1.8.0 +# SMTPGraphRelay -V1.8 ergänzt zwei Betriebsfunktionen: +SMTPGraphRelay ist ein nativer Windows-SMTP-Relay für interne Geräte und Anwendungen. -- Failed-Queue-Verwaltung im Setup-/Manager -- kooperativer Graceful Shutdown für Update, Repair und manuelles Stoppen über den Manager +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. -Alle Funktionen aus V1.7 bleiben erhalten, insbesondere SMTP AUTH LOGIN/PLAIN, -Queue-ID, Retry/Backpressure, Zertifikatsrotation, Health Check und Online-Update. +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. -## Installation +--- -**Windows PowerShell 5.1 als Administrator**: +## Überblick + +```text +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: ```powershell $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 ``` -## Failed Queue verwalten - -Im Manager: +Der Bootstrap-Installer lädt automatisch den aktuellen Stand aus dem Gitea-Repository und installiert SMTPGraphRelay nach: ```text -[10] Failed Queue verwalten +C:\Program Files\SMTPGraphRelay ``` -Untermenü: +Es muss kein ZIP manuell heruntergeladen oder entpackt werden. -```text -[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 -``` +--- -Die Übersicht zeigt u. a.: +# Setup / Manager -- Queue-ID -- Zeitpunkt -- RetryCount -- Envelope-From -- Empfänger -- letzten HTTP-/Graph-Status -- Größe - -In den Details steht zusätzlich die letzte Fehlermeldung und – falls vorhanden – -der SMTP-AUTH-Benutzer. - -### Requeue - -Beim erneuten Zustellen wird die `.eml` samt Metadaten von `failed` nach -`queue\pending` verschoben. - -Dabei werden: - -```text -RetryCount = 0 -NextAttemptUtc = jetzt -RequeuedUtc = jetzt -``` - -gesetzt. Die alte Fehlerbeschreibung bleibt in den Metadaten erhalten, bis ein -neuer Versandversuch sie aktualisiert. - -Der laufende Queue-Worker nimmt die Mail anschließend automatisch wieder auf. - -## Graceful Shutdown - -Update und Repair verwenden nicht mehr zuerst `Stop-ScheduledTask`. - -Stattdessen erstellt der Manager: - -```text -C:\Program Files\SMTPGraphRelay\shutdown.request -``` - -Der Relay erkennt das Signal kurzfristig und führt diesen Ablauf aus: - -```text -Shutdown angefordert - | - v -SMTP-Listener schließen - | - +--> keine neuen Verbindungen mehr - | - v -laufende SMTP-Sessions auslaufen lassen - | - v -Queue-/Graph-Worker beendet aktuellen Versand - | - +--> startet keine weitere Queue-Mail - | - v -Runspaces schließen - | - v -Graph-Verbindung trennen - | - v -Relay beendet sich selbst -``` - -Standard-Timeout: - -```json -"Smtp": { - "GracefulShutdownSeconds": 30 -} -``` - -Zulässiger Bereich: - -```text -5 bis 300 Sekunden -``` - -Wenn der Relay innerhalb dieses Zeitraums nicht selbst beendet ist, verwendet -der Manager als Fallback einen harten `Stop-ScheduledTask`. - -Beim nächsten Start wird ein eventuell altes `shutdown.request` vorsorglich -entfernt. - -## Warum das für Updates wichtig ist - -Ein Update/Repair kann damit nicht mehr unnötig mitten in: - -- einer SMTP-DATA-Übertragung -- einer aktiven SMTP-Session -- oder einem laufenden Graph-sendMail-Aufruf - -den Prozess beenden. - -Wenn ein Client oder Graph länger als das konfigurierte Grace-Timeout hängt, -wird nach Ablauf des Timeouts kontrolliert auf den bisherigen harten Stop -zurückgefallen. - -## Manager +Nach dem Start erscheint das Verwaltungsmenü: ```text [1] Neuinstallation aus Gitea @@ -152,5 +65,799 @@ zurückgefallen. [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: + +```text +POST /v1.0/users//sendMail +``` + +Die Authentifizierung erfolgt mit: + +```text +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: + +```text +Application Mail.Send + | + v +Custom Resource Scope + | + v +konfiguriertes SenderMailbox +``` + +Beispiel: + +```text +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: + +```text +Cert:\LocalMachine\My +``` + +Eigenschaften: + +```text +RSA 2048 +SHA256 +Private Key nicht exportierbar +Gültigkeit: 2 Jahre +``` + +Der Relay überwacht die Zertifikatslaufzeit regelmäßig. + +Standard: + +```text +Warnung: 60 Tage +Kritisch: 14 Tage +Prüfung: alle 12 Stunden +``` + +Das Zertifikat kann über den Manager erneuert werden: + +```text +[5] Zertifikat erneuern +``` + +Die Rotation erfolgt mit Überlappung: + +```text +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: + +```text +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: + +```text +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: + +```json +"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: + +```text +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: + +```text +AUTH LOGIN +AUTH PLAIN +``` + +SMTP-AUTH kann optional oder verpflichtend aktiviert werden. + +Beispiel: + +```json +"RequireAuth": true +``` + +Clients ohne erfolgreiche Authentifizierung erhalten dann: + +```text +530 5.7.0 Authentication required +``` + +Erfolgreiche Anmeldung: + +```text +235 2.7.0 Authentication successful +``` + +Fehlgeschlagene Anmeldung: + +```text +535 5.7.8 Authentication credentials invalid +``` + +Nach mehreren Fehlversuchen kann die Verbindung temporär gesperrt werden: + +```text +454 4.7.0 Too many authentication failures +``` + +Standard: + +```text +AuthMaxFailures = 5 +``` + +--- + +# SMTP-Benutzerverwaltung + +Im Manager: + +```text +[9] SMTP-AUTH verwalten +``` + +Funktionen: + +```text +[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: + +```text +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: + +```json +"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: + +```json +"ForceSender": true +``` + +wird immer `Graph.SenderMailbox` als Absender verwendet. + +--- + +# Parallele SMTP-Verbindungen + +SMTPGraphRelay verarbeitet mehrere SMTP-Clients parallel über einen PowerShell-Runspace-Pool. + +Standard: + +```text +MaxConcurrentClients = 20 +``` + +Ist das Limit erreicht: + +```text +421 4.3.2 SMTPGraphRelay busy, try again later +``` + +--- + +# SMTP-Limits + +Standardwerte: + +```text +MaxRecipients = 50 +MaxMessagesPerConnection = 25 +MaxMessageSizeMB = 25 +``` + +Zu viele Empfänger: + +```text +452 4.5.3 Too many recipients +``` + +Zu viele Nachrichten innerhalb einer Verbindung: + +```text +452 4.5.3 Too many messages in this session +``` + +Zu große Nachricht: + +```text +552 5.3.4 Message size exceeds fixed maximum message size +``` + +--- + +# Store-and-Forward Queue + +Queue-Struktur: + +```text +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: + +```text +7F3A91C2D441 +``` + +SMTP-Antwort: + +```text +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: + +```text +1 Minute +5 Minuten +15 Minuten +30 Minuten +60 Minuten +120 Minuten +240 Minuten +480 Minuten +``` + +Standard: + +```text +MaxRetries = 8 +``` + +Automatische Wiederholung erfolgt bei: + +```text +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: + +```text +MaxPendingMessages = 5000 +MinFreeDiskSpaceMB = 1024 +``` + +Queue-Limit erreicht: + +```text +452 4.3.1 SMTPGraphRelay queue limit reached +``` + +Zu wenig freier Speicher: + +```text +452 4.3.1 Insufficient system storage +``` + +Kann eine Nachricht nach `DATA` nicht atomar gespeichert werden: + +```text +451 4.3.0 SMTPGraphRelay queue temporarily unavailable +``` + +--- + +# Failed Queue + +Im Manager: + +```text +[10] Failed Queue verwalten +``` + +Funktionen: + +```text +[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: + +```text +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: + +```text +GracefulShutdownSeconds = 30 +``` + +Bei Timeout fällt der Manager auf einen harten Scheduled-Task-Stop zurück. + +--- + +# Logging + +Logdatei: + +```text +C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log +``` + +Log-Rotation: + +```text +MaxFileSizeMB = 10 +RetentionDays = 30 +CleanupHours = 12 +``` + +Archivierte Logs: + +```text +SMTPGraphRelay-YYYYMMDD-HHMMSS.log +``` + +--- + +# Health Check + +Im Manager: + +```text +[6] Health Check ausführen +``` + +oder direkt: + +```powershell +.\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: + +```text +0 = OK +1 = Warnung +2 = Fehler +``` + +--- + +# SMTP-Testmail + +```powershell +.\Test-SMTPGraphRelay.ps1 ` + -SendTestMail ` + -TestRecipient "user@example.com" +``` + +Bei aktiviertem SMTP-AUTH: + +```powershell +.\Test-SMTPGraphRelay.ps1 ` + -SendTestMail ` + -TestRecipient "user@example.com" ` + -SmtpUsername "scanner01" +``` + +Das Passwort wird interaktiv und verdeckt abgefragt. + +--- + +# Online Update + +Im Manager: + +```text +[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: + +```text +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: + +```text +[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: + +```text +config.json +queue\ +failed\ +logs\ +backup\ +Zertifikat +Entra App Registration +Exchange Application RBAC +``` + +--- + +# Failure-Mode QA + +Im Manager: + +```text +[11] Failure-Mode QA +``` + +oder direkt: + +```powershell +.\Test-SMTPGraphRelay-FailureModes.ps1 +``` + +Tests: + +```text +[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: + +```text +SYSTEM +``` + +Ausgeführt wird explizit: + +```text +C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe +``` + +mit: + +```text +-NoLogo +-NoProfile +-ExecutionPolicy Bypass +-File "C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1" +-ConfigPath "C:\Program Files\SMTPGraphRelay\config.json" +``` + +--- + +# Verzeichnisstruktur + +```text +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 + +```text +https://me-gitea.maieredv.cloud/MAIEREDV/SMTPGraphRelay +``` + +--- + +# Betriebskonzept + +SMTPGraphRelay ist für den internen Einsatz vorgesehen. + +Empfohlene Absicherung: + +```text +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.