Dateien nach "/" hochladen
This commit is contained in:
@@ -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
|
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.
|
||||||
- kooperativer Graceful Shutdown für Update, Repair und manuelles Stoppen über den Manager
|
|
||||||
|
|
||||||
Alle Funktionen aus V1.7 bleiben erhalten, insbesondere SMTP AUTH LOGIN/PLAIN,
|
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.
|
||||||
Queue-ID, Retry/Backpressure, Zertifikatsrotation, Health Check und Online-Update.
|
|
||||||
|
|
||||||
## 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
|
```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
|
$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
|
Der Bootstrap-Installer lädt automatisch den aktuellen Stand aus dem Gitea-Repository und installiert SMTPGraphRelay nach:
|
||||||
|
|
||||||
Im Manager:
|
|
||||||
|
|
||||||
```text
|
```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
|
Nach dem Start erscheint das Verwaltungsmenü:
|
||||||
- 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
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[1] Neuinstallation aus Gitea
|
[1] Neuinstallation aus Gitea
|
||||||
@@ -152,5 +65,799 @@ zurückgefallen.
|
|||||||
[8] Status anzeigen
|
[8] Status anzeigen
|
||||||
[9] SMTP-AUTH verwalten
|
[9] SMTP-AUTH verwalten
|
||||||
[10] Failed Queue verwalten
|
[10] Failed Queue verwalten
|
||||||
|
[11] Failure-Mode QA
|
||||||
[0] Beenden
|
[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/<SenderMailbox>/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.
|
||||||
|
|||||||
Reference in New Issue
Block a user