QUIC mit IIS

Wenn Sie von QUIC auch im internen Netzwerk profitieren wollten, dann muss ihr Server natürlich zuerst einmal QUIC anbieten. Für QUIC und SMB gibt es eine eigene Seite. Hier geht es um den IIS, der ab Windows 2022 schon erste QUIC-Spuren zeigt.

Bindung im IIS

Wenn Sie auf einem Windows 2022 Server die IIS-Rolle installieren, dann sehen Sie in den Bindungen schon eine Funktion "Disable QUIC".

Damit könnten Sie dem IIS per GUI sagen, dass er QUIC nicht anbieten soll aber damit ist QUIC noch lange nicht konfiguriert.

MSQUIC und REGEDIT

Wenn der IIS nicht nur per HTTP/TCP erreichbar sein soll, und QUIC ein eigenes Protokoll neben TCP ist, dann finden sich auch im System entsprechende Einträge. Der ür die Bereitstellung von HTTP wichtige HTTPListener (HTTP.SYS) hat eine Abhängigkeit:

Der Dienst "MsQUIC" ist auch in der Konfiguration schon angelegt:

Damit stellt ihr IIS aber noch keine QUIC-Funktion bereit, wie Sie per PowerShell einfach ermitteln können:

PS C:\> Get-NetUDPEndpoint -LocalPort 443

Noch lauscht nichts auf 443/UDP.

QUIC konfigurieren

Für den Einsatz von QUIC ist nicht nur ein Zertifikate für die mit QUIC verpflichtende Verschlüsselung erforderlich sondern auch TLS 1.3 und die "TLS_CHACHA20_POLY1305_SHA256"-Cipher Suite. Zuerst sind folgende Schlüssel zu setzen, wenn Sie noch nicht vorhanden sind. Dazu sind einige Vorarbeiten erforderlich

Schritt Erledigt

Zertifikat

QUIC nutzt verpflichtend eine Verschlüsselung und dazu müssen Sie auf ihrem Webserver ein Zertifikat installieren. Das kann für einen Test auch mal ein "Self Signed"-Zertifikat sein, welches Sie im IISAdmin direkt anfordern können.

Auf Dauer sollten Sie aber ein Zertifikat von einer internen oder öffentlichen PKI anfordern und installieren.

TLS 1.3 aktivieren

Prüfen Sie die Einträge, ob TLS 1.3 auf dem Server schon aktiv ist. Ansonsten setzen Sie folgende Werte

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

HTTP3 aktivieren

Zwei weitere Einträge sind erforderlich, dass der IIS auch HTTP/3 und den Alt-Svc-Header unterstützt

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters]
"EnableHttp3"=dword:00000001
"EnableAltSvc"=dword:00000001

Diese Änderungen zu EnableHTTP3 werden aber nur nach einem Neustart von HTTP.SYS aktiv

NET STOP HTTP
NET START HTTP

Achtung: Es dürften noch andere Dienste davon abhängig sein. Vielleiciht ist ein Restart des Servers der einfachere Weg.

Cipher Suite Reihenfolge

Im nächsten Schritt setzen wir die CipherSuite an den Anfang:

Enable-TlsCipherSuite -Name TLS_CHACHA20_POLY1305_SHA256 -Position 0

Es gibt wohl Hinweise, dass bei einen Inplace-Update von Windows Server nicht immer die neuen Cipher Suites installiert werden.

Windows Firewall

QUIC kommuniziert über Port 443/UDP und wenn ihr Windows Server noch im Standard ist, gibt es eine passende Regel:

Bei mir war sie schon aktiviert, d.h. eingehende Verbindungen sind möglich. Per PowerShell geht das auch

# Aktuelle Regel ausgeben
Get-NetFirewallRule `
| Where-Object { $_.DisplayName -eq "World Wide Web Services (QUIC Traffic-In)" }`
| select name,enabled,status

# Regel ggfls. aktivieren
Get-NetFirewallRule IIS-WebServerRole-QUIC-In-UDP|enable-netfirewallrule 

Kontrolle UDP/443

Damit sollte die generelle Vorarbeit erledigt sein. Es fehlt aber noch ein letzter Schritt aber vorher möchte ich erst einmal prüfen, ob UDP/443 schon angeboten wird.

PS C:\> Get-NetUDPEndpoint -LocalPort 443

In meinem Fall wurde dies angegeben.

Der QUIC-Stack läuft im Prozessraum des HTTP.SYS mit und wird damit als "SYSTEM" geführt und nicht im W3SVC o.ä.

Damit sind die Grundlagen gelegt aber die Konfiguration ist noch nicht abgeschlossen.

QUIC aktivieren

Ich habe die Aktivierung absichtlich als eigenen Abschnitt ausgeführt, weil ich hier auch die Probleme aufzeige. Aktivieren Sie QUIC nicht einfach mal so sondern stehen Sie für Tests bereit.

Beim Zugriff per Browser auf "https://localhost" musste ich natürlich erst die Zertifikatswarnung bestätigen aber im Debugger habe ich nur die eine Verbindung über "h2" gesehen:

Das ist auch zu erwarten, denn wenn Sie sich die "Response Headers" anschauen, dann fehlt dort die Information über QUIC. Der Registrierungsschlüssel "EnableAltSvc" wirkt hier nicht und ich muss den passenden Header noch setzen:

Ich habe hier einfach nur "quic:443" addiert. Sie können aber auch noch die Cachedauer addieren.

Ich habe hier den Wert "ma" absichtlich niedriger auf 600 Sekunden gesetzt, um Caching auf dem Client zu begrenzen.

Wenn der Parameter "ma" nicht angegeben ist, dann scheint 24h der Default zu sein.

Custom Response Header gehen zumindest beim IIS 8.5 nur, wenn Verzeichnis als Applikation deklariert ist.

Auch das ist per Powershell möglich:

Import-Module WebAdministration
$siteName ="Default Web Site"
$headerName="alt-svc"
$headerValue='h3=":443"; ma=600'
Add-WebConfigurationProperty `
   -Filter "system.webServer/httpProtocol/customHeaders" `
   -PSPath IIS:\Sites\$siteName `
   -Name . `
   -AtElement @{name=$headerName}`
   -Value @{name=$headerName;value=$headerValue}

QUIC mit Browser verifizieren

Gespannt war ich dann auf den ersten Zugriff des Browsers.

Manchmal ist es sinnvoll, den "Private mode" zu nutzen, um Caching von Einträgen zu vergessen.

Aus dem Bild sehe ich zwei Dinge:

  • Kein H3, nur HTTP2
    Es kam hier wohl noch keine QUIC-Verbindung zustande, denn dann müsste in der Protokoll-Spalte ein H3 stehen
  • Große-Verzögerung
    Wer das Wasserfall-Diagramm liest, erkennt eine deutliche Verzögerung beim Laden des Bilds "iisstart.png"

Die Header des HTML-Dokuments sollte zeigen, dass die Änderung des HTTP-Response Header angenommen wurde.

Nun liegt es am Client, genau am Browser, die ersten Seite noch klassisch per HTTP/1.1 oder HTTP/2 zu laden und dann anhand des Alt-Svc-Headers per QUIC auf Webseite zuzugreifen und natürlich muss ihr Netzwerk den Weg zum Webserver per DNS auflösen und per Firewall erreichen können. Ein Netzwerktrace kann aber schon Hinweise geben, warum es nicht funktioniert. Hier sieht man sehr wohl, dass der ALT_SVC-Eintrag erkannt wurde aber den Status "is_broken = true" hat.

Wo wird der Browser natürlich kein QUIC versuchen. Eine Korrektur wird aber nicht immer sofort genutzt.

Hier hilft wieder der Netzwerkmitschnitt im Browser (edge://net-export). Wir sehen hier nicht nur, dass der Browser den "At-Svc"-Header verstanden hat, sondern auch, wie lange die Konfiguration noch als "Broken" angesehen wird. Hier wird 5 Minuten kein weiterer QUIC-Versuch mehr gestartet.

Wenn Sie es häufiger probieren, dann wird das Intervall immer größer. Hier sind wir schon bei 24 Stunden!

Hier hilft dann ein "Privater Browser" weiter oder Sie starten einen "Empty cache and hard refresh" über den Reload-Button bei aktivem F12-Debugger

This class tracks HTTP alternative services that have been marked as broken. The brokenness of an alt-svc will expire after some time according to an exponential back-off formula: each time an alt-svc is marked broken, the expiration delay will be some constant multiple of its previous expiration delay. This prevents broken alt-svcs from being retried too often by the network stack.
Quelle: https://chromium.googlesource.com/chromium/src/+/HEAD/net/http/broken_alternative_services.h#60

Zur Suche nach der Ursache wollte ich zuerst sehen, dass UDP-Pakete übertragen werden. Das lässt sich zwar auch im Chromium Netzwerktrace auslesen aber Wireshark liefert das meiner Ansicht nach schöner. Ein paralleler Mitschnitt mittels Wireshark zeigt aber sehr wohl die QUIC-Pakete selbst, (Ich habe mittlerweile eine zweite VM dazu genutzt.)

Damit ist bewiesen, dass sowohl der Browser als auch der Server sich QUIC über QUIC zumindest erreichen können.

Zertifikate

Damit sind Namensauflösung, Alt"-Svc"-Header, IP-Verbindung, Firewall-Freischaltung etc. nicht die Ursache, warum der Browser noch nicht die Bilder über QUIC mit dem Server abholt. QUIC erfordert TS 1.3 und ich habe daher geprüft, ob mein IIS überhaupt TLS 1.3 anbietet. Über die Einstellung "Security" im Debugger kann ich die Details zum TLS-Handshake auslesen:

Die Voraussetzung TLS 1.3 ist erfüllt und auch die Cypher Suite TLS_CHACHA20_POLY1305_SHA256 wurde genutzt. Auch ist das Zertifikat als "vertrauenswürdig" eingestuft, selbst wenn es nur ein "Self Signed Cert" ist und kein PKI-Zerfifikat. In der weiteren Analyse mit dem Netzwerkstack habe ich gesehen, dass UDP-Pakete und ein QUIC-Handshake gestartet wurden aber dennoch mit einem Zertifikatfehler abgebrochen wurde:

Allerdings scheitert die QUIC-Verbindung am "Self Signed" Zertifikat, was ich aber komisch finde, denn die HTTPS-Verbindung per HTTP/1.1 und HTTP/2 funktioniert ohne Fehler. Ich habe natürlich das SelfSigned-Zertifikat in den passenden Trusted Root-Store addiert. Wenn ich dann mit dem Fehler "QUIC_TLS_CERTIFICATE_UNKNOWN self signed" suche, dann finden sich weitere Hinweise:

Note that the server's certificate must be trusted by a default CA for Chrome/Chromium to accept it for QUIC. If you are using a self-signed certificate or a certificate that is signed by a custom CA, you need to use the --ignore-certificate-errors-spki-list command line flag to trust an individual certificate based on its SPKI. It is not possible to trust a custom CA using this flag.
Quelle: Playing with QUIC https://www.chromium.org/quic/playing-with-quic/

Allerdings hat der Aufruf bei mir nur eine Warnung im Browser produziert:

QUIC wurde aber dennoch nicht genutzt und ich habe weiter gesucht

Note that Chrome/Chromium (the browser) does not allow custom CAs for QUIC, so in addition to adding the root certificate to the certificate store, you'll need to pass in --ignore-certificate-errors-spki-list=.. with the certificate's SPKI to allow Chrome/Chromium to accept your custom certificate as valid.
Quelle: https://www.chromium.org/quic/playing-with-quic/

If you’re not using an official TLS certificate (signed by a certificate authority or root certificate that is trusted by Chrome, such as Let’s Encrypt), then you cannot use QUIC. 
https://www.smashingmagazine.com/2021/09/http3-practical-deployment-options-part3/#additional-issues

If the server you are connecting to does not have a trusted certificate, use the --disable_certificate_verification flag on the client to disable certificate verification. If the server's certificate is trusted but chains to a user installed CA (e.g. a CA generated by the script mentioned above), use the --allow_unknown_root_cert flag on the client to allow connections where the cert chains to a user installed CA.
Quelle: https://www.chromium.org/quic/playing-with-quic/

Note that all of --ignore-cerificate-errors, --ignore-certificate-errors-spki-list, and --origin-to-force-quic-on are required, along with the root cert in the cert store, to avoid certificate validation errors.
Quelle: https://www.chromium.org/quic/playing-with-quic/

Pass a flag to Chromium indicating which certificate needs to be trusted. For the example above, that flag would be: --ignore-certificate-errors-spki-list=Gi/HIwdiMcPZo2KBjnstF5kQdLI5bPrYJ8i3Vi6Ybck= Verification with certificate hash/fingerprint only works for certificates valid for no more than 14 days.
Quelle: https://stackoverflow.com/questions/75979276/do-i-have-to-get-a-valid-ssl-certificate-to-make-webtranport-server-examples-wor

Chromium macht es wohl wirklich schwer, QUIC mit privaten Zertifikaten zu nutzen und vertraut nur den vorbelegten Stammzertifikaten und alle anderen dürfen angeblich nicht älter als 2 Wochen sein. Es gibt ja jauch eine ganze Menge an Schaltern.

--disable_certificate_verification
--ignore-cerificate-errors
--ignore-certificate-errors-spki-list
--origin-to-force-quic-on

Gelungen ist es mir letztlich mit folgendem Aufruf:  (Umbrüche entfernen)

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" 
   --profile-directory=Default 
   --origin-to-force-quic-on=s2022.msxfaq.intranet:443 
   https://s2022.msxfaq.intranet/quictest.htm

Allerdings wurde Chrome damit dann auch angewiesen, gleiche mit QUIC zu starten. Der Abruf meiner "quictest.htm"-Seite erfolgte hier dann auch schon per QUIC_

Damit war dann aber letztlich bewiesen, dass der IIS auf Windows 2022 mit QUIC erreichbar ist.

QUIC analysieren

Auf den Seiten QUIC und Timeout, QUIC mit Proxy und Firewall und anderen habe ich schon verschiedene Analysen zu QUIC mit Gegenstellen im Internet beschrieben. Zum Test habe ich mir eine kleine HTML-Datei angelegt, die auf sechs eine Grafiken verweist:

<html>
<head><title>QUICTEST</title></head>
<body>
<h1>QUICTEST</h1>
<p>Image 1-6
<img src=".\bullet00.gif">
<img src=".\bullet01.gif">
<img src=".\bullet02.gif">
<img src=".\bullet03.gif">
<img src=".\bullet04.gif">
<img src=".\bullet05.gif">
<img src=".\bullet06.gif">
</p>
</body>
</htm>

Die Bilder sind einfach hier von der MSXFAQ kopiert: . Der normale Abruf per HTTP/2 ist recht einfach nachzuvollziehen und sie sehen gut den Abruf der HTML-Seite  und dann von Bilder aber auch, dass einige Abrufe verzögert werden

 

 

 

:start
curl https://ss -k --http3 --resolve domain.tld:443:127.0.0.1
goto start

 

Einschätzung

Wenn Sie schon Windows 2022 und höher haben und auf Basis des IIS auch Dienste anbieten, dann kann QUIC durchaus eine gewisse Performance bringen, da der Browser nicht mehr auf 4-6 HTTP1.1 TCP-Connections beschränkt ist. Aber die meisten Browser und Webserver können auch HTTP/2 unterstützen und damit über eine Connection mehrere parallele Streams übertragen. Störend ist bei TCP aber jeglicher Paketverlust, eine zu kleine Window-Size und lange Latenzzeiten über weite Entfernungen. Daher ist QUIC insbesondere für Anbieter wie Amazon, Google, Microsoft und Content Delivery Networks wichtig.

Ein Betreiber eines internen Webservers, der nur von Clients im gleichen Standort ohne Paketverlust und geringer Latenzzeit angesprochen wird, sollte keine Wunder erwarten. Eine gute Analyse ihrer Webanwendung auf dem Server und dem Client könnte viel mehr Performance gewinnen als die reine Aktivierung von QUIC. Sie sollten aber immer nur Zertifikate von RootCAs verwenden, die bei Chromium auch als vertrauenswürdig angesehen werden. Eine eigene Firmen-PKI zählt da aktuell nicht dazu, was den rein internen Einsatz schon wieder erschwert.

Weitere Links