Teams und HTTP Proxy Caching
Bandbreite kann man angeblich nie genug haben aber sie ist nicht endlos. Diese Seite beschreibt, wie ein Proxy-Server mit Caching z.B. die Ladezeiten von Teams und Apps optimieren kann. Auch die Bandbreite von Teams LiveEvent und Teams Townhall Meetings kann ein korrekt konfigurierter Proxy optimieren.
Spoiler: Der Einsatz von einem internen HTTP-Proxy zum Cachen von bestimmten Inhalten ist möglich und kann sinnvoll sein. Aber Sie müssen SSL-Inspection für die gewünschten Ziele aktivieren.
Teams Datenströme
In aller Kürze möchte ich noch einmal auf die Teams Media-Steams und Übertragungen eingehen, denn nur ein ganz kleiner Teil ist "Proxy-tauglich".
Workload | Protokoll | Daten | Cache möglich/sinnvoll |
---|---|---|---|
Teams Application (HTML, JavaScript, CSS, Bilder, Klingeltöne (.mp3) etc.) |
HTTPS |
Identisch |
Ja/Ja |
Teams Daten (Präsenz, Chat, Gruppendiskussionen, OneDrive Zugriffe) |
HTTPS |
Individuell |
Nein/Nein |
Teams 1:1 Audio/Video |
UDP/TCP/HTTP |
Individuell |
Nein/Nein |
Teams N:M Meeting Audio/Video |
UDP/TCP/HTTP |
Individuell |
Nein/Nein |
Teams LiveEvent/Townhall Meeting Producer |
UDP/TCP/HTTP |
Individuell |
Nein/Nein |
Teams LiveEvent/Townhall Teilnehmer |
HTTPS |
Identisch |
Ja/Ja |
Teams LiveEvent/Townhall eCDN Teilnehmer |
Websocket und P2P-UDP |
Identisch |
Nein/Nein |
Es bleiben also nur zwei Datenübertragungen überhaupt im Fokus, da alle anderen Übertragungen entweder individuelle Inhalte sind und im Cache keinen Sinn machen oder als P2P-Traffic sowieso nicht durch einen Proxy laufen würden oder laut Microsoft am besten am Proxy vorbei geroutet werden sollten. Aber auch für die beiden grünen Übertragungen müssen wir noch einmal hinschauen, ob ein Cache hier auch funktionieren kann.
HTTPS und Caching
Damit Datenübertragungen von einem HTTP-Proxy tatsächlich auch gecached werden, müssen einige Voraussetzungen erfüllt sein.
- Sichtbarkeit und SSL Inspection
Der Proxy muss natürlich den Request sehen und verstehen. Das funktioniert nur mit HTTP-Verbindungen ohne besondere Vorarbeiten. Da mittlerweile aber die überwiegende Anzahl an Verbindungen auf HTTPS setzt, sieht ein Proxy-Server nur die "CONNECT"-Anforderung und danach nichts mehr. Für ein Caching von HTTPS-Verbindungen ist es zwingend erforderlich, dass der Proxy eine SSL-Inspection für diese URLs umsetzt.
Microsoft stellt speziell die Updates nicht per HTTP bereit, da TLS nicht nur die Verschlüsselung erlaubt, sondern vor allem sicherstellt, dass Sie den richtigen Server erreicht haben und die Daten bei der Übertragung nicht verändert wurden. Das ist insbesondere für Code wichtig. - Cacheable URL
Wenn mehrere Clients die gleichen Informationen abrufen, dann sollten alle auch die gleiche URL nutzen. Wenn Webseiten dahinter aber Parameter oder sei es nur Tracking-Daten addieren, dann ist das für den Proxy eine andere URL und damit nicht mehr für den Cache relevant. - Authentifizierung
Aber auch eine gleiche URL bedeutet nicht unbedingt, dass auch der gelieferte Inhalt identisch ist. Wenn zwei Nutzer die gleiche URL aber unterschiedlichen vorherigen Anmeldungen aufrufen, dann wäre eine Auslieferung der falschen Daten aus dem Cache natürlich ein Problem. Eine gute Webapplikation sollte solche Daten natürlich mit einem sehr kurzen Timeout oder als "nicht Cachebar versehen. - Server Cache Timeout
Ich habe aber auch schon Webseiten gesehen, die serverseitig einen sehr kurzen Cache oder "NoCache" einstellen, um die Zugriffe mehrerer Personen hinter einem Proxy zählen zu können. Sicher kann ein Proxy einen HEAD-Request absetzen, um die Aktualität seines Cache zu prüfen aber letztlich entscheidet der Webserver, ob er ein "not modified" oder "modified" ausliefert und damit den Cache untauglich macht. - Client Cache Request
Aber auch der Client kann dem Proxy-Server befehlen, dass er die Daten nicht aus dem Cache sondern aus dem Original bekommen möchte.
Daher müssen wir uns den ein oder anderen Request einfach mal anschauen. Übrigens hat natürlich auch ihr Client eine Cache und speichert statische Inhalte lokal zwischen. Einige Browser laden sogar schon vorsorglich weitere Seiten, damit sie beim Anklicken schneller erscheinen und auch Webseitenbetreiber können z.B. mittels JavaScript weitere Inhalte schon einmal anfordern. Wie immer gibt es zu dem Thema auch eine RFC und viele weitere Seiten:
- HTTP Cache Headers - A Complete Guide
https://www.keycdn.com/blog/http-cache-headers
HTTP-Feld: Cache-Control
Die Steuerung des Cache erfolgt seit HTTP 1.1 über das Feld "Cache-Control", welches mehrere Wert enthalten kann. Das Feld kann sowohl beim Zugriff vom Client zum Server als auch vom Server zum Client gesetzt sein. Hier ein Beispiel von Firefox beim Zugriff auf https://www.msxfaq.de und die Antwort darauf
GET / HTTP/1.1 Host: www.msxfaq.de User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: de,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate, br Connection: keep-alive Cookie: _ga=GA1.1.2132152683.1629900119; _ga_FMY31V3QXY=GS1.1.1703017660.8.0.1703017670.0.0.0 Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 If-Modified-Since: Wed, 06 Dec 2023 23:56:01 GMT If-None-Match: "57b5-60be017d9e640-gzip"
Hier wird erst einmal kein "Cache-Control" gesetzt aber anscheinend hat Firefox eine ältere Version in seinem Cache und nutzt den Header "If-Modified-Since", um dem Webserver eine passende Antwortmöglichkeit zu geben, z.B. ein "Not modified" zu senden. Die Antwort auf den Request enthält folgende Header:
HTTP/1.1 200 OK Date: Fri, 29 Dec 2023 19:07:41 GMT Content-Type: text/html Content-Length: 6523 Connection: keep-alive Server: Apache X-Frame-Options: SAMEORIGIN Last-Modified: Tue, 26 Dec 2023 02:13:27 GMT ETag: "595a-60d603a55ffc0-gzip" Accept-Ranges: bytes Cache-Control: private, must-revalidate Expires: Fri, 29 Dec 2023 19:16:01 GMT Vary: Accept-Encoding Content-Encoding: gzip Referrer-Policy: origin-when-cross-origin X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000; includeSubDomains Permissions-Policy: interest-cohort=()
Sie sehen hier gleich mehrere Felder, die das Caching beeinflussen, z.B. Last-Modified, ETag, Cache-Control und Expires. Das Feld "Cache-Control" enthält hier nur "private, must-revalidate". Es können aber noch weitere Werte gesetzt sein, z.B.:
Feld |
Bedeutung |
---|---|
max-age |
Anzahl in Sekunden, die eine Antwort genutzt werden darf |
s-maxage |
Dauer in Sekunden, die der Inhalt in einem Shared Cache vorgehalten werden darf. |
must-revalidate. |
Der Cache muss die Quelle erneut fragen und die Gültigkeit prüfen |
proxy-revalidate |
Weist den Proxy separat an, eine Information erneut zu überprüfen |
no-transform |
Der Inhalt darf nicht verändert werden, z.B. "Content-Encoding" etc. |
Beachten Sie, dass diese Header nicht Teil der HTML-Datei auf einem Webserver sind sondern vom Webserver (.htacces) oder einem Script gesetzt werden können.
Neben dem Feld "Cache-Control" gibt es auch weitere native Felder:
Feld |
Bedeutung |
---|---|
Expires |
Zeitpunkt, ab wann die Information nicht mehr gültig ist |
pragma |
Alter früherer Eintrag um Caching zu steuern |
ETag |
Wenn eine Information abgelaufen ist, müsste der Client oder Proxy die komplette Seite wieder holen. Der Webserver kann aber eine eindeutige Zahl im Feld "ETAG" hinterlegen. Wenn dann der Client oder Server beim Revalidieren nur den Header holt und sich der ETag nicht geändert hat, dann ist die Information im Cache wieder gültig |
Last-Modified |
Zeitpunkt der letzten Änderung. Als "max-age", "Expires" etc. noch nicht genutzt wurden, haben einige Clients die Dauer seit der letzten Änderung als Anhaltspunkt für die weitere Gültigkeit missbraucht. |
- RFC 7234 Hypertext Transfer Protocol (HTTP/1.1): Caching
https://datatracker.ietf.org/doc/html/rfc7234 - RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1
https://www.ietf.org/rfc/rfc2616.txt - 13 Caching in HTTP
https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html - Cache-Control
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control - HTTP.DEV: Cache-Control
https://http.dev/cache-control
Teams Client im Browser
Ausgestattet mit diesen Informationen können wir nun mal schauen welche Clients für welche Zugriffe ein Caching erlauben oder nutzen würden. Dazu zählt natürlich auch der Teams Client und insbesondere Updates. Zuerst habe ich dazu Microsoft Teams in einem neuen Browser-Fenster gestartet, welches aber früher schon einmal Teams gestartet hatte. Damit erwarte ich dass im Cache schon eine "alte Teams-Version" oder zumindest alte Bestandteile zu finden sind. Da Microsoft Teams als "Moderne App" ja quasi in JavaScript geschrieben ist und das keine große monolithische JS-Datei ist, habe ich jede Menge Requests gesehen:
Auch statische Inhalte wie z.B. die MP3-Dateien der Klingeltöne werden geladen. Wenn Sie die "Size" anschauen, dann sind das schon einige Kilobyte, die da pro Client zusammen kommen, wenn diese nicht mehr im lokalen Cache vorliegen.
Sie können aber auch gut erkennen, dass Microsoft für die statischen Inhalte extra einen eigenen Hostnamen nutzt:
https://statics.teams.cdn.office.net
Die Daten kommen hier nicht von https://teams.microsoft.com, sondern einem eigenen Content Delivery-Netzwerk für statische Inhalte. Damit entlastet Microsoft natürlich die eigentlichen Teams-Services, die dann nur noch die individuellen Daten liefern müssen und die CDN-Server können näher bei dem Kunden stehen. Die DNS-Anfrage zeigt auch auf Dienste von Akamai:
C:\>nslookup statics.teams.cdn.office.net Name: a1813.dscd.akamai.net Addresses: 2a00:6020:100:800::b916:8c10 2a00:6020:100:800::b916:8c11 185.22.140.17 185.22.140.16 Aliases: statics.teams.cdn.office.net teams-staticscdn.trafficmanager.net statics.teams.cdn.office.net-c.edgesuite.net statics.teams.cdn.office.net-c.edgesuite.net.globalredir.akadns.net
Die Bereitstellung erfolgt (Stand Dez 2023) per Geo-DNS und nicht über Anycast-Routing. Abhängig vom jeweils gefragten DNS-Server kommen andere Adressen zurück. Sie sollten auf jeden Fall sicherstellen, dass ihr Namensauflösung immer entlang des IP-Routings verläuft.
Die Klingeltöne sind natürlich dankbare Dateien, die sich nicht ändern, anonym erreichbar sind und cachebar sind. Ein Request vom Client zum Server war:
Die Antwort liefert die 304353 Bytes MP3-Datei aber auch die Information, dass diese Datei "public" und 365 Tage gepuffert werden darf!
Zudem liefert der Server ein eindeutiges "Etag"-Feld mit, so dass ein Proxy oder Client auch später noch einmal nachfragen kann, ob er die Datei neu laden muss. Haben Sie auch das Feld "Last-Modified" gesehen? Die Datei ist tatsächlich schon einige Monate unverändert. Wer sie sich anhören möchte. Hier ist der Link:
https://statics.teams.cdn.office.net/hashed/audio/ring-fb90357.mp3
Ein Download ist auch nicht schwer:
Invoke-WebRequest ` -Uri https://statics.teams.cdn.office.net/hashed/audio/ring-fb90357.mp3 ` -OutFile ring- fb90357.mp3
Es ist der 8 Sekunden lange "Klingelton", wenn Sie mit Teams einen anderen Teilnehmer anrufen.
Ich frage mich schon, ob ein Freizeichen wirklich mit 48kHz, Stereo und 32Bit bei 320kB/s gesampelt werden muss, wenn die meisten MP3-Songs mit 128kBit oder 196kBit und 8-Bit Stereo codiert sind. Das weiß aber wohl nur Microsoft, warum 8 Sekunden 297kByte groß sein müssen, wo doch auch 120kbyte reichen würden.
Wir haben also durchaus Potential durch ein Caching hier Bandbreite zu sparen. Da diese Dateien sogar von einem eigenen Hostnamen kommen, könnten Sie über eine "proxy.pac"-Datei gezielt diese Zugriffe über einen Proxy leiten.
Leider habe ich keine Daten einer produktiven Cache-Instanz, die das Einsparungspotential aufzeigen könnte.
In dem Zuge habe ich mal schauen wollen, was denn auf meinem Client im Cache liegt. Ich musste feststellen, dass es mit modernen Browsern gar nicht mehr so einfach ist, über das Dateisystem den Cache anzuschauen. Im Browser selbst wird nur noch die Größe angezeigt und das Löschen angeboten. In den Verzeichnissen liegen nur scheinbar zufällig benannte Dateien.
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache\Cache_Data %LOCALAPPDATA%\Microsoft\Edge\User Data\Profile 1\Cache\Cache_Data
Aber es gibt Dritthersteller wie z.B. Nirsoft, die einen Einblick erlauben:
- Nirsoft: Chrome Cache View
https://www.nirsoft.net/utils/chrome_cache_view.html
Ich kann hier jede Datei einzeln anschauen und vor allem die Cache-Control-Werte sehen. Hier am Beispiele eines Benutzerfotos.
Diese Information wird also bis zu 5184000 Sekunden (=60 Tage) gehalten. Folgende Cache-Zeiten habe ich gefunden:
Information | Cache-Control |
|
|
---|---|---|---|
Teams Benutzerfoto https://teams.microsoft.com/api/mt/emea/beta/users/8:orgid:<guid>/profilepicturev2?displayname=<name>&size=HR64x64 |
private, max-age=5184000, stale-while-revalidate=5184000 |
|
|
Teams Klingelton https://teams.microsoft.com/assets/audio/ring.mp3 |
public,max-age=31536000 |
|
|
Teams JavaScript https://teams.microsoft.com/ ... /Serviceworker.js |
no-transform, max-age=5400, private |
|
|
Teams JavaScript https://statics.teams.cdn.office.net/ ... teams_enterprise_m24.js |
public, max-age=604800 |
|
|
Sharepoint https://static2.sharepointonline.com/files/fabric/assets/icons/fabricmdl2icons.woff2?2.21 |
public, max-age=23318415 |
|
|
Auch viele anderen Firmen, z.B. Facebook etc. nutzen JavaScript-Dateien, die einen "hashwert" als Dateinamen haben und im Cache durchaus 365 liegen können. Das ist auch nicht sonderlich schlimm, wenn sie als Betreiber der Webseite eine neue Version ihres JavaScript mit dem geänderten Hashwert Bereitstellung und verlinken.
Durch die Technik die Datei mit einem Hashwerte zu bekennen erlaubt es dem Cache die Dateien lange vorhalten. Er muss auch nicht regelmäßig deren Aktualität prüfen. Sie ändern sich nämlich nie aber werden irgendwann einfach nicht mehr verwendet.
Das macht es aber natürlich interessant, diese Dateien auch entsprechend zu cachen.
Teams 2.1 Client Update
Deutlich kniffliger ist die Analyse des Teams Update. Der vollwertige Teams-Client lädt die Updates ja im Hintergrund herunter und startet dann einfach durch. Auf der Seite Teams Client Update habe ich für den "classic Client" den Prozess auseinander genommen. Der New Teams Client / Teams 2.1 nutzt allerdings eine andere Technik. Mittels "Get-AppxPackage" kann ich einen installierten Teams Clients ermitteln aber es gibt kein "Update-AppxPackage" um eine Aktualisierung zu starten.
PS C:\> Get-AppxPackage -Name MSTeams RunspaceId : 1bdabcb3-53dd-4979-871d-58256d82bed7 Name : MSTeams Publisher : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US PublisherId : 8wekyb3d8bbwe Architecture : X64 ResourceId : Version : 23320.3021.2567.4799 PackageFamilyName : MSTeams_8wekyb3d8bbwe PackageFullName : MSTeams_23320.3021.2567.4799_x64__8wekyb3d8bbwe InstallLocation : C:\Program Files\WindowsApps\MSTeams_23320.3021.2567.4799_x64__8wekyb3d8bbwe IsFramework : False PackageUserInformation : {} IsResourcePackage : False IsBundle : False IsDevelopmentMode : False NonRemovable : False Dependencies : {} IsPartiallyStaged : False SignatureKind : Developer Status : Ok
Im Installationsverzeichnis findet sich auch eine "AppxManifest.xml" mit dem Hinweis auf die im gleichen Verzeichnis liegenden "ms-teamsupdate.exe". Das Programm hat aber weder eine Hilfe noch reagiert es auf Parameter. Also musste ich eine alte VM reaktivieren, auf der ein alter neuer Teams Client installiert war und mit Fiddler betrachten, welche Daten Teams nachlädt. Wie erwartet werden jede Menge JavaScript-Dateien vom Task "msedgewebview2" geladen.
Fast alle Dateien haben die Cache-Control-Eintrag auf "public" und "max-age: 31556926" erlaubt ein Caching für etwas mehr als 365 Tage. Es gibt keinen "Authentication Header", d.h. der Abruf ist anonym möglich, was ich per PowerShell auch einfach verifizieren konnte.
Das bedeutet aber hier, dass ein HTTP-Proxy mit SSL-Decryption und Cache für die URL "statics.teams.cdn.office.net" ziemlich viel Bandbreite sparen kann, insbesondere wenn viele Clients an einem Standort sind.
Sie können zwar aus den Zugriffsprotokollen im Proxy dann sogar sehen, welche Client-IP sich schon die Updates gezogen hat, aber zur Inventarisierung gibt es bessere Ansätze, z.B. "Get-AppxPackage -Name MSTeams".
- Get-AppxPackage
https://learn.microsoft.com/de-de/powershell/module/appx/get-appxpackage - Packen, Bereitstellen und Abfragen von Windows-Apps
https://learn.microsoft.com/de-de/windows/win32/appxpkg/appx-portal - Updates für App-Pakete
https://learn.microsoft.com/de-de/windows/msix/app-package-updates - Appx
https://learn.microsoft.com/en-us/powershell/module/appx/
Teams A/V-HTTPProxy Caching
Bislang haben wir uns um die relativ statischen Installationsquellen gekümmert. Der neue Teams Client hat einen Umfang von ca. 130MByte (Dez 2023) und wenn 1000 Clients an einem Standort eine neue Version beziehen, dann kann ein Caching hier 130 Gigabyte Transfervolumen sparen. Das kling viel aber ist nichts im Gegensatz zu einem Meeting.
Schon am Anfang habe ich beschrieben, dass die klassischen Teams 1:1-Verbindungen und Teams Konferenzen gar nicht über HTTPS laufen sondern sinnvollweise ihre Bilder und Töne über UDP übertragen. Selbst wenn Sie Teams zu HTTPS zwingen, wird ein Proxy mit Caching nicht bringen, da jeder Teilstream individuell verschlüsselt ist.
Wenn es aber um sehr große Teams-Meetings geht, die als LiveEvent/Townhall-Meeting übertragen werden, dann kommt wieder HTTPS zum Einsatz und hier ist kann ein geeigneter Proxy Bandbreite sparen. Hier macht es auch Sinn, wenn eine Teilnahme an einem Townhall-Meeting mit Audio und Video generiert auch gerne mal 1-2 Megabit/Sekunde. 8 Sekunden sind dann schon mindestens 1 Megabyte und nach 17 Minuten haben wir schon die gleiche Datenmenge übertragen, die ansonsten durch die Installation verbraucht wurde.
Die benötigte Bandbreite ist dabei im Zeichen von "Flatrates" weniger ein Kostenproblem sondern einfach eine Kapazitätsfrage. Dabei müssen Sie den kompletten Pfad von dem Client bis zum ausliefernden Service betrachten, d.h. ihr LAN, ihre Firewall und ihr Internetanschluss aber genauso gut auch die Kapazitäten beim Provider und sein Peering zu Microsoft oder seinem Upstream-Provider.
Live Events und Teams Townhall Meetings sind natürlich nicht so zeitkritisch wie ein klassisches Meeting und alle Teilnehmer sehen exakt die gleiche Information. Da stellt sich dann schon die Frage, ob der Request und die Daten durch einen HTTP-Proxy als Cache optimiert ausgeliefert werden können. Bei Microsoft finde ich dazu:
Das klingt doch schon einmal vielversprechend. Allerdings ist da ein "Aber" mit im Bild, denn ein HTTP-Proxy kann nur cachen, was er "sieht". Aber selbst dies zumindest beschrieben aber bestätigt damit auch, dass es funktionieren kann:
Allerdings hält diese Seite noch eine weitere Aussage bereit, die explizit auf die SSL-Inspektion eingeht und zwei Domains nennt, die man bitteschön von der SSL-Inspektion ausnehmen und idealerweise sogar als Bypass durchlassen sollte:
Beide Adressen sind auch in den Office 365 IP-Adressen aufgeführt. Allerdings ist "bmc.cdn.office.net" nur unter "*.office.net" einzuordnen. Der "*" bedeutet also auch weitere Subdomains.
Eine weitere Fundstelle ist:
Das ist nun gerade nicht, was ich erhofft habe.
Ich hätte mir gewünscht, dass die HTTP-GET-Requests auf die Media-Blöcke unverschlüsselt erfolgen würden und die Payload mit einem für alle Teilnehmer kleinen Meetingkey verschlüsselt ist und damit HTTP-Proxy-Server ganz ohne SSL-aufbrechen ein Caching durchführen können.
Ich habe dann ein LiveEvent/Townhall-Meeting gestartet und auf zwei PCs als Teilnehmer die Pakete mit Fiddler mitgeschnitten.
Fiddler-Ausschnitt Live Event Teilnehmern
Ca. alle 2 Sekunden wird ein Audio-Ausschnitt und ein Video-Ausschnitt per HTTPS von Microsoft heruntergeladen. mit 20kByte Audio/Sekunde kommen wir auf 10KBytet/Sek oder ca. 100kbit. Die Datenmenge bei Video ist natürlich deutlich höher, die 12 Abschnitte über eine Zeit von ca. 20 Sekunden haben ca. 2,2MByte was auf ca. 1100kBit/Sek auf einen 720p-Stream hinweist. Hier ein exemplarischer Request und die Antwort:
Im Request gibt es keinerlei Hinweis auf eine Art "Authentication", d.h. weder Cookies, noch "Authentication"-Header oder Formularfelder oder Individualisierung für den Teilnehmer . Ein Abruf per Invoke-Webrequest funktioniert tatsächlich und liefert die Datei.
Interessant sind hier auch die Header im Bezug auf Caching, die Fiddler sehr schön auseinandernimmt.
HTTP/200 responses are cacheable by default, unless Expires, Pragma, or Cache-Control headers are present and forbid caching. HTTP/1.0 Expires Header is present: Tue, 02 Jan 2024 02:43:25 GMT Legacy Pragma Header is present: IISMS/6.0,IIS Media Services Premium by Microsoft !! WARNING: IE supports only an EXACT match of "Pragma: no-cache". IE will ignore the Pragma header if any other values are present. HTTP/1.1 Cache-Control Header is present: max-age=259200 max-age: This resource will expire in 72 hours. [259200 sec] HTTP/1.1 ETAG Header is present: "Ny8xNS8yMDEz"
Die Daten könnten also bis zu 72 Stunden im Cache gehalten werden. Das Feld "X-Cache" im Header gibt gut Auskunft, ob die Daten aus dem Cache des Content Delivery Netzwerk (CDN) oder erst vom Ursprungsserver geholt werden mussten.
Quelle:
https://learn.microsoft.com/de-de/azure/cdn/cdn-msft-http-debug-headers#response-header-format
Das AzureCDN ist quasi auch "nur" ein Proxy mit Cache, der hier aber nun in Gegenrichtung konfiguriert ist, d.h. als Reverse Proxy. Da ich das Meeting einige Wochen nicht genutzt habe, liegen die Informationen dann nur noch auf dem Heimserver und der Reverse Proxy kann sie Sie nicht aus seinem Cache liefern. Daher finde ich ein Feld "X-Cache:TCP_MISS" im Header.
(Invoke-Webrequest ` -URI ("http://endpoint1-s00prddencompsvc.prd.bmc.cdn.office.net/" ` +"b1080223-6624-401c-816d-c79e9cbcc912" ` +"/9fe43086-dcaf-4e4d-bdbb-0bcdcb7598f7.ism" ` +"/QualityLevels(96000)/Fragments(audio=10848337280,format=mpd-time-csf)")).headers."X-Cache"
Wenn ich mir die URL zweimal hole und den Header "X-Cache" anschaue, dann sehen sie beim ersten Aufruf auch den "TCP_MISS" und dem Folgeaufruf den "TCP_HIT".
Sobald mehrere Clients bei Microsoft über den gleichen Cache-Server die Daten abrufen würden, könnte Microsoft die Daten aus dem Cache ausliefern und im Header ein "X-Cache: TCP_HIT" setzen. Ich habe auch den Wert "TCP_REMOTE_HIT" gefunden. Anscheinend meldet das dann eine Proxy, der die TLS-Verbindung aufgebrochen hat. In dem Fall war es das Azure CDN, welches als Reverse Proxy den Zugriff von Extern aus dem Cache bedient.
Das wirft nun natürlich wieder Fragen auf, wie Microsoft z.B. mehrere Clients aus der gleichen Region zum gleichen Cache weiterleiten. Bei ausgehenden Proxy-Servern kenne ich das Verfahren den Hostnamen zu einem numerischen Hashwert zu konvertieren und durch die Anzahl der Proxy-Server zu teilen. So sollten alle Clients beim Zugriff auf das gleiche Ziel immer den gleichen Proxy nutzen, was die Cache-Trefferrate erhöht.
HTTP statt HTTPS
Ich habe aktuell keinen Test dahingehend gemacht, die Verbindung per HTTPS zu "*.cdn.office.net" zu verbieten und darauf zu hoffen, dass der Client vielleicht auf HTTP umschwenkt und damit ein HTTP-Proxy auch ohne TLS-Inspection. Aber die URLs sind auch ohne HTTPS erreichbar.
Theoretisch könnte ein Townhall Meeting Client die Daten auch ohne HTTPS herunterladen und entsprechen ein Proxy ohne SSL-Inspection ein Caching vornehmen. Wenn ich dies mit meinem lokalen Squid Proxy probiere, dann sehe ich im Header X-Cache sogar beide Einträge:
Allein die Tatsache, dass die Verbindung auch unterschlüsselt per HTTP möglich ist, ist keine Zusicherung, dass dieser Weg auch genutzt würde. Theoretisch könnte ich auf einem Proxy Server den HTTPS-Zugriff auf die verschiedenen Streams-Endpunkte von Microsoft unterbinden und darauf hoffen, dass der Townhall Client vielleicht auf HTTP schwenkt und mir damit das Caching vereinfacht. Ich habe dies aber nicht ausprobiert, da Microsoft, der Proxy und der Client dann ja nicht mehr sicher sein könnten, dass sie wirklich den richtigen Stream betrachten. HTTPS ist ja nicht nur eine Frage der Verschlüsselung sondern auch der Überprüfbarkeit der Gegenstelle anhand des Zertifikats und quasi einer Signatur. In Zeiten von SEO-Marketing, Suchmaschinen, Let's Encrypt und der starken Verbreitung von TLS gehe ich auch nicht davon aus, dass der Townhall-Client auf HTTP umsteigen würde.
Auch die Pflege der per HTTPS zu unterbindenden Gegenstellen wäre eine aufwändige und sicher nicht 100% zuverlässige Tätigkeit. Sie können ja auch nicht pauschal den Zugriff auf "*.office.net" oder "*.cnd.office.net" unterbinden. Ein CDN kann ja auch Code, z.B. Updates, JavaScript etc., bereitstellen, bei denen die Authentizität sichergestellt sein muss.
Wenn nach einigen Monaten der Inhalt aber verfallen ist, dann kommt folgender Fehler:
Invoke-Webrequest : 41025007Asset streaming locator has expired. Please try changing the access policy on the locator.9b34e212-c6be-408a-b2d5-53d4ed3f8ff20f4496cd-4476-4e25-872d-823163c127cf
Wenn Sie A/V-Streams von Townhall-Meetings durch einen HTTPS-Proxy cachen wollen, dann funktioniert das nach meiner Einschätzung nur, wenn der Proxy die TLS-Verbindung aufbricht und so die Requests und Antworten im Klartext sieht.
Verifikation
Bislang waren alle Ausführungen nur Ergebnisse meiner Analysen und Textumgebung aber basieren nicht auf realen Messwerten bei Kunden. Es ist schon etwas aufwändiger, in einer kleinen Labor-Umgebung mehrere Clients bereitzustellen und einen Proxy-Server mit Cache SSL Inspection und Logging zu betreiben. Zudem wären aufgrund der kleinen Stichprobe die Ergebnisse mit Vorsicht zu betrachten.
Hier wäre ich dann doch mal auf Rückmeldungen aus der Leserschaft angewiesen, die Daten bereitstellen würden wie:
Anzahl Clients |
Verwendeter Proxy |
SSL Inspection Aktiv |
Cache-Größe |
Teams Code Total/Cache |
LiveEvents/Townhall Total/Cache |
---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Die Frage bleibt nun aber, ob ein HTTP-Proxy, der die Verbindung per TLS-Inspection aufbricht, die Inhalte vernünftig cachen kann. Dazu müsste ich einen HTTP-Proxy mit TLS Inspection für die fraglichen URLs UND Caching konfigurieren. Oder vielleicht würde Teams auch ohne SSL ein Rückfall auf HTTP machen?. Alles noch offene Fragen.
Das klingt alles interessant, aber
dürfte mehrere Tage Aufwand bedeuten, die ich aktuell noch
nicht aufgewendet habe. Vielleicht ist ein Kunde ja bereit,
mit mir so ein Setup komplett durchzuspielen.
Und das ist sicher ein Thema für eine eigene Seite auf der
MSXFAQ
Fiddler wäre ein schnell aufzusetzender SSL-Inspection Proxy, der aber leider keinen Cache bereitstellt. Basierend auf meinen Vorarbeiten von Squid-Proxy auf WSL mit Kerberos würde ich eher Squid einsetzen. Squid dürfte auch der Unterbau auf vielen Appliances und Firmen sein.
- Websockets
- Squid-Proxy auf WSL mit Kerberos
- Intercept HTTPS CONNECT messages with
SSL-Bump
https://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit - Configure Squid proxy for SSL/TLS
inspection (HTTPS interception)
https://scubarda.com/2020/03/23/configure-squid-proxy-for-ssl-tls-inspection-https-interception/
https://github.com/gmellini/squidproxy-conf - Proxy servers for Teams and Skype for
Business Online
https://learn.microsoft.com/en-us/microsoftteams/proxy-servers-for-skype-for-business-online - Azure CDN Coverage by Metro
https://learn.microsoft.com/en-us/azure/cdn/cdn-pop-locations - Edge Caching for Media Delivery
https://learn.microsoft.com/en-us/iis/media/iis-media-services/edge-caching-for-media-delivery - Configure and Enable Disk Cache in
Application Request Routing
https://learn.microsoft.com/en-us/iis/extensions/configuring-application-request-routing-arr/configure-and-enable-disk-cache-in-application-request-routing
Irreführend, weil das ein Cache auf der Anbieterseite ist. - Windows Media Server or Web Server?
https://learn.microsoft.com/en-us/iis/media/windows-media-services/windows-media-server-or-web-server
eCDN und Websockets-Caching
Wer eine eCDN-Lizenz für all seine Anwender kauft, kann natürlich auch anstatt des HTTP-Proxy-Servers auf die interne Verteilung von Client zu Client setzt. Dazu laden sich wenige Clients die A/V-Daten von Microsoft und verteilen diese intern weiter. Interessanterweise nutzt Microsoft dazu nicht HTTPS-Download von 2 Sekunden langen Blöcken, sondern die Clients verbinden sich über Websockets mit dem Server.
Ein Proxy-Server kann die Nutzung von Websockets unterbinden oder zulassen. Allerdings ist das Kommunikationsverhalten dabei komplett unterschiedliche. Bei der Nutzung von Websockets wird ein HTTP/HTTPS-Request an den Server gemacht, der aber ein "Upgrade" der Verbindung zu Websockets anfordert und danach einen bidirektionalen Kanal überträgt.
Nach meiner Einschätzung kann ein Proxy-Server solche Daten nicht wirklich cachen, da es keine sich wiederholenden HTTP-Requests gibt, deren Antworten beim ersten Mal von extern geladen und dann aus dem Cache bedient werden können.
Insofern würde ich eher prüfen, ob sie Townhall-Meetings über einen HTTP-Proxy mit SSL-Inspection cachen können.
Weitere Links
Auf den den folgenden Seiten habe ich die Kommunikation per HTTP und eines HTTP-Proxy etwas weiter beschrieben.
- Teams XXL Meetings
- Teams Townhall Meetings
- Teams LiveEvent
- Teams CDN/eCDN
- WebRTC P2P
- Websockets
- Geo-DNS / Pinpoint DNS
- Anycast-Routin
- HTTP Proxy Authentication
- Proxy 407 Handling
- Microsoft eCDN Documentation - Technical
documentation - Netzwerkanforderungen
https://learn.microsoft.com/de-de/ecdn/technical-documentation/network-requirements - How to Optimize Stream & Live Events traffic in a VPN scenario
https://techcommunity.microsoft.com/t5/microsoft-365-blog/how-to-optimize-stream-amp-live-events-traffic-in-a-vpn-scenario/ba-p/1439767?WT.mc_id=M365-MVP-6771 - Teams view-only meeting experience
https://docs.microsoft.com/de-de/microsoftteams/view-only-meeting-experience - Introducing Microsoft eCDN for a New Era of Communications
https://techcommunity.microsoft.com/t5/microsoft-teams-blog/introducing-microsoft-ecdn-for-a-new-era-of-communications/ba-p/3615306 - Office 365 URLs and IP address ranges - Microsoft 365 Common and Office
Online
https://learn.microsoft.com/en-gb/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide#microsoft-365-common-and-office-online