diff --git a/README.md b/README.md index ebf9619..a7206e7 100644 --- a/README.md +++ b/README.md @@ -1,133 +1,104 @@ -# SMTPGraphRelay V1.3 – parallele SMTP-Verbindungen +# SMTPGraphRelay V1.4 – Zertifikats-Lifecycle -V1.3 baut auf V1.2 auf. Entra-App, Zertifikat, Exchange Application RBAC und -`config.json` können unverändert weiterverwendet werden. +V1.4 erweitert V1.3 um Zertifikatsüberwachung und sichere Rotation. -## Neu +## Relay: automatische Zertifikatsüberwachung -- bis zu 20 parallele SMTP-Verbindungen standardmäßig -- konfigurierbares Parallel-Limit über `Smtp.MaxConcurrentClients` -- SMTP-Clients laufen in einem .NET Runspace Pool -- Queue-/Graph-Versand läuft in einem eigenen Runspace -- ein langsamer Graph-Aufruf blockiert die SMTP-Annahme nicht mehr -- ein langsamer/hängender SMTP-Client blockiert andere Clients nicht mehr -- bei erreichtem Parallel-Limit erhält ein neuer Client: - `421 4.3.2 SMTPGraphRelay busy, try again later` -- Logging ist mit einem benannten Mutex gegen parallele Schreibzugriffe geschützt -- Queue-/Retry-Logik aus V1.2 bleibt erhalten +Beim Start wird das Zertifikat aus `Graph.CertificateThumbprint` geprüft: -## Optional: Parallel-Limit konfigurieren +- Zertifikat vorhanden +- privater Schlüssel vorhanden +- Ablaufdatum -Bestehende `config.json` muss nicht geändert werden. Ohne Eintrag gilt `20`. +Standardwerte: -Optional: +- Warnung ab 60 Tagen Restlaufzeit +- kritisch ab 14 Tagen +- erneute Prüfung alle 12 Stunden + +Optional in `config.json`: ```json -"Smtp": { - "ListenAddress": "0.0.0.0", - "Port": 2525, - "Hostname": "SMTPRELAY01", - "AllowedNetworks": [ - "127.0.0.1/32", - "10.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16" - ], - "MaxMessageSizeMB": 25, - "ClientTimeoutSeconds": 120, - "MaxConcurrentClients": 20 +"Graph": { + "TenantId": "...", + "ClientId": "...", + "CertificateThumbprint": "...", + "SenderMailbox": "info@example.com", + "ForceSender": true, + "CertificateWarningDays": 60, + "CertificateCriticalDays": 14, + "CertificateCheckHours": 12 } ``` -Erlaubter Bereich: 1 bis 200. Ungültige Werte fallen auf 20 zurück. +Die zusätzlichen Werte sind optional; bestehende Configs funktionieren unverändert. -## Update +## Rotation + +`Renew-SMTPGraphRelayCertificate.ps1` muss als Administrator mit +**Windows PowerShell 5.1** ausgeführt werden. + +```powershell +cd "C:\Program Files\SMTPGraphRelay" +.\Renew-SMTPGraphRelayCertificate.ps1 +``` + +Ablauf: + +1. bestehende Config lesen +2. neues nicht exportierbares Zertifikat in `LocalMachine\My` erzeugen +3. Entra-Admin interaktiv anmelden +4. bestehende App über ihre ClientId finden +5. neues Zertifikat **zusätzlich** in `keyCredentials` hinterlegen +6. App-only Login mit dem neuen Zertifikat testen +7. erst danach `config.json` atomar auf den neuen Thumbprint umstellen +8. Relay-Scheduled-Task neu starten +9. optional altes Cloud- und lokales Zertifikat entfernen + +Exchange Application RBAC muss nicht neu aufgebaut werden, weil die App/ClientId +bei der Rotation unverändert bleibt. + +## Warum das alte Zertifikat zunächst erhalten bleibt + +Die sichere Reihenfolge ist: + +```text +OLD funktioniert + | +NEW erzeugen + | +OLD + NEW in Entra + | +NEW Auth testen + | +Config -> NEW + | +Relay neu starten + | +erst dann optional OLD entfernen +``` + +So gibt es während der Rotation keinen Zeitpunkt ohne gültiges Credential und ein +Rollback bleibt möglich. + +## Update von V1.3 + +Task stoppen: ```powershell Stop-ScheduledTask -TaskName "SMTPGraphRelay" - -Copy-Item ` - "C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1" ` - "C:\Program Files\SMTPGraphRelay\SMTPGraphRelay-V1.2-backup.ps1" ``` -Dann `SMTPGraphRelay-V1.3.ps1` als - -```text -C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1 -``` - -ablegen und starten: +V1.3 sichern und V1.4 als `SMTPGraphRelay.ps1` ablegen, dann: ```powershell Start-ScheduledTask -TaskName "SMTPGraphRelay" ``` -Log: +Die `config.json` muss nicht geändert werden. -```powershell -Get-Content ` - "C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log" ` - -Tail 100 -``` - -Beim Start sollten u. a. erscheinen: +Im Log erscheint bei einem gesunden Zertifikat beim Start beispielsweise: ```text -SMTPGraphRelay V1.3 gestartet ... -Maximale parallele SMTP-Verbindungen: 20 -Queue-/Graph-Worker läuft separat vom SMTP-Listener. +Graph-Zertifikat gültig bis 2028-08-13 23:00:00 (729 Tage verbleibend). ``` - -## Test für Parallelität - -In mehreren PowerShell-Fenstern gleichzeitig: - -```powershell -Send-MailMessage ` - -SmtpServer 127.0.0.1 ` - -Port 2525 ` - -From "info@maieredv.de" ` - -To "manuel.maier@maieredv.de" ` - -Subject "Parallel-Test" ` - -Body "SMTPGraphRelay V1.3" -``` - -Für einen härteren Test können mehrere Jobs gleichzeitig gestartet werden: - -```powershell -1..10 | ForEach-Object { - Start-Job -ArgumentList $_ -ScriptBlock { - param($n) - Send-MailMessage ` - -SmtpServer 127.0.0.1 ` - -Port 2525 ` - -From "info@maieredv.de" ` - -To "manuel.maier@maieredv.de" ` - -Subject "Parallel-Test $n" ` - -Body "Nachricht $n" - } -} - -Get-Job | Wait-Job | Receive-Job -Get-Job | Remove-Job -``` - -## Architektur - -```text - +--> SMTP Worker 1 --+ -SMTP Listener -----------+--> SMTP Worker 2 --+--> pending\ - +--> SMTP Worker N --+ - Runspace Pool - | - | unabhängig - v - Queue / Graph Worker - | - v - Microsoft Graph -``` - -Der SMTP-Listener nimmt dadurch weiter neue Verbindungen an, während andere Clients -noch `DATA` übertragen oder Microsoft Graph gerade langsam antwortet.