Dateien nach "/" hochladen
This commit is contained in:
@@ -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
|
V1.4 erweitert V1.3 um Zertifikatsüberwachung und sichere Rotation.
|
||||||
`config.json` können unverändert weiterverwendet werden.
|
|
||||||
|
|
||||||
## Neu
|
## Relay: automatische Zertifikatsüberwachung
|
||||||
|
|
||||||
- bis zu 20 parallele SMTP-Verbindungen standardmäßig
|
Beim Start wird das Zertifikat aus `Graph.CertificateThumbprint` geprüft:
|
||||||
- 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
|
|
||||||
|
|
||||||
## 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
|
```json
|
||||||
"Smtp": {
|
"Graph": {
|
||||||
"ListenAddress": "0.0.0.0",
|
"TenantId": "...",
|
||||||
"Port": 2525,
|
"ClientId": "...",
|
||||||
"Hostname": "SMTPRELAY01",
|
"CertificateThumbprint": "...",
|
||||||
"AllowedNetworks": [
|
"SenderMailbox": "info@example.com",
|
||||||
"127.0.0.1/32",
|
"ForceSender": true,
|
||||||
"10.0.0.0/8",
|
"CertificateWarningDays": 60,
|
||||||
"172.16.0.0/12",
|
"CertificateCriticalDays": 14,
|
||||||
"192.168.0.0/16"
|
"CertificateCheckHours": 12
|
||||||
],
|
|
||||||
"MaxMessageSizeMB": 25,
|
|
||||||
"ClientTimeoutSeconds": 120,
|
|
||||||
"MaxConcurrentClients": 20
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
```powershell
|
||||||
Stop-ScheduledTask -TaskName "SMTPGraphRelay"
|
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
|
V1.3 sichern und V1.4 als `SMTPGraphRelay.ps1` ablegen, dann:
|
||||||
|
|
||||||
```text
|
|
||||||
C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
ablegen und starten:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
Start-ScheduledTask -TaskName "SMTPGraphRelay"
|
Start-ScheduledTask -TaskName "SMTPGraphRelay"
|
||||||
```
|
```
|
||||||
|
|
||||||
Log:
|
Die `config.json` muss nicht geändert werden.
|
||||||
|
|
||||||
```powershell
|
Im Log erscheint bei einem gesunden Zertifikat beim Start beispielsweise:
|
||||||
Get-Content `
|
|
||||||
"C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log" `
|
|
||||||
-Tail 100
|
|
||||||
```
|
|
||||||
|
|
||||||
Beim Start sollten u. a. erscheinen:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
SMTPGraphRelay V1.3 gestartet ...
|
Graph-Zertifikat gültig bis 2028-08-13 23:00:00 (729 Tage verbleibend).
|
||||||
Maximale parallele SMTP-Verbindungen: 20
|
|
||||||
Queue-/Graph-Worker läuft separat vom SMTP-Listener.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user