# STEP 4.1a – TLS-ENFORCEMENT VERIFIKATION (BEWEIS) # Status: ABGESCHLOSSEN # Datum: 2026-02-22 --- ## 1. Listener-Tabelle | Server | Port | Host | Protokoll (mit TLS) | Protokoll (ohne TLS) | |--------|------|------|---------------------|----------------------| | backend_main | 8000 (ENV PORT) | 0.0.0.0 | HTTPS only | Fail-Start (AZA_TLS_REQUIRE=1) | | transcribe_server | 8090 (ENV TRANSCRIBE_PORT) | 0.0.0.0 | HTTPS only | Fail-Start (AZA_TLS_REQUIRE=1) | | todo_server | 5111 | 0.0.0.0 | HTTPS only | Fail-Start (AZA_TLS_REQUIRE=1) | | workforce_planner | variabel | variabel | Über uvicorn CLI | Kein eigener __main__ | --- ## 2. Test-Kommandos und Ergebnisse ### TEST 1: Fail-Start ohne Zertifikat (AZA_TLS_REQUIRE=1) **Kommando:** ``` $env:AZA_TLS_CERTFILE = "" $env:AZA_TLS_KEYFILE = "" $env:AZA_TLS_REQUIRE = "1" $env:MEDWORK_API_TOKEN = "test123" python backend_main.py ``` **Ergebnis:** ``` FEHLER: TLS ist erforderlich (AZA_TLS_REQUIRE=1), aber AZA_TLS_CERTFILE und/oder AZA_TLS_KEYFILE sind nicht gesetzt. ``` Exit Code: 1 **Bewertung: PASS** – Server startet nicht ohne Zertifikat. --- ### TEST 2: HTTPS-Verbindung **Kommando:** ```python ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE r = urllib.request.urlopen('https://127.0.0.1:8444/health', context=ctx) ``` **Ergebnis:** ``` HTTPS: 200 {"ok": true} ``` **Bewertung: PASS** – HTTPS funktioniert. --- ### TEST 3: HTTP-Verbindung (muss fehlschlagen) **Kommando:** ```python r = urllib.request.urlopen('http://127.0.0.1:8444/health', timeout=5) ``` **Ergebnis:** ``` http.client.RemoteDisconnected: Remote end closed connection without response ``` Exit Code: 1 **Bewertung: PASS** – HTTP wird abgelehnt. Kein HTTP-Fallback. --- ### TEST 4: TLS-Version und Cipher **Kommando:** ```python ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE with ctx.wrap_socket(socket.socket(), server_hostname='localhost') as s: s.connect(('127.0.0.1', 8444)) print(s.version(), s.cipher()) ``` **Ergebnis:** ``` TLS Version: TLSv1.3 Cipher: TLS_AES_256_GCM_SHA384 Protocol: TLSv1.3 Bits: 256 ``` **Bewertung: PASS** – TLS 1.3 mit AES-256-GCM, PFS aktiv. --- ### TEST 5: Zertifikat-Details **Kommando:** ```python cert = s.getpeercert(binary_form=True) c = x509.load_der_x509_certificate(cert) ``` **Ergebnis:** ``` Subject: CN=localhost,O=AZA MedWork DEV Issuer: CN=localhost,O=AZA MedWork DEV Key: 4096 bit RSA Algo: SHA-256 Valid: 2026-02-22 -> 2027-02-22 ``` **Bewertung: PASS** – RSA 4096-bit, SHA-256, Self-Signed (DEV). --- ### TEST 6: ENV-Hardcoding-Prüfung **Kommando:** Grep nach "dev-cert.pem" / "dev-key.pem" in *.py **Ergebnis:** Nur in `aza_tls.py` Zeilen 114-115 (Generierungsfunktion) und Docstring. NICHT in todo_server.py, transcribe_server.py, backend_main.py. Alle Server lesen Zertifikatspfade ausschliesslich aus ENV-Variablen. **Bewertung: PASS** – Keine hardcodierten Zertifikatspfade. --- ## 3. Fix während Verifikation | Datei | Zeile | Problem | Fix | |-------|-------|---------|-----| | aza_tls.py | 93-97 | `ssl_version: ssl.TLSVersion.TLSv1_2` inkompatibel mit uvicorn (ValueError: invalid protocol version 771) | Ersetzt durch `ssl_ciphers: _STRONG_CIPHERS` | --- ## 4. Gesamtbewertung | Test | Ergebnis | |------|----------| | Fail-Start ohne Cert | **PASS** | | HTTPS-Verbindung | **PASS** | | HTTP-Ablehnung | **PASS** | | TLS >= 1.2 | **PASS** (TLS 1.3 verhandelt) | | Starke Cipher | **PASS** (AES-256-GCM) | | PFS | **PASS** (ECDHE/DHE only) | | Zertifikat RSA 4096 | **PASS** | | Keine hardcodierten Pfade | **PASS** | **GESAMTERGEBNIS: PASS (8/8)**