AEK443001: NetScaler – TLS-Handshake-Fehler wegen fehlender ECC-Kurven
Das Ausrollen auf einen Citrix NetScaler scheitert mit remote error: tls: handshake failure, weil am Management-Dienst keine ECC-Kurven gebunden sind. Ursache, Diagnose und zwei Lösungswege.
Der aethercert-agent kann ein Zertifikat nicht auf einen Citrix NetScaler ausrollen, wenn am Management-Dienst keine ECC-Kurven gebunden sind. Die Korrektur erfolgt auf dem NetScaler, am Agent und am Target ist nichts zu ändern.
| Feld | Wert |
|---|---|
| Artikelnummer | AEK443001 |
| Betroffen | Target Citrix NetScaler ADC (NITRO über die NSIP) |
| Nachgestellt mit | NetScaler 14.1 Build 73.41 |
| Ursache | Keine ECC-Kurven am Dienst nshttps-127.0.0.1-443, dadurch kein ECDHE-Cipher verhandelbar |
| Lösung | ECC-Kurven und eine ECDHE-Cipher-Gruppe binden |
Symptom
Der Deploy-Schritt auf das NetScaler-Target bricht mit einem TLS-Fehler ab, bevor ein NITRO-Aufruf stattfindet.
- Das Agent-Log zeigt
remote error: tls: handshake failurebeim Verbindungsaufbau zur NSIP. - Die Zertifikatsausstellung selbst ist erfolgreich, nur das Ausrollen scheitert.
- Die NetScaler-GUI im Browser und NITRO-Aufrufe mit
curl.exeoder PowerShell funktionieren weiterhin. Deshalb fällt der Fehler im Alltag nicht auf.
Ursache
NetScaler und Agent haben keinen gemeinsamen Cipher, weil am Management-Dienst keine ECC-Kurven gebunden sind.
- Der HTTPS-Zugriff auf die NSIP läuft über die internen Dienste
nshttps-127.0.0.1-443undnshttps-::1l-443. - Dort ist die Cipher-Gruppe
DEFAULTgebunden, aber keine ECC-Kurve. Ohne Kurve kann der NetScaler keinen ECDHE-Cipher aushandeln. - Aus
DEFAULTbleiben damit nur Cipher mit reinem RSA-Schlüsselaustausch übrig, etwaAES128-SHAoderAES256-GCM-SHA384. - Der aethercert-agent bietet keine Cipher mit reinem RSA-Schlüsselaustausch an. Diese Cipher haben keine Forward Secrecy und gelten als veraltet.
- Ohne Schnittmenge beendet der NetScaler den Handshake mit
handshake_failure.
Browser und Windows-Werkzeuge (SChannel) bieten RSA-Schlüsselaustausch noch an und kommen deshalb durch.
Diagnose
Die Ursache ist bestätigt, wenn am Dienst keine ECC-Kurven erscheinen und der ECDHE-Test scheitert, der RSA-Test aber klappt. Alle Befehle sind nur lesend.
1. Dienst und SSL-Parameter prüfen (NetScaler-CLI):
show ssl service nshttps-127.0.0.1-443
show ssl parameter- In der Ausgabe des Dienstes fehlen Zeilen wie
ECC Curve Name: P_256. show ssl parameterzeigt unterDefault profile, ob Enhanced SSL Profiles aktiv sind. Davon hängt ab, ob Lösung A oder Lösung B passt.- Sind die Profile aktiv, zusätzlich
show ssl profile ns_default_ssl_profile_internal_frontend_serviceprüfen.
2. Gegenprobe mit OpenSSL (auf der NetScaler-Shell, <NSIP> ersetzen):
shell
openssl s_client -connect <NSIP>:443 -tls1_2 -cipher ECDHE-RSA-AES128-GCM-SHA256 </dev/null
openssl s_client -connect <NSIP>:443 -tls1_2 -cipher AES128-GCM-SHA256 </dev/null
exitDer erste Aufruf endet mit einem Handshake-Fehler, der zweite baut die Verbindung auf.
Vorher Backup oder Snapshot erstellen
Bevor die folgenden Befehle abgesetzt werden, ein Backup der NetScaler-Konfiguration oder einen Snapshot der VM erstellen.
Lösung A: mit Enhanced SSL Profiles
Diese Lösung gilt, wenn show ssl parameter unter Default profile den Wert ENABLED
zeigt. Kurven und Cipher-Gruppe werden dann einmal am Profil des Management-Dienstes gebunden.
Die Cipher-Gruppe lässt sich danach als Hausstandard für weitere Profile nutzen.
1. Cipher-Gruppe anlegen (TLS 1.3 und ECDHE-GCM für RSA- und ECDSA-Zertifikate):
add ssl cipher CG_AETHERCERT
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-CHACHA20-POLY1305-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-AES128-GCM-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-ECDSA-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-ECDSA-AES128-GCM-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA2562. Profil des Management-Dienstes anpassen:
bind ssl profile ns_default_ssl_profile_internal_frontend_service -eccCurveName X_25519
bind ssl profile ns_default_ssl_profile_internal_frontend_service -eccCurveName P_256
bind ssl profile ns_default_ssl_profile_internal_frontend_service -eccCurveName P_384
bind ssl profile ns_default_ssl_profile_internal_frontend_service -cipherName CG_AETHERCERT -cipherPriority 1
set ssl profile ns_default_ssl_profile_internal_frontend_service -tls13 ENABLEDDie Kurven werden bewusst einzeln statt mit ALL gebunden. So bleibt die schwache Kurve
P_224 außen vor.
3. Optional: DEFAULT lösen. Für den Deploy nicht nötig, mit den Kurven sind auch die
ECDHE-Cipher aus DEFAULT verhandelbar. Das Lösen härtet den Dienst zusätzlich, weil danach
nur noch die Cipher aus CG_AETHERCERT angeboten werden:
unbind ssl profile ns_default_ssl_profile_internal_frontend_service -cipherName DEFAULTLösung B: ohne Enhanced SSL Profiles
Sind die Profile nicht aktiviert, werden Kurven und Cipher-Gruppe direkt an beiden Management-Diensten gebunden. Das ändert nur diese zwei Dienste, bestehende Sitzungen bleiben erhalten.
1. Cipher-Gruppe anlegen (TLS 1.3 und ECDHE-GCM für RSA- und ECDSA-Zertifikate). Existiert
CG_AETHERCERT schon, diesen Schritt überspringen:
add ssl cipher CG_AETHERCERT
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-CHACHA20-POLY1305-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.3-AES128-GCM-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-ECDSA-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-ECDSA-AES128-GCM-SHA256
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384
bind ssl cipher CG_AETHERCERT -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA2562. Kurven binden:
bind ssl service nshttps-127.0.0.1-443 -eccCurveName X_25519
bind ssl service nshttps-127.0.0.1-443 -eccCurveName P_256
bind ssl service nshttps-127.0.0.1-443 -eccCurveName P_384
bind ssl service nshttps-::1l-443 -eccCurveName X_25519
bind ssl service nshttps-::1l-443 -eccCurveName P_256
bind ssl service nshttps-::1l-443 -eccCurveName P_3843. Cipher-Gruppe binden:
bind ssl service nshttps-127.0.0.1-443 -cipherName CG_AETHERCERT
bind ssl service nshttps-::1l-443 -cipherName CG_AETHERCERT4. Optional: DEFAULT lösen. Für den Deploy nicht nötig, das Lösen härtet die Dienste
zusätzlich. Erst nach Schritt 3, damit die Dienste nie ohne Cipher sind:
unbind ssl service nshttps-127.0.0.1-443 -cipherName DEFAULT
unbind ssl service nshttps-::1l-443 -cipherName DEFAULTPrüfen und Deploy wiederholen
Nach der Änderung klappt der ECDHE-Test, und der Deploy-Job läuft ohne weitere Anpassung durch.
-
Die OpenSSL-Gegenprobe aus der Diagnose wiederholen. Der ECDHE-Test zeigt jetzt
Cipher is ECDHE-RSA-AES128-GCM-SHA256. WurdeDEFAULTgelöst, scheitert der Test mitAES128-GCM-SHA256nun bewusst, weilCG_AETHERCERTkeinen RSA-Schlüsselaustausch enthält. -
Konfiguration speichern:
save ns config -
Im aethercert-Dashboard unter Verwalten > Jobs den fehlgeschlagenen Job mit Bereitstellung wiederholen erneut anstoßen. Der Agent hat das Zertifikat bereits, es läuft also nur der Deploy-Schritt. Siehe Certificate jobs.
Hinweise
DEFAULTenthält weiterhin SHA1-CBC-Cipher und Cipher mit RSA-Schlüsselaustausch.CG_AETHERCERTkann deshalb auch für SSL-vServer der Hausstandard werden. Mit Lösung A geht das über das Profilns_default_ssl_profile_frontend.- Mit aktivem Default-Profil bindet der NetScaler
ns_default_ssl_profile_internal_frontend_servicean die internen Dienste und deaktiviert dort SSLv3, TLS 1.0 und TLS 1.1. - Zertifikate von Hand auf dem NetScaler tauschen: Citrix NetScaler (ADC).