QUIC Erreichbarkeitstest
Es ist ja nett, wenn mein Client per HTTPS zu einem Webserver kommt, der dann im "Alt-Svc"-Header auch QUIC anbietet. Der Client wird dann auch QUIC versuchen und je nach Netzwerk, Firewall und Proxy-Konfiguration kann dies gelingen oder auch nicht. Da wäre es doch interessant, einmal die Erreichbarkeit eines QUIC-Servers vom Client zu testen. Ich habe nun natürlich keinen vollständigen QUIC-Stack implementiert aber auch per PowerShell kann ich UDP-Pakete senden und zumindest für den ersten Handshake sollte es ausreichen-
Wenn auf der entfernten Seite ein UDP-Service auf Port 443 eingehende Anfragen annimmt und umgehend beantwortet, dann eignet sich so eine Gegenstelle auch als Probe-System. Beim TCP-Handshake konnte ich das auch durch den 3-Wege Handshake ermitteln. Für die Teams/Skype TURN-Server habe ich mit End2End-UDP3478 schon ein Modul geschrieben, um UDP-Server zu testen. Das ist nun auch mit QUIC möglich. Der Aufhänge ist das erste "Initial"-Paket an Port 443/UDP eines Servers, der dann mit einem Handshake antwortet.
QUIC basiert auf UDP und ich habe einfach ein "INITIAL-Paket" mit Wireshark mitgeschnitten und per UDP an eine Gegenstelle gesendet.
- UIC: A UDP-Based Multiplexed and Secure Transport draft-ietf-quic-transport-08 -
5.4.1. Initial Packet
https://datatracker.ietf.org/doc/html/draft-ietf-quic-transport-08#page-14
Tatsächlich konnte ich ein Paket, welches original an "play.google.com" gegangen ist, auch an Facebook oder www.google.com senden und bekam eine Antwort zurück:
Da ich selbst den Handshake dann natürlich nicht weiter geführt habe, kann man auch schön sehen, wie die Gegenseite (www.google.com) aufgrund meiner ausbleibenden Quittung nach 50ms, 100ms, 100ms 200ms, 400ms und 32 Sekunden noch mal sendet. Es gibt aber noch andere Paketformate, wie folgender Trace aufzeigt:
Hier ist auch gut zu sehen, dass in einem Paket gleich mehrere Frames enthalten sein können und es zumindest zwei unterschiedliche Anfangsverfahren gibt.
Das Script nutzt aktuell nur das erste "schnelle" Verfahren.
# test-quicconnection # # 20210602 initial Version # Simple QUIC Reachability Test param ( [string]$remotesystem = "play.google.com", # remote host or IP-Address [int]$remoteudpport=443, # user https/udp port [int]$sourceudpport=0 # use any high port #[string]$remoteip = "www.facebook.com" #[string]$remoteip = "172.217.20.67" # ip von www.google.com ) $udpClient = new-Object System.Net.Sockets.Udpclient($sourceudpport) $udpClient.Client.ReceiveTimeout = 1000 # QUIC Packet from an Wireshark Connection to play.google.com $byteBuffer = @(0xc7,0xff,0x00,0x00,0x1d,0x08,0xaa,0xb1,0x22,0x79,0xc4,0x13,0xd3,0x56,0x00,0x37, 0x00,0x87,0xca,0x2e,0xe5,0x06,0xce,0xbd,0x4e,0xf7,0x0f,0xa2,0x7c,0x57,0x05,0x8d, 0x21,0xf9,0x4f,0xde,0xb3,0xad,0x9a,0x75,0xff,0x26,0xbb,0xe5,0x5d,0xd8,0xd3,0x85, 0x21,0x72,0x50,0x51,0x23,0x9d,0xbb,0xfe,0xc6,0xdd,0x98,0xcd,0xa3,0xc2,0xe9,0x83, 0x43,0x29,0x37,0x1f,0x49,0xa6,0xd8,0x44,0xe9,0x43,0x64,0x70,0xed,0x8b,0x49,0xcb, 0x89,0x14,0xb4,0x3e,0x63,0x02,0x65,0xe9,0x1d,0x0c,0x93,0xa7,0x04,0xaa,0xfa,0x84, 0x3f,0x18,0x2f,0x68,0x3a,0xbd,0x32,0x59,0x85,0x63,0x3e,0x48,0x11,0xb3,0xd6,0x98, 0xda,0x30,0xc6,0x30,0x59,0xe3,0xef,0x6e,0x40,0xfd,0x4c,0x57,0x97,0xa2,0x4e,0x93, 0x3f,0xef,0x4f,0x98,0x83,0x79,0xa2,0x58,0x79,0xb0,0xfa,0x2b,0x00,0xa4,0x13,0x7b, 0x09,0x27,0x66,0x81,0x4f,0xe4,0xce,0x06,0x79,0xd7,0x0c,0x62,0x09,0x09,0x78,0xc7, 0xcb,0x2c,0x4b,0x86,0x1b,0xbd,0xe2,0x65,0x2c,0x48,0x2b,0x8f,0xc6,0xbe,0x7e,0xc6, 0x3e,0xf5,0x1d,0x55,0x82,0x82,0xad,0x56,0x88,0x41,0xad,0xa7,0xc9,0x9a,0xe7,0x37, 0xf9,0x6e,0xbb,0xf6,0xcf,0x21,0x22,0x6c,0x7b,0x04,0x40,0x06,0x03,0x2f,0x69,0x98, 0xe8,0x15,0xf4,0x3c,0xfb,0xfc,0x83,0xdf,0x19,0x5e,0xfe,0x3f,0x70,0x02,0x16,0xfd, 0x0d,0x19,0xd6,0xac,0xc2,0x05,0xff,0x78,0xe9,0xb2,0x6f,0x77,0x39,0x39,0xf8,0x08, 0x7b,0xc6,0x89,0x12,0x54,0xe7,0x0d,0x1b,0xda,0xe2,0xc4,0xbe,0x1a,0x18,0xd7,0x44, 0x65,0x9e,0xbe,0xb8,0x59,0xee,0xdc,0xf5,0x3a,0x4f,0xa5,0x29,0xa6,0xcd,0x9c,0xd2, 0x12,0x82,0xef,0xcf,0x68,0x92,0x74,0xb8,0x9b,0x66,0xd7,0xd5,0x23,0xbf,0x04,0x62, 0x5c,0x2b,0x98,0x10,0x4d,0x5e,0xa0,0x36,0xbc,0xa9,0xb5,0xf0,0x06,0x22,0xc1,0x63, 0xb8,0xb6,0x34,0xfe,0xfc,0x51,0x72,0xd9,0x40,0x45,0x38,0x3d,0x6b,0x6d,0xda,0x4b, 0x7f,0xd6,0xb3,0x79,0xcb,0xbb,0x7b,0x63,0x73,0xd7,0x88,0x9a,0x60,0xde,0x3f,0xdb, 0x27,0xf4,0xa4,0x83,0xc5,0xaa,0x97,0x84,0x85,0x52,0x1a,0xd7,0x38,0xd0,0x1f,0x51, 0xf8,0xb4,0x1e,0x30,0xcb,0x31,0xc1,0x0e,0x8c,0xc2,0x2d,0x72,0x58,0x4d,0xa3,0xa8, 0xf7,0x7c,0xda,0x27,0xb2,0x18,0xa9,0xfc,0x97,0x77,0xa2,0x4b,0x0f,0xea,0xff,0xfb, 0xc9,0x71,0x63,0xf3,0x81,0xed,0xe2,0xb8,0x4b,0x60,0x17,0x7f,0x17,0x2e,0x5c,0x30, 0x66,0x38,0xe5,0x0d,0x3d,0x70,0x22,0xbb,0x4f,0xc2,0x74,0x33,0xd1,0xef,0xba,0xc7, 0x90,0x88,0x0f,0xfb,0x86,0x26,0xfe,0x8a,0x98,0xce,0xfa,0x41,0x44,0xb3,0x4d,0x84, 0xa2,0x2e,0x15,0x12,0x1d,0x9c,0x09,0x71,0xf7,0xdc,0x6c,0x41,0x24,0x12,0xbf,0x34, 0x98,0x2a,0x2e,0xa6,0xd8,0xbf,0x18,0xdd,0x14,0xd8,0x02,0xc0,0x16,0x81,0x27,0xdb, 0xb1,0x65,0xcf,0x47,0x92,0xff,0x18,0x01,0x80,0x36,0x56,0xdf,0xe9,0xee,0x68,0xc4, 0x4d,0x37,0x7b,0xe7,0xdd,0x22,0x03,0x72,0x7e,0x21,0xec,0x08,0x30,0x75,0x95,0x2d, 0x05,0x69,0x7a,0x25,0x23,0x5e,0x28,0x03,0x0d,0x4a,0x3d,0xdf,0xe6,0xd6,0xad,0x2c, 0x60,0xb9,0x4a,0xa9,0xf1,0x7b,0xdc,0x3d,0x84,0x83,0xe6,0xf1,0xcc,0x75,0xee,0xda, 0xc9,0x9b,0x42,0x9f,0x3d,0x99,0xef,0x3d,0x2a,0xcc,0x7c,0xdb,0x53,0x79,0x57,0xea, 0x2b,0xaa,0x3d,0x05,0x5a,0x7f,0x9c,0xa2,0xef,0x5a,0x06,0xb6,0xca,0x6d,0x94,0xdf, 0xd7,0x98,0xf7,0x9a,0x4c,0x2e,0x74,0x4c,0xe4,0x37,0xd8,0x2f,0x58,0xeb,0x19,0xeb, 0x62,0x97,0x6e,0x29,0xc8,0xa5,0xab,0x59,0x33,0x24,0xd8,0xc6,0x82,0x91,0x81,0x45, 0x8a,0xa3,0xd3,0x95,0xf2,0xad,0xca,0x1a,0x2c,0x03,0x13,0x6a,0x90,0xfa,0xf9,0x37, 0x09,0xd0,0x6b,0x12,0x86,0x06,0x66,0x0e,0x77,0xf8,0x24,0xe0,0x6d,0xc3,0xbc,0x40, 0x54,0x96,0xb7,0x71,0x96,0x07,0x25,0x5f,0x42,0x27,0xa9,0xc0,0x33,0xa5,0x9d,0x56, 0xec,0x59,0x4a,0x1a,0x38,0xb0,0x20,0xc0,0x1a,0xb7,0x47,0xe9,0xf3,0x58,0x9e,0x10, 0xfe,0xae,0xff,0x55,0x80,0x40,0x26,0x68,0xeb,0xcb,0xe0,0x75,0x68,0xb5,0x73,0xd5, 0xe4,0x1f,0x27,0x18,0x47,0x4e,0xe1,0x52,0x3c,0x3f,0xc3,0x29,0xbd,0x8f,0xef,0x74, 0x6d,0xd2,0x19,0x77,0x1f,0x5b,0x5f,0x6b,0x36,0xa7,0x16,0x21,0x0f,0x3c,0x5c,0xbe, 0x63,0x03,0x86,0x16,0x01,0xe0,0x9c,0xcb,0x76,0x96,0xa5,0xc4,0xc8,0xe8,0x42,0x66, 0x30,0x37,0x47,0xb4,0xa3,0x61,0x98,0xfe,0x46,0xac,0x94,0x98,0x70,0x3e,0x28,0x7d, 0x58,0x10,0x4e,0xc8,0x25,0xec,0x84,0xe8,0xb5,0xa5,0x23,0x3e,0xbe,0x9c,0xc4,0xce, 0x93,0x2f,0x2b,0xab,0x73,0xee,0x5c,0x65,0xbe,0x33,0x60,0x62,0x9e,0x7a,0x0d,0x75, 0xe9,0x9d,0x81,0xb5,0x49,0xfd,0x39,0xfe,0x86,0x6a,0xbd,0x4a,0x37,0x28,0xc7,0x17, 0xfa,0xdc,0xfb,0x19,0xd5,0x24,0x8c,0x64,0x5e,0xc5,0xbd,0x37,0xa0,0xcf,0x6a,0x92, 0x8c,0x9a,0xdc,0x46,0x70,0x9a,0xe8,0x29,0x71,0xa2,0xdc,0xc5,0xed,0xfa,0xa8,0x72, 0x0b,0x51,0x1e,0x9b,0x9f,0x2f,0x26,0x37,0x6c,0x36,0xb1,0xd4,0xec,0x02,0x02,0x22, 0x7e,0x4d,0xac,0x90,0xcb,0x0c,0x6a,0x42,0x06,0xfe,0x0e,0xbc,0x41,0x4d,0x1f,0xfa, 0x98,0x67,0x0f,0x29,0x83,0x1d,0xf0,0x30,0xe8,0x7c,0x17,0x50,0x6a,0xc4,0x82,0xff, 0x73,0x0e,0x35,0x57,0x9c,0x05,0xd9,0x58,0xcc,0x30,0xf7,0xa0,0xd2,0x18,0xb3,0xd4, 0xcf,0x1c,0x2d,0x3e,0x3c,0xe0,0x27,0x05,0xfc,0x92,0x4e,0x44,0x1a,0xf5,0xf4,0xf6, 0x20,0x4d,0xa3,0x57,0x61,0x6f,0x8d,0xdd,0xd2,0xf6,0x5b,0xcf,0x76,0x5a,0x7b,0x1b, 0xc5,0x87,0xa8,0x0e,0x48,0x03,0x4c,0x50,0xa8,0x8b,0xad,0xfa,0x0d,0x3a,0x4d,0x0f, 0x40,0xd0,0xf8,0xf1,0xbf,0x7f,0x21,0x5f,0x8f,0xe5,0x83,0x79,0x8c,0x03,0xf0,0x26, 0xfe,0xb6,0x13,0x4e,0x3f,0x14,0x51,0xaf,0xae,0x03,0xf6,0x45,0xe9,0x98,0x98,0xd4, 0x33,0xa1,0x5a,0xb8,0xe8,0x1c,0xef,0x69,0x4e,0xdf,0xf6,0x5a,0x50,0xa4,0x99,0x39, 0xed,0xe6,0xfa,0x45,0x08,0x50,0xc0,0x6b,0x2c,0xd1,0xe5,0xe9,0xc5,0xf3,0xe4,0xac, 0xbc,0x87,0x17,0x82,0x63,0x22,0x28,0x38,0x6b,0xb4,0xc5,0xaa,0x71,0x97,0xdc,0x2d, 0x54,0xb8,0x0c,0xeb,0xaa,0xef,0xe6,0x4a,0x66,0x9b,0x5e,0xf3,0x9f,0x60,0x79,0x35, 0xaf,0xf5,0x4e,0x0c,0x14,0xb8,0x65,0xc3,0x72,0xc8,0xe8,0xce,0x78,0x52,0xa2,0x88, 0xe8,0x72,0xfb,0xb9,0x42,0xb7,0x6a,0x66,0xe2,0xbf,0x61,0xa4,0x7c,0xe9,0x00,0xc4, 0xe5,0x26,0x00,0x59,0xe2,0x61,0x91,0x07,0xe7,0x9b,0x73,0x5e,0xb2,0xf9,0x49,0x97, 0x4c,0x39,0xd4,0xbb,0x78,0xf8,0x7b,0xa4,0xe4,0xb6,0xe7,0x28,0x16,0x83,0x2a,0xb8, 0xe1,0x7e,0x88,0x39,0x00,0xca,0x5a,0x57,0x58,0x17,0xeb,0xf1,0x1f,0x44,0xa3,0x3a, 0x19,0x4b,0x45,0x71,0x2a,0xc8,0xd7,0xa4,0x5c,0x13,0x39,0xed,0x1f,0xb7,0x4b,0xaa, 0xb0,0x29,0x98,0x22,0x43,0x15,0xb2,0xb1,0xa5,0x98,0x4c,0x44,0x4b,0x93,0x21,0xe7, 0x0c,0xa6,0x27,0xfb,0xe0,0xd5,0x54,0xdf,0x50,0x2d,0x9d,0xa9,0xda,0x6a,0xd4,0xd7, 0x45,0x86,0xd7,0x04,0xe1,0xa5,0xda,0xeb,0x6d,0xe1,0x06,0xaf,0xdd,0x5b,0x15,0x78, 0xf7,0x42,0xc2,0x24,0xd3,0x76,0xb2,0xc2,0xbd,0x2a,0x11,0x59,0x91,0x3a,0xa8,0xb7, 0xc8,0xaf,0x0a,0x28,0x56,0x86,0x8a,0x5b,0x87,0x7b,0xc1,0x30,0xdc,0x44,0x70,0xee, 0xde,0x38,0x95,0x16,0xb2,0xca,0x60,0xda,0x88,0xad,0xb0,0xc7,0x2b,0xe9,0xa9,0x87, 0x55,0xb7,0x1e,0x6c,0xda,0x14,0x92,0x49,0xe8,0x34,0xa7,0x4d,0x27,0xcd,0xaa,0x4a, 0xb2,0x43,0x20,0xe8,0x6d,0x5e,0x76,0xec,0x3e,0x8f,0x6e,0x66,0x66,0x73,0x09,0x6e, 0x6f,0x09,0x00,0xf1,0x18,0x44,0x49,0x7d,0x13,0xc7,0x8a,0x34,0xd2,0xd5,0x69,0x3f, 0x17,0x78,0xbb,0xc4,0x48,0x45,0x2b,0x83,0xef,0x52,0xbb,0x72,0x41,0xbe,0x96,0xf2, 0xbc,0x2a,0x20,0x0f,0xb9,0x69,0xcc,0x3c,0x28,0xe2,0x01,0xe0,0xe6,0x01,0xf4,0x27, 0x86,0xdf,0xbf,0xe6,0x07,0xb1,0xb1,0xed,0x08,0xd1,0x32,0x46,0x1d,0x04,0x89,0xce, 0x0e,0x57,0xc7,0x1e,0x69,0x65,0xda,0xb8,0xef,0x82,0x18,0x7b,0x40,0xc7,0xaf,0xed, 0xda,0x1d) $RemoteIpEndPoint = New-Object System.Net.IPEndPoint([system.net.IPAddress]::Parse("0.0.0.0"),0); $sentbytes = $udpClient.Send($byteBuffer, $byteBuffer.length, $remotesystem, $remoteudpport) try { $receive=$udpClient.Receive([ref]$remoteIpEndpoint) write-host "TTL $($_) Answer received" $result=[System.BitConverter]::ToString($receive); if ($result.Substring(3,11) -eq "FF-00-00-1D") { Write-host "QUIC- Draft-29 Header found" "200 OK" } else { Write-host "No QUIC- Draft-29 Header found" "400 UNKNOWN" } } catch { write-host "No Answer received" "500 NOANSWER" }
Über den Receive-Teil kann ich die Rückmeldung einsammeln. Das erste Antwortpaket hatte folgende UDP-Payload:
Wenn ich mich hier auf die Versionsnummer stütze, dann dürfte dies ein gutes Kriterium für eine QUIC-Gegenstelle sein. Entsprechend kann ich einfach prüfen.
if ($result.Substring(3,11) -eq "FF-00-00-1D") { Write-host "QUIC- Draft-29 Header found" }
Hier das ganze als PowerShell-Script.
test-quicconnection.20210602.ps1
Speichern Sie die TXT-Datei auf ihrem System und starten sie es einfach in einer PowerShell. By Default nutzt das Skript "www.facebook.com"
PS C:\> .\test-quicconnection.ps1 www.google.com 200 OK PS C:\> .\test-quicconnection.ps1 www.office.com 500 Timeout
Wenn der Aufruf zu www.google.com, www.facebook.com und anderen QUIC-tauglichen Gegenstellen nicht erfolgreich ist, dann blockt vielleicht ihre Firmenfirewall den Zugang per UDP auf Port 443
Aufgrund der Nutzung von UDP und mit mehreren Streams und eingebauter Verschlüsselung könnte ich mir gut vorstellen, dass sehr bald auch VoIP-Lösungen auf QUIC aufsetzen könnten.
Weitere Links
- PowerShell und UDP
- NGINX QUIC Test
https://quic.nginx.org/quic.html - QUIC Interop Runner
https://interop.seemann.io/