End2End-UDP3478

Für eine effektive Übertragung von Audio/Video eignet sich am besten eine direkte Verbindung per UDP. Da dies oft nicht geht, ist eine indirekte Verbindung per STUN/TURN erforderlich. Der dazu genutzte Port ist eigentlich immer 3478/UDP. Es ist daher wichtig einen Test zu haben, ob dieser Port erreichbar ist und wie weit er "weg" ist. Daher habe ich mir end2end-UDP3478 geschrieben.

Funktionsweise

Zuerst habe ich einer funktionierenden Verbindung auf die Finger geschaut. Mit dem Skype for Business Online Network Assessment Tool habe ich einen Test-Call ausgeführt und die ersten Pakete betrachtet. Sie sehen direkt einen "STUN Allocate Request" der aber ohne Anmeldedaten natürlich daneben geht. Aber mir reicht das um das anfragende Paket zu erhalten.

Diese Daten habe ich nun direkt als Byte-Array in meinem PowerShell-Script genutzt, um das gleiche Paket abzusenden.

$byteBuffer = @(0x00,0x03,0x00,0x54,0x21,0x12,0xa4,0x42,0xd2,0x79,0xaa,0x56,0x87,0x86,0x48,
                0x73,0x8f,0x92,0xef,0x58,0x00,0x0f,0x00,0x04,0x72,0xc6,0x4b,0xc6,0x80,0x08,
                0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x30,0x04,0x00,0x00,0x1c,0x00,
                0x09,0xbe,0x58,0x24,0xe4,0xc5,0x1c,0x33,0x4c,0xd2,0x3f,0x50,0xf1,0x5d,0xce,
                0x81,0xff,0xa9,0xbe,0x00,0x00,0x00,0x01,0xeb,0x15,0x53,0xbd,0x75,0xe2,0xca,
                0x14,0x1e,0x36,0x31,0xbb,0xe3,0xf5,0x4a,0xa1,0x32,0x45,0xcb,0xf9,0x00,0x10,
                0x00,0x04,0x00,0x00,0x01,0x5e,0x80,0x06,0x00,0x04,0x00,0x00,0x00,0x01)

Das Paket sende ich dann per UDP-Client (Siehe auch PowerShell und UDP) an die Adresse und warte auf die Antwort.

Der Verhalten bei Microsoft Teams ist sehr ähnlich, was den ersten Kontakt angehen: Wobei hier mehrere Ziel-IP-Adressen angesprochen werden.

Schaut man aber genau hin, dann gibt es auch hier Verbindungen, die wie bei Skype for Business einen "Allocate Bandwidth" machen. In meinem Beispiel ist es hier die 52.113.193.5 und eine Verbindung zu diesem Server funktioniert genau wie auch bei Skype for Business.

Erreichbarkeitstest

Um zu prüfen, ob die Gegenstelle erreichbar ist, sende ich dann einfach das Paket los. Auf meine Anfrage bekomme ich dann auch eine Antwort zurück, die ich mit dem gleichen UDP-Client annehmen kann. Die empfangenen Daten kann ich prüfen, ob es ein "STUN Allocate Error" ist und damit die erfolgreiche Verbindung über Port 3478 bestätigen. Selbst ohne eine genaue Prüfung ist schon allein der Empfang einer UDP-Antwort ein ausreichend guter Indikator, so dass folgender Code schon alle Merkmale mitbringt:

# Simple Skype for Business Online Edge Turn test
[int]$sourceudpport=50000
[int]$remoteudpport=3478
[string]$remoteip = "13.107.8.2"

$udpClient = new-Object System.Net.Sockets.Udpclient($sourceudpport) 
$udpClient.Client.ReceiveTimeout = 1000   
#$udpClient.Client.Blocking = $true

# Session Traversal Utilities for NAT
# STSUN Packet from SfB Network Assessment Tool
$byteBuffer = @(0x00,0x03,0x00,0x54,0x21,0x12,0xa4,0x42,0xd2,0x79,0xaa,0x56,0x87,0x86,0x48,
                0x73,0x8f,0x92,0xef,0x58,0x00,0x0f,0x00,0x04,0x72,0xc6,0x4b,0xc6,0x80,0x08,
                0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x30,0x04,0x00,0x00,0x1c,0x00,
                0x09,0xbe,0x58,0x24,0xe4,0xc5,0x1c,0x33,0x4c,0xd2,0x3f,0x50,0xf1,0x5d,0xce,
                0x81,0xff,0xa9,0xbe,0x00,0x00,0x00,0x01,0xeb,0x15,0x53,0xbd,0x75,0xe2,0xca,
                0x14,0x1e,0x36,0x31,0xbb,0xe3,0xf5,0x4a,0xa1,0x32,0x45,0xcb,0xf9,0x00,0x10,
                0x00,0x04,0x00,0x00,0x01,0x5e,0x80,0x06,0x00,0x04,0x00,0x00,0x00,0x01)

$RemoteIpEndPoint = New-Object System.Net.IPEndPoint([system.net.IPAddress]::Parse("0.0.0.0"),0);

$sentbytes = $udpClient.Send($byteBuffer, $byteBuffer.length, $remoteip, $remoteudpport)
try {
   $receive=$udpClient.Receive([ref]$remoteIpEndpoint)
   write-host "TTL $($_) Answer received"
   $result=[System.BitConverter]::ToString($receive);
}
catch {
   write-host "TTL $($_) NO Answer received"
}

So einfach ist schon mal die generelle Durchgängigkeit von einem Client zu einem Office 365 STUN-Server zu prüfen. Sie können natürlich daraus auch eine Überwachung machen. Allerdings ist ein STUN-Request noch kein RTP-Paket. Um für VoIP aussagekräftige Daten zu bekommen, sollten Sie schon RTP übertragen und dafür eignet sich das Skype for Business Online Network Assessment Tool viel besser.

Auswerten der Rückantwort

Ob ich nun wirklich einen STUN/TURN-Server erreicht habe, kann ich nur durch einen Vergleich der Antwort mit einem Sollwert überprüfen. Auch hier hilft mir WireShark mit, welcher die Antwort nicht nur anzeigt, sondern auch parst. Da es sein kann, dass die Antwort sich verändert, wollte ich nun nicht den kompletten Rückgabewert vergleichen sondern nur einen Teil davon.

Ich beschränke mich auf den Wert "01 13", der für einen "Allocate Error Response" steht und am Ende das "rtcmedia" steht. Das geht ganz einfach mit:

if ($result.startswith("01-13") -and $result.endswith("72-74-63-6D-65-64-69-61-22")){
   write-host "Edge reachable"
}
else {
   write-host "unexpected answer"
}

PRTG Modul

Ich habe das Skript dann gleich noch etwas erweitert, dass es als Custom Sensor unter PRTG eingesetzt werden kann. Es erweitert die Rückgabe dann einfach um eine XML-Struktur, die von PRTG ausgewertet wird. Der Einsatz unter PRTG ist als PRTG - Custom Sensor einzurichten. Nach einigen Stunden sollten Sie dann eine Grafik sehen:

Das ist mein T-DSL Anschluss zuhause, der interessanterweise nicht nur eine längere Latenzzeit in den Abendstunden aufweist (Netflix?) sondern dann auch die Anzahl der Hops anfängt zu schwanken. Da wäre es schon mal interessant, welche Stationen da genau durchlaufen werden. Auch sieht man gut, dass die Roundtriptime (RTT) in der Zeit auch zunimmt. Ich bin mal gespannt, wie die Werte bei Firmenanschlüssen aussehen.

Um aber mehr Details über die Leitwege zu bekommen, müsste ich einen Traceroute mit ICMP-Verarbeitung aufsetzen, was mit dem PowerShell UDP-Manager meines Wissens nicht so einfach möglich ist.

Aber auch so ist der Monitor sehr hilfreich um z.B. schnell zu erkennen, wenn eine Regeländerung der Firewall Port 3478 plötzlich sperrt oder Störungen im WAN zu größeren Umwegen führen. Insofern sollten Sie nach der Einrichtung des Sensors auch entsprechende Warn- und Fehlergrenzwerte samt Benachrichtigung in PRTG konfigurieren.

Bei einer Firmen-Installation hatte ich dann folgende Bild:

Die Entfernung ist eigentlich immer 12 Hops aber es gibt auch hier die ein oder andere Veränderungen im Routing. Seit dem 26.12.2018 scheint der HopCount sich auf höherem Niveau stabilisiert zu haben. Die Roundtrip-Time ist dadurch zumindest noch nicht sichtbar schlechter geworden. Auch hier ist eine Betrachtung über mehrere Monate natürlich interessant. Der Sensor lief aber erst einige Wochen.

Die End2End-UDP3478 Funktion ist aber nicht auf Office 365 beschränkt. Sie können damit jeden TURN-Server, also auch den eigenen Edge-Server testen. Das funktioniert auch von einer Niederlassung über das eigene WAN zum Edge-Server in der Hub-Site. Hier sollten Sie dann natürlich deutlich schnellere Werte erhalten:

Ergänzend zu dem Sensor können Sie natürlich auch mit anderen Sensoren weiter Daten ermitteln:

Download/Tool

Das folgende PowerShell-Script können Sie einfach interaktiv starten oder als Custom-Sensor in PRTG einbinden. Über den Parameter "Remote-IP" könne sie ihren eigenen Edge-Server einbinden. Wenn Sie "o365" oder "teams" eingeben, nutzt das Skript hinterlegte IP-Adressen, die aber zukünftig ggfls. falsch sein können.

Wenn Sie eine PRTG-URl addieren, dann können die Ergebnisse auch über einen PRTG - HTTP Push-Sensor senden.

end2end-udp3478.ps1

Beim einfachen Aufruf sehen Sie die Aktionen interaktiv:

Ich habe mittlerweile die Detailausgaben alle mit "Write-Verbose" versteckt und mittels Farbe die Antworten sichtbar gemacht. Die Daten landen natürlich auch in der CSV-Datei für spätere Auswertungen und können auch z.B. an PRTG gesendet werden.

Weitere Links